當(dāng)前位置:首頁 > 嵌入式培訓(xùn) > 嵌入式學(xué)習(xí) > 講師博文 > 快速了解ZigBee的協(xié)議棧
帶大家來一起快速的看懂ZigBee的協(xié)議棧的運(yùn)行流程。
1.讀任何程序都需要從main函數(shù)入手,那我們先來看Zmain.c中的main函數(shù)。
問題:在main中我們會看到很多的函數(shù),我們究竟要看哪個函數(shù)呢?
回答:這么多的函數(shù)中其實(shí)我們只需要關(guān)注osal_init_system()和osal_start_system()兩個函數(shù)就可以了。我們在編程的時候其實(shí)也只會關(guān)系到這兩個函數(shù)。
2.我們跟蹤(把光標(biāo)放在這個函數(shù)上點(diǎn)右鍵,再點(diǎn)擊go to define)osal_init_system()這個函數(shù),發(fā)現(xiàn)它在OSAL.c文件中。
問題:在這個函數(shù)中有遇到了很多函數(shù),那我們又要關(guān)注那些函數(shù)呢?
回答:這個函數(shù)中我們只需要關(guān)注osalInitTasks()函數(shù)就可以了,這其實(shí)就是把每個事件作為每個任務(wù)。
3.我們跟蹤osalInitTasks()這個函數(shù),發(fā)現(xiàn)在OSAL_SampleApp.c中。其他的函數(shù)先不管。
在這個函數(shù)我們可以看到我們的任務(wù)編號是從0開始的,然后每添加一個任務(wù)任務(wù)編號(taskID++)就加一,并且為任務(wù)分配內(nèi)存。如下:
uint8 taskID = 0;
tasksEvents = (uint16 *)osal_mem_alloc( sizeof( uint16 ) * tasksCnt);
osal_memset( tasksEvents, 0, (sizeof( uint16 ) * tasksCnt));
在這個函數(shù)中需要我們特別關(guān)注的是SampleApp_Init(taskID)這個函數(shù),因?yàn)槲覀冊诰幊痰臅r候這個函數(shù)是需要我們程序員去編寫的,這個事協(xié)議棧提供的編程接口。
4.同樣我們跟蹤這個函數(shù)SampleApp_Init(taskID),發(fā)現(xiàn)它在SampleApp.c中(這個函數(shù)很重要)。在這個函數(shù)中我們看到需要我們?nèi)ヅ渲靡恍┬畔ⅲ绱诓ㄌ芈、流控等等?/p>
uartConfig.callBackFunc = Serial_CallBack;
這需要我們來定義串口回調(diào)函數(shù)來無線發(fā)送數(shù)據(jù)。
5.現(xiàn)在系統(tǒng)的初始化已經(jīng)做好了,遇到SampleApp_Init()函數(shù)的return后一步一步的返回。
6.返回到main函數(shù)后,我們再來看osal_start_system()函數(shù),注意這個函數(shù)一但進(jìn)去之后,此函數(shù)就不會再返回。我們跟蹤這個函數(shù),發(fā)現(xiàn)它在OSAL.c中。
do {
if (tasksEvents[idx]) // Task is highest priority that is ready.
{
break;
}
} while (++idx < tasksCnt);
注意這段邏輯,這是把任務(wù)中優(yōu)先級高的選出來。
events = tasksEvents[idx];//把優(yōu)先級高的選出來賦值給事件來處理。
這里我們需要來看一個數(shù)組:
const pTaskEventHandlerFn tasksArr[] = {
macEventLoop,
nwk_event_loop,
Hal_ProcessEvent,
#if defined( MT_TASK )
MT_ProcessEvent,
#endif
APS_event_loop,
#if defined ( ZIGBEE_FRAGMENTATION )
APSF_ProcessEvent,
#endif
ZDApp_event_loop,
#if defined ( ZIGBEE_FREQ_AGILITY ) || defined ( ZIGBEE_PANID_CONFLICT )
ZDNwkMgr_event_loop,
#endif
SampleApp_ProcessEvent
};
我們知道這些都是事件處理函數(shù)。問題又來了,這么多我們應(yīng)該看和用哪一個呢?
協(xié)議棧給用戶提供的函數(shù)編程接口是SampleApp_ProcessEvent這個函數(shù)。
然而怎么調(diào)用到這個函數(shù)呢?看下面的代碼。
events = (tasksArr[idx])( idx, events );//這是是一個函數(shù)指針的應(yīng)用。自己補(bǔ)C語言,這里不贅述。
7.既然是這樣我們就要跟蹤SampleApp_ProcessEvent()這個函數(shù),發(fā)現(xiàn)它在SampleApp.c中。
case AF_INCOMING_MSG_CMD:
SampleApp_MessageMSGCB( MSGpkt );
break;
這是我們需要關(guān)注的case,這個就是接受到數(shù)據(jù)的時候讀出無線發(fā)過來的數(shù)據(jù)。SampleApp_MessageMSGCB( MSGpkt );這個函數(shù)就需要程序員進(jìn)行編寫。所以這個函數(shù)也非常的重要。
這就是協(xié)議棧的大體運(yùn)行過程,當(dāng)然這些還很淺顯,還沒有討論一些深層次的內(nèi)容,并且有些地方寫得不合適的地方,希望大家指正,這里我表示萬分的感激。