Z-Stack 軟件架構分析


      Z-Stack main 函數在 Zmain.c 中,總體上來說,它一共做了兩件工作,一個是系統初始化,即有啟動代碼來初始化硬件系統和軟件架構需要的各個模塊,另一個作用就是開福寺執行操作系統實體。
1.系統初始化
   系統啟動代碼需要完成初始化硬件平台和軟件架構所需要的各個模塊,為操作系統的運行做好准備工作,主要分為初始化系統時鍾,檢測芯片工作電壓、初始化堆棧、初始化各個硬件模塊、初始化FLASH存儲、形成芯片MAC地址、初始化非易失量、初始化MAC層協議、初始化化應用幀層協議、初始化操作系統等十余部分
 
2. 操作系統的執行
   啟動代碼為操作系統的執行做好准備工作后,就開始執行操作系統入口程序,並由此徹底將控制權移交給操作系統。
其實,操作系統實體只有一行代碼:
1 Osal_start_system(); // No Return from here
   在這句話后面有一條注釋,意思是本函數不會返回,也就是說它是一個死循環,永遠不可能執行完。這個函數就是osal系統輪轉查詢操作的主體部分,它所做的工作就是不斷的查詢每個任務中是否有事件發生,如果有事件發生,就調用相應的事件處理函數,如果沒有任何事件發生就一直查詢。我們可以看到下面就是這個函數的實現,其實這個函數的就是在一個無限的循環中。
 1 void osal_start_system( void )
 2 {
 3 #if !defined ( ZBIT )
 4   for(;;) // Forever Loop
 5 
 6 #endif
 7   {
 8     uint8 idx = 0;
 9 
10     Hal_ProcessPoll(); // This replaces MT_SerialPoll() and osal_check_timer().
11 
12 
13     do {
14       if (tasksEvents[idx]) // 最高優先級任務被找到
15 
16       {
17         break;
18       }
19     } while (++idx < tasksCnt); //其中tasksCnt為tasksArr數組中元素的個數
20 
21   //得到了待處理的具有最高優先級的任務的索引號 idx
22 
23     if (idx < tasksCnt) 
24     {
25       uint16 events;
26       halIntState_t intState;
27     // 進入/退出臨界區,來提取出需要處理的任務中的事件,其實這和μC/OS-II操作系統中進入臨界區很相似,μC/OS-II中使用OS_ENTER_CRITICAL();OS_EXIT_CRITICAL();
28 
29       HAL_ENTER_CRITICAL_SECTION(intState);
30       events = tasksEvents[idx];
31       tasksEvents[idx] = 0; // Clear the Events for this task.
32 
33       HAL_EXIT_CRITICAL_SECTION(intState);//通過指針調用來執行對應的任務處理函數
34 
35 
36       events = (tasksArr[idx])( idx, events );
37     //進入/退出臨界區,保存尚未處理的事件
38 
39           HAL_ENTER_CRITICAL_SECTION(intState);
40       tasksEvents[idx] |= events; // Add back unprocessed events to the current task.
41 
42           HAL_EXIT_CRITICAL_SECTION(intState);
43       } //本次事件處理結束,
44 
45 #if defined( POWER_SAVING )
46     else // 所有的任務事件都被查詢結束后,沒有任何事件被激活
47 
48     {
49       osal_pwrmgr_powerconserve(); // 系統進入休眠狀態。
50 
51     }
52 #endif
53     }
54 }

操作系統專門分配了存放所有任務事件的tasksEvents[]數組,每一個單元對應存放着每一個任務的所有事件,在這個函數中首先通過一個do—while循環來遍歷tasksEvents[],找到一個具有待處理事件的優先級最高的任務,序號低的任務優先級高,然后跳出循環,此時,就得到了最高優先級任務的序號idx,然后通過events=tasksEvents[idx]語句,將這個當前具有最高優先級的任務的事件取出,接着就調用(tasksArr[idx])(inx,events)函數來執行具體的處理函數了,taskArr[]是一個函數指針數組,根據不同的idx就可以執行不同的函數。

TI給出了幾個例子來演示Z-Stack協議棧,其實這些例子中的大部分代碼是相同的,只有用戶的應用層,添加了不同的任務及事件處理函數。這里以GeneralApp這個例子來說明。

首先,明確系統中要執行的幾個任務。在GeneralApp這個例子中,幾個任務函數組成了上述的tasksArr函數指針數組,在Osal_GeneralApp.c中定義,osal_start_system()函數通過函數指針(tasksArr[idx])(inx,events)調用。

