Ztack学习笔记(3)-系统启动分析

一 系统启动

//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 = 0; osalTimeUpdate(); Hal_ProcessPoll();//轮询TIMERUART 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] = 0; // 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】zstack sampleApp程序分析3 

备注1

1 #define HAL_ENABLE_INTERRUPTS()         st( EA = 1; )
2 #define HAL_DISABLE_INTERRUPTS()        st( EA = 0; )
3 #define HAL_INTERRUPTS_ARE_ENABLED()    (EA)
4 
5 typedef unsigned char halIntState_t;
6 #define HAL_ENTER_CRITICAL_SECTION(x)   st( x = EA;  HAL_DISABLE_INTERRUPTS(); )
7 #define HAL_EXIT_CRITICAL_SECTION(x)    st( EA = x; )
8 #define HAL_CRITICAL_STATEMENT(x)       st( halIntState_t _s; HAL_ENTER_CRITICAL_SECTION(_s); x; HAL_EXIT_CRITICAL_SECTION(_s); )
View Code
原文地址:https://www.cnblogs.com/gjianw217/p/4493350.html