嵌入式 Linux C語言(十一)――C語言模塊化編程
一、C語言模塊化編程
所謂模塊化編程,就是指一個程序包含多個源文件(.c 文件和 .h 文件),每個模塊即是一個.c文件和一個.h文件的結合,頭文件(.h)中是對於該模塊接口的聲明。C語言模塊化編程中對.c、.h文件的潛規則:
1、.c 文件主要負責實現,也就是定義函數;.h 文件主要負責聲明,比如函數聲明、宏定義等,結構的定義、自定義數據類型一般也放在頭文件中,不能在.h文件中定義變量。將一個功能模塊的代碼單獨編寫成一個.c文件,然後把該模塊的接口函數放在.h文件中。
定義變量和聲明變量的區別在於定義會產生內存分配的操作,是匯編階段的概念;而聲明則只是告訴包含該聲明的模塊在連接階段從其它模塊尋找外部函數和變量。
2、引入編譯器自帶的頭文件(包括標准頭文件)用尖括號,引入自定義頭文件用雙引號,例如:
#include <stdio.h>
#include "myFile.h"
頭文件應當是冪等的。也就是說,多次包括頭文件的效果和僅包括一次的效果完全相同。
#ifndef _STDIO_H
#define _STDIO_H
/* 聲明部分 */
#endif
3、模塊提供給其它模塊調用的外部函數及數據需在.h中文件中冠以extern關鍵字聲明;模塊內的函數和全局變量需在.c文件開頭冠以static關鍵字聲明。
二、嵌入式系統開發中的模塊化編程
嵌入式系統通常包括兩類模塊:
(1)硬件驅動模塊,一種特定硬件對應一個模塊。
(2)軟件功能模塊,其模塊的劃分應滿足低偶合、高內聚的要求。模塊之間聯系越緊密,其耦合性就越強,模塊的獨立性則越差;模塊內各元素(語名之間、程序段之間)聯系的越緊密,內聚性就越高。
1、單任務系統
所謂"單任務系統"是指該系統不能支持多任務並發操作,宏觀串行地執行一個任務。而多任務系統則可以宏觀並行(微觀上可能串行)地"同時"執行多個任務。
單任務程序典型架構
(1)從CPU復位時的指定地址開始執行;
(2)跳轉至匯編代碼startup處執行;
(3)跳轉至用戶主程序main執行,在main中完成:
a.初試化各硬件設備;
b.初始化各軟件模塊;
c.進入死循環(無限循環),調用各模塊的處理函數
用戶主程序和各模塊的處理函數都以C語言完成。用戶主程序最後都進入了一個死循環,其首選方案是:
while(1)
{
}
2、多任務系統
多任務的並發執行通常依賴於一個多任務操作系統(OS),多任務OS的核心是系統調度器,它使用任務控制塊(TCB)來管理任務調度功能。TCB包括任 務的當前狀態、優先級、要等待的事件或資源、任務程序碼的起始地址、初始堆棧指針等信息。調度器在任務被激活時,要用到這些信息。此外,TCB還被用來存 放任務的"上下文"(context)。任務的上下文就是當一個執行中的任務被停止時,所要保存的所有信息。通常,上下文就是計算機當前的狀態,也即各個寄存器的內容。當發生任務切換時,當前運行的任務的上下文被存入TCB,並將要被執行的任務的上下文從它的TCB中取出,放入各個寄存器中。
究竟選擇多任務還是單任務方式,依賴於軟件的體系是否龐大。例如,絕大多數手機程序都是多任務的,但也有一些小靈通的協議棧是單任務的,沒有操作系統,它們的主程序輪流調用各個軟件模塊的處理程序,模擬多任務環境。
3、中斷服務程序
中斷是嵌入式系統中重要的組成部分,但是在標准C中不包含中斷。許多編譯開發商在標准C上增加了對中斷的支持,提供新的關鍵字用於標示中斷服務程序(ISR),類似於__interrupt、#program interrupt等。當一個函數被定義為ISR的時候,編譯器會自動為該函數增加中斷服務程序所需要的中斷現場入棧和出棧代碼。
中斷服務程序需要滿足如下要求:
(1)不能返回值;
(2)不能向ISR傳遞參數;
(3) ISR應該盡可能的短小精悍;
(4) printf(char * lpFormatString,…)函數會帶來重入和性能問題,不能在ISR中采用。
4、硬件驅動模塊
一個硬件驅動模塊通常應包括如下函數:
(1)中斷服務程序ISR
(2)硬件初始化
A、修改寄存器,設置硬件參數(如UART應設置其波特率,AD/DA設備應設置其采樣速率等);
B、將中斷服務程序入口地址寫入中斷向量表:
/* 設置中斷向量表 */
m_myPtr = make_far_pointer(0l); /* 返回void far型指針void far * */
m_myPtr += ITYPE_UART; /* ITYPE_UART: uart中斷服務程序 */
/* 相對於中斷向量表首地址的偏移 */
*m_myPtr = &UART _Isr; /* UART _Isr:UART的中斷服務程序 */
(3)設置CPU針對該硬件的控制線
A、如果控制線可作PIO(可編程I/O)和控制信號用,則設置CPU內部對應寄存器使其作為控制信號;
B、設置CPU內部的針對該設備的中斷屏蔽位,設置中斷方式(電平觸發還是邊緣觸發)。
(4)提供一系列針對該設備的操作接口函數。例如,對於LCD,其驅動模塊應提供繪制像素、畫線、繪制矩陣、顯示字符點陣等函數;而對於實時鐘,其驅動模塊則需提供獲取時間、設置時間等函數。
本文介紹了C語言模塊編程的主要思想,嵌入式系統開發中模塊劃分、多任務還是單任務選取、單任務程序典型架構、中斷服務程序、硬件驅動模塊設計等。
本文是學習網絡博文並經自己思考總結整理而來,博文來源有:
C語言中文網、C語言模塊化程序設計(EDN電子技術設計 wnhb)、嵌入式C語言之---模塊化編程 (CSDN zhzht19861011)。
由於網絡博文繁雜,無法一一查明原出處,所列來源為本人學習時所查閱資料。
本文出自 “生命不息,奮斗不止” 博客,請務必保留此出處http://9291927.blog.51cto.com/9281927/1790678