我使用的协议栈版本及例子信息: ZigBee2006\Texas Instruments\ZStack-1.4.3-1.2.1\Projects\zstack\Samples\SampleApp
……~~
个人觉得,整个协议栈中触发事件有三种方式
1、通过设置一个“软件定时器”,当其溢出时触发事件。osal_start_timerEx()—osalTimerUpdate()— osal_set_event() 2、通过调用系统消息传递机制触发事件。osal_msg_send()—osal_set_event() 3、直接调用osal_set_event()触发事件。
前面两种方式其实是间接调用了osal_set_event(),协议中很多应用都是通过前面两种方式来触发。
而osal_set_event(): /********************************************************************* * @fn osal_set_event * * @brief * * This function is called to set the event flags for a task. The * event passed in is OR'd into the task's event variable. * * @param byte task_id - receiving tasks ID * @param byte event_flag - what event to set * * @return ZSUCCESS, INVALID_TASK */ byte osal_set_event( byte task_id, UINT16 event_flag ) { if ( task_id < tasksCnt ) { halIntState_t intState; HAL_ENTER_CRITICAL_SECTION(intState); // Hold off interrupts tasksEvents[task_id] |= event_flag; // Stuff(填充,塞) the event bit(s) HAL_EXIT_CRITICAL_SECTION(intState); // Release interrupts } else return ( INVALID_TASK );
return ( ZSUCCESS ); }
/********************************************************************* 可以看到通过tasksEvents[task_id] |= event_flag就能让系统主循环函数轮询到所发生的任务事件,再调用相应任务事件处理函数进行处理,具体参见“系统主循环流程”。
在协议栈里面,调用osal_set_event()的函数最主要是两个: (1)osalTimerUpdate() (2)osal_msg_send()
对于1,当有osal_start_timerEx()在系统软件定时器链表中添加一个软件定时器并启动时,系统通过osalTimerUpdate()对链表中的每一个软件定时器进行减1ms操作(具体参见有关于系统时钟的记录),当定时器溢出时,调用osal_set_event()触发事件,如下 /************************ static void osalTimerUpdate( uint16 updateTime ) { …………
// When timeout, execute the task if ( srchTimer->timeout == 0 ) { osal_set_event( srchTimer->task_id, srchTimer->event_flag );
………… } /************************ 对于2,对msg_ptr一系列处理后,调用osal_set_event()触发事件,如下 /************************ byte osal_msg_send( byte destination_task, byte *msg_ptr ) { ………… osal_set_event( destination_task, SYS_EVENT_MSG );
return ( ZSUCCESS ); } /***********************
说明: 本文作者所记录,以上基本为个人见解,错误之处还请高手指点,本人随时更新,转载请注明出处,谢谢! 参考资料: 《OSAL系统框架专题》
|