首页 > 代码库 > (zigbee学习总结一)zigbee协议栈中OSAL运行机理

(zigbee学习总结一)zigbee协议栈中OSAL运行机理

       在基于zigbee协议栈的应用程序开发过程中,用户只需要实现应用层的开发即可,zigbee应用程序框架中包含了最多240个应用程序对象,每个应用程序对象运行在不同的端口上,因此端口的最作用是区分不同的应用程序对象,可以把一个应用程序对象看成为一个任务。因此,需要一个机制来实现任务的切换、同步和互斥,这就是OSAL产生的根源。

      OSAL用一句话来说就是指支持多任务运行的系统资源分配机制。OSAL中有三个参数非常重要,即:tasksCnt、tasksEvent[]和tasksArr[]。

    (1)tasksCnt:该变量用于保存任务总数;在Samples\GenericApp\CC2530DB\中可以可以看到

      const uint8 tasksCnt = sizeof( tasksArr ) / sizeof( tasksArr[0] );   //将总任务数赋值给tasksCnt

    (2)tasksEvent[]:是一个数组,其中每一项表示与其相对应的任务发生的事件,例如 tasksEvent[1]=2,则表示任务1发生了事件2。

    (3)tasksArr[]:是一个指针数组,其中每一项均指向对应任务的事件处理函数,例如tasksArr[1]的值为任务1的事件处理函数的地址。在Samples\GenericApp\CC2530DB\中可以可以看到:

const pTaskEventHandlerFn tasksArr[] =

{  

macEventLoop,  

nwk_event_loop,  

Hal_ProcessEvent,

#if defined( MT_TASK )

     MT_ProcessEvent,

#endif  

APS_event_loop,

#if defined ( ZIGBEE_FRAGMENTATION )  

     APSF_ProcessEvent,

#endif  

ZDApp_event_loop,

#if defined ( ZIGBEE_FREQ_AGILITY ) || defined ( ZIGBEE_PANID_CONFLICT )  

    ZDNwkMgr_event_loop,

#endif  

GenericApp_ProcessEvent

};           

      用户自己创建的任务GenericApp的事件处理函数GenericApp_ProcessEvent()的地址赋值给了tasksArr[]中的对应项。

      在ZMain.c中找到主函数,在主函数中调用了 osal_start_system(),进入该函数,可以看到for死循环中调用了 osal_run_system()函数,进入该函数,去掉一些不必要的代码后如下

void osal_run_system( void )

    uint8 idx = 0;                   //任务索引

    osalTimeUpdate();     Hal_ProcessPoll();

  do {   

           if (tasksEvents[idx])  // 不断查询各个任务当前发生的事件是否为0(在系统初始化过程中把各个任务的事件初始化为0  )

          {     

             break;                   //有任务发生的事件不为0,则跳出do-while循环

           }  

       } while (++idx < tasksCnt);

     if (idx < tasksCnt) 

   {    

     uint16 events;    

     events = tasksEvents[idx];                     

     tasksEvents[idx] = 0;                           // 重置该任务事件为0.  

     events = (tasksArr[idx])( idx, events );  //调用该任务事件处理函数

     tasksEvents[idx] |= events;                   //返回没有处理的事件   

    }

}

      在上面的程序中我们可以看到for死循环中,不断查询各个任务的tasksEvents[]来确定各个任务是否有事件发生,如果有事件发生则调用对应任务的事件处理函数。每个任务只有一个事件处理函数,在这一个任务处理函数中对该任务发生的不同事件进行处理。于是OSAL就在for循环这样的运行了起来。

 

(zigbee学习总结一)zigbee协议栈中OSAL运行机理