tasksArr數組如下:

 1 const pTaskEventHandlerFn tasksArr[] = {
 2   macEventLoop,         //MAC層任務處理函數
 3 
 4   nwk_event_loop,       //網絡層任務處理函數
 5 
 6   Hal_ProcessEvent,     //硬件抽象層任務處理函數
 7 
 8 #if defined( MT_TASK )
 9 
10   MT_ProcessEvent,     //調試任務處理函數 可選
11 
12 #endif
13 
14   APS_event_loop,     //應用層任務處理函數,用戶不用修改
15 
16   ZDApp_event_loop,  //設備應用層任務處理函數,用戶可以根據需要修改
17 
18   GenericApp_ProcessEvent  //用戶應用層任務處理函數,用戶自己生成
19 
20 };

 

如果不算調試任務,操作系統一共要處理6項任務,分別為MAC層,網絡層。硬件抽象層,應用層,ZigBee設備應用層以及完全由用戶處理的應用層,其優先級由高到低。MAC層任務具有最高優先級,用戶層具有最低的優先級。Z-Stack已經編寫了對從MAC層到ZigBee設備應用層這五層任務的事件處理函數,一般情況下不需要修改這些函數,只需要按照自己的需求編寫應用層的任務及事件處理函數就可以。

其它的幾個例子文件中,唯一不同的是最后一個函數其它的函數都是一樣的。一般情況下用戶只需要額外添加三個文件就可以完成一個項目。一個是主文件,存放具體的任務事件處理函數如上述事例中的GenericApp_ProcessEvent,一個是這個主文件的頭文件,另外一個是操作系統的接口文件以Osal開頭,是專門存放任務處理函數數組tasksArr[]的文件。這樣就實現了Z-Stack代碼的公用,用戶只需要添加這幾個文件,編寫自己的任務處理函數就可以了。到現在是不是感覺很簡單,別不想想像的那么復雜,這個操作系統抽象層和實時操作系統中的μC/OS-II有相似之處,唉μC/OS-II中可以分配給64個任務。了解了這個操作系統的話,理解OSAL應該不是很困難,但是,Z-Stack只是基於這個OSAL運行,但重點不在這里,而是ZigBee設備之間的通信的實現,以及組網,組成不同的網絡結構,這些才是整個ZigBee協議中的核心內容,當然也應該遠比我們添加幾個文件來的復雜。

 

Z-Stack在項目中的目錄結構

在Z-Stack項目中大約有14個目錄文件,目錄文件下面又有很多的子目錄和文件。下面就來看看這14個根目錄,具體是有什么作用:

(1)      App:應用層目錄,這個目錄下的文件就是創建一個新項目時自己要添加的文件,

(2)      HAL:硬件層目錄,Common目錄下的文件是公用文件,基本上與硬件無關,其中hal_assert.c是斷言文件,用於調用,hal_drivers.c是驅動文件,抽象出與硬件無關的驅動函數,包含有與硬件相關的配置和驅動及操作函數。Include目錄下主要包含各個硬件模塊的頭文件,而Target目錄下的文件是跟硬件平台相關的,可能看到有兩個平台,分別是Cc2430DB平台和一個CC2430EB平台。后面的DB和EB表示的是TI公司開發板的型號,其實還有一種類型是BB的,BB: Battery Board
DB: Development Board  EB: Evaluation Board
分別對應TI公司開發的三種板型,其功能按上順序依次變強。可以參看"Z-Stack User's Guide for CC2430"的圖片,可以獲得更直觀的認識。

(3)      MAC:MAC層目錄,High Level和Low Level兩個目錄表示MAC層分為了高層和底層兩層,Include目錄下則包含了MAC層的參數配置文件及基MAC的LIB庫函數接口文件,這里的MAC層的協議是不開源的,以庫的形式給出

(4)      MT:監制調試層目錄,該目錄下的文件主要用於調試目的,即實現通過串口調試各層,與各層進行直接交互。

(5)      NWK:網絡層目錄,含有網絡層配置參數文件及網絡層庫的函數接口文件,及APS層庫的函數接口

(6)      OSAL:協議棧的操作系統抽象層目錄

(7)      Profile:AF層目錄,Application Farmework 應用框架,包含AF層處理函數接口文件。

(8)      Security:安全層目錄,包含安全層處理函數接口文件

(9)      Services:ZigBee和802.15.4設備地址處理函數目錄,包括地址模式的定義及地址處理函數

(10)   Tools:工作配置目錄,包括空間划分及Z-Stack相關配置信息

(11)   ZDO:指ZigBee設備對象,可認為是一種公共的功能集,文件用戶用自定義的對象調用APS子層的服務和NWK層的服務

(12)   ZMAC:其中Zmac.c是Z-StackMAC導出層接口文件,zmac_cb.c是ZMAC需要調用的網絡層函數

(13)   Zmain:Zmain.c主要包含了整個項目的入口函數main(),在OnBoard.c包含硬件開始平台類外設進行控制的接口函數

(14)   Output:輸出文件目錄,這個是EW8051 IDE自動生成的


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM