ZigBee ZStack 協議棧學習--架構分析篇

靈思致遠Leansmall發表於2018-05-05

https://blog.csdn.net/zl374216459/article/details/59110230

本文著重分析ZStack(V3.0)的程式架構,只保留最重要的部分,其他部分暫時略過。。。
1.ZStack程式是從main()函式開始的:開啟IAR工程->ZMain資料夾->ZMain.c檔案
main函式包含兩個重要的函式如下:系統初始化函式osal_init_system()和啟動系統函式osal_start_system()
int main( void )
{
    ……
    osal_init_system();
    osal_start_system();
    ……
}


2.系統初始化函式osal_init_system()中包含一個重要函式任務初始化函式osalInitTasks();
uint8 osal_init_system( void )
{
    ……
    osalInitTasks();
    ……
}

3.任務初始化函式osalInitTasks()中與之相關的三個引數:

tasksEvents:指向事件表首地址的指標
tasksCnt:任務總數
tasksArr[]:任務處理函式的指標陣列

void osalInitTasks( void )
{
    a.定義一個tasksEvents指標指向tasksArr[]
    b.清空陣列快取區為0
    c.從底層到應用層依次呼叫任務初始化函式,並分配taskID,每層+1

}


4.啟動系統函式osal_start_system()中一個死迴圈,重複呼叫osal_run_system()函式
void osal_start_system( void )
{
    for(;;)
    {
        osal_run_system();
    }
}

5.osal_run_system()函式先按照自底向上查詢事件表,有任務的事件發生,則呼叫任務處理函式,如APP層有事件發生呼叫zclSampleApp_event_loop()函式處理

void osal_run_system( void )
{
    do{
        if (tasksEvents[idx])  //自底向上查詢每層是否有事件發生
        {
            break;
        }
    } while (++idx < tasksCnt);
    if (idx < tasksCnt)
    {
        events = tasksEvents[idx];
        tasksEvents[idx] = 0;  //暫時清空事件標誌位
        events = (tasksArr[idx])( idx, events );//呼叫任務處理函式進行處理
        tasksEvents[idx] |= events;  //將未處理完的事件重新置位
    }
}

6.在任務處理函式中,基本框架如下:

uint16 zclSampleApp_event_loop( uint8 task_id, uint16 events )
{
    if ( events & SYS_EVENT_MSG )//提取系統事件:接收到資料、按鍵狀態改變、網路狀態改變等
    {
        while ( (MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( zclSampleApp_TaskID )) )//接收該任務ID對應的訊息佇列中的資料
        {
            switch ( MSGpkt->hdr.event ){
              case ZCL_INCOMING_MSG:
               zclSampleApp_ProcessIncomingMsg( (zclIncomingMsg_t *)MSGpkt );
              break;
            ……
            default:
              break;
            }
        }
        return (events ^ SYS_EVENT_MSG);//處理完成,將事件標誌位清0
    }
    if ( events & SAMPLEAPP_END_DEVICE_REJOIN_EVT )//提取使用者自定義事件
    {
        bdb_ZedAttemptRecoverNwk();//事件處理函式
        return ( events ^ SAMPLEAPP_END_DEVICE_REJOIN_EVT );//處理完成,清空事件標誌位
    }
    ……
}

相關文章