全域性變數應該是得到記憶體分配且可以被其他模組通過c語言中extern關鍵字呼叫的變數。因此,必須在 .c 和 .h 檔案中定義。這種重複的定義很容易導致錯誤。以下討論的方法只需用在標頭檔案中定義一次。雖然有點不易懂,但使用者一旦掌握,使用起來卻很靈活。表1.2中的 定義出現在定義所有全域性變數的.h標頭檔案中。
程式清單 l 1.2 定義全域性巨集。
#ifdef ***_globals
#define ***_ext
#else
#define ***_ext extern
#endif
.h 檔案中每個全域性變數都加上了***_ext的字首。***代表模組的名字。該模組的.c檔案中有以下定義:
#define ***_globals
#include "includes.h"
當 編譯器處理.c檔案時,它強制***_ext(在相應.h檔案中可以找到)為空,(因為***_globals已經定義)。所以編譯器給每個全域性變數分配 記憶體空間,而當編譯器處理其他.c檔案時,***_global沒有定義,***_ext被定義為extern,這樣使用者就可以呼叫外部全域性變數。為了說 明這個概念,可以參見uc/os_ii.h,其中包括以下定義:
#ifdef os_globals
#define os_ext
#else
#define os_ext extern
#endif
os_ext int32u osidlectr;
os_ext int32u osidlectrrun;
os_ext int32u osidlectrmax;
同時,ucos_ii.h有中以下定義:
#define os_globals
#include 「includes.h」
當編譯器處理ucos_ii.c時,它使得標頭檔案變成如下所示,因為os_ext被設定為空。
int32u osidlectr;
int32u osidlectrrun;
int32u osidlectrmax;
這樣編譯器就會將這些全域性變數分配在記憶體中。當編譯器處理其他.c檔案時,標頭檔案變成了如下的樣子,因為os_global沒有定義,所以os_ext被定義為extern。
extern int32u osidlectr;
extern int32u osidlectrrun;
extern int32u osidlectrmax;
在這種情況下,不產生記憶體分配,而任何 .c檔案都可以使用這些變數。這樣的就只需在 .h 檔案中定義一次就可以了。
總結:在嵌入式c語言定義乙個全域性變數,而且希望此全域性變數在其他c檔案中和在工程彙編中使用此變數的話。我們在標頭檔案裡定義了乙個全域性變數,在其它檔案裡用extern 關鍵字引用即可。而如果每個檔案都引用這個標頭檔案會產生重複定義全域性變數的問題。我們使用這種條件編譯就能解決此問題。
ucosII學習筆記
以前很少接觸過嵌入式作業系統,這次因為要嘗試研究ucosii這個嵌入式作業系統,看看自己能不能盡快的會使用它,查詢了不少資料。ucosii學習筆記。以下是nathan.yu的 ucosii學習筆記 整理的不錯,自己先借鑑。ucosii學習筆記 by nathan.yu ucos ii特性 l 可剝奪...
UCOS II學習筆記
1.標頭檔案的配置 include stm32f10x.h include stm32f10x conf.h include ucos ii.h 2.任務堆疊配置 os stk led0 task stk 64 os stk led1 task stk 64 定義兩個任務的堆疊陣列 3.對硬體的配置...
ucosII學習筆記 1
核心結構學習 一.臨界段 critical sections 的臨界段也稱為臨界區。程式執行到臨界區時,不允許有中斷進入,因此在進入臨界區前要關中斷,執行完臨界區馬上開中斷。c os 中的這兩個巨集呼叫分別是 os enter critical 和os exit critical 因為這兩個巨集的定...