車乾的ZigBee學習筆記八-淺析協議棧

一、初識OSAL

  • ZigBee協議棧的實時操作系統
  • 操作系統抽象層-Operating System Abstraction Layer
  • 作用:任務調度,資源分配和管理
  • 關鍵詞:任務和事件
  • taskCnt–任務總數
  • taskEvents–指向事件表首地址的指針
  • taskArry–數組,數組中的每一個元素都是指向事件處理函數的指針

二、協議棧運行機制

1、入口在Zmain文件下,Zmain.c的main函數中,其中包含了各種硬件和協議棧的初始化,直到調用osal_start_system()函數,協議棧纔開始真正運行起來。

  • int main(void)
  • {
  •   ...
    
  •   ...
    
  • osal_start_system(); //不再返回
  • return 0; //
  • }

2、當發生兩個事件同時發生時,0SAL處理

  • #define SYS_EVENT_MSG 0X8000
  • #define SAMPLEAPP_SEND_PERIODIC_MSG_EVT 0X0001
  • 如果這兩個事件同時發生,則events =0x8001
  • 異或運算,同爲0,異爲1
  • events^SYS_EVENT_MSG = 0x0001(只剩下最後一個事件)
  • events^SAMPLEAPP_SEND_PERIODIC_MSG_EVT =0x8000(只剩前一個事件)

三、osal_start_system(); 詳解

void osal_start_system( void )
{
#if !defined ( ZBIT ) && !defined ( UBIT )
  for(;;)  //首先是一個FOR的死循環
#endif
  {
    uint8 idx = 0;  //定義變量用來索引事件表

    osalTimeUpdate(); //用來更新系統時鐘
    Hal_ProcessPoll();  // 查看硬件方面是否有事件發生
    
    do {
      if (tasksEvents[idx])  // tasksEvents事件表,當有事件發生,idx 會變爲一個16進制的數字
      {
        break;//idx不爲0時,跳出do_while循環
      }
    } while (++idx < tasksCnt);  //如果沒有事件發生,++idx繼續檢查下一項是否有事件發生

    if (idx < tasksCnt)  //跳出任務檢查循環後,第一步,保證不超出任務總數
    {
      uint16 events;
      halIntState_t intState;

      HAL_ENTER_CRITICAL_SECTION(intState);  //進入中斷
      events = tasksEvents[idx];  //保存事件
      tasksEvents[idx] = 0;  // 事件表清除爲0.
      HAL_EXIT_CRITICAL_SECTION(intState); //退出中斷

      events = (tasksArr[idx])( idx, events );//調用數據處理函數

      HAL_ENTER_CRITICAL_SECTION(intState); //進入中斷
      tasksEvents[idx] |= events;  // 把未處理的事件返回給事件表
      HAL_EXIT_CRITICAL_SECTION(intState); //退出中斷
    }
#if defined( POWER_SAVING )
    else  //完全通過所有沒有活動的任務事件?
    {
      osal_pwrmgr_powerconserve();  // 完全通過所有沒有活動的任務事件?
    }
#endif
  }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章