一 系統啟動
//OSAL.c
void osal_start_system( void )
{
#if !defined ( ZBIT ) && !defined ( UBIT )
for(;;) // Forever Loop
#endif
{
osal_run_system();
}
}
二 作業系統執行
//OSAL.c
void osal_run_system( void )
{
uint8 idx = ; osalTimeUpdate();
Hal_ProcessPoll();//輪詢TIMER與UART do {
if (tasksEvents[idx]) // Task is highest priority that is ready.
{
break;
}
} while (++idx < tasksCnt);
初始化時由osal_memset()設為0,只要不為空型別NULL,即有相對應任務事件發生,就break跳出迴圈體,通過下面的程式進行任務事件處理。如果為空,執行判斷語句,即idx自增,再返回輪詢有無各層的任務事件發生。如果執行完迴圈語句都沒有檢測到有事件發生,idx=7(任務初始化時,最下面的 SampleApp_Init( taskID )為task=6,即最大為6),進入睡眠。
if (idx < tasksCnt)
{
uint16 events;
halIntState_t intState; HAL_ENTER_CRITICAL_SECTION(intState);//中斷臨界狀態:儲存先前中斷狀態,然後關中斷,見備註1
events = tasksEvents[idx];//對應有事件發生的任務的陣列
tasksEvents[idx] = ; // Clear the Events for this task.//取出任務事件後,清除此任務資料的事件
HAL_EXIT_CRITICAL_SECTION(intState);//跳出中斷臨界狀態:恢復先前中斷狀態 activeTaskID = idx;
events = (tasksArr[idx])( idx, events ); //呼叫相對應的任務事件處理函式處理,各類事件處理函數M(task_id,event),返回的都是這個任務未被處理的事件。
activeTaskID = TASK_NO_TASK; HAL_ENTER_CRITICAL_SECTION(intState); //把剛才返回未處理的任務事件新增加當前任務中再進行處理,跳出此if(idx < tasksCnt)迴圈再進行if (tasksEvents[idx])判斷並處理)
tasksEvents[idx] |= events; // Add back unprocessed events to the current task.
HAL_EXIT_CRITICAL_SECTION(intState);
}
#if defined( POWER_SAVING )
else // Complete pass through all task events with no activity?
{
osal_pwrmgr_powerconserve(); // Put the processor/system into sleep
}
#endif /* Yield in case cooperative scheduling is being used. */
#if defined (configUSE_PREEMPTION) && (configUSE_PREEMPTION == 0)
{
osal_task_yield();
}
#endif
}
三 事件機制
events = (tasksArr[idx])( idx, events );任務idx的事件處理函式
以上程式碼是響應具體的事件函式,其中tasksArr定義為如下:
//OSAL_SampleApp.c
const pTaskEventHandlerFn tasksArr[ ] =
{
macEventLoop, //MAC層任務事件處理函式
nwk_event_loop, //NWK層任務事件處理函式
Hal_ProcessEvent, //PHY層事件處理函式
#if defined( MT_TASK )
MT_ProcessEvent, //MT任務事件處理函式
#endif
APS_event_loop, //APS層任務事件處理函式
ZDApp_event_loop, //ZDO任務事件處理函式
SampleApp_ProcessEvent //使用者應用任務事件處理函式
};
而pTaskEventHandlerFn又定義為
//OSAL_Tasks.h
typedef unsigned short (*pTaskEventHandlerFn)( unsigned char task_id, unsigned short event );
即:pTaskEventHandlerFn宣告為一種函式指標,該函式指標指向M(task_id,event)這種型別的函式,而tasksArr是一個指標陣列,數組裡面的元素的型別為pTaskEventHandlerFn,就是函式指標,這樣tasksArr[ ]就是一個按照idx順序排列的函式陣列。如果呼叫tasksArr中相對應的函式,直接使用 tasksArr[idx](task_id,event)就行了。在osal_run_system中,呼叫events = (tasksArr[idx])( idx, events ),執行由idx相對應的事件任務。
四 參考連結
備註1
#define HAL_ENABLE_INTERRUPTS() st( EA = 1; )
#define HAL_DISABLE_INTERRUPTS() st( EA = 0; )
#define HAL_INTERRUPTS_ARE_ENABLED() (EA) typedef unsigned char halIntState_t;
#define HAL_ENTER_CRITICAL_SECTION(x) st( x = EA; HAL_DISABLE_INTERRUPTS(); )
#define HAL_EXIT_CRITICAL_SECTION(x) st( EA = x; )
#define HAL_CRITICAL_STATEMENT(x) st( halIntState_t _s; HAL_ENTER_CRITICAL_SECTION(_s); x; HAL_EXIT_CRITICAL_SECTION(_s); )