您的位置:首页 > 其它

Z-STACK学习笔记-OSAL分析

2017-06-16 09:07 253 查看
首先看的是main函数

里面有两个关于OSAL的函数

1、  osal_init_system();  //初始化系统

2、 osal_start_system(); //启动系统

首先分析一下系统的初始化

系统初始化里包含了几部分内容

1、内存分配管理的初始化

2、定时器的初始化

3、电源管理初始化

4、系统任务初始化             osalInitTasks();

我这里是先看的系统任务初始化,先了解任整个系统的运行流程

在osalInitTasks()

首先是

tasksEvents = (uint16 *)osal_mem_alloc( sizeof( uint16 ) * tasksCnt);

函数中有两个变量  tasksEvents  初步看是个任务事件指针 暂时不知道干什么用的

                                  tasksCnt         任务数  定义如下:const uint8 tasksCnt = sizeof( tasksArr ) / sizeof( tasksArr[0] );

     tasksCnt是tasksArr 这个数组的大小 暂时不知道是干什么的 

先看下tasksArr的定义

// The order in this table must be identical to the task initialization calls below in osalInitTask.

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

  ShyApp_ProcessEvent

};

typedef unsigned short (*pTaskEventHandlerFn)( unsigned char task_id, unsigned short event );

由上面可以看出tasksArr 是一个函数指针数组 初始化了所用到任务的函数入口指针。

  macTaskInit( taskID++ );

  nwk_init( taskID++ );

  Hal_Init( taskID++ );

#if defined( MT_TASK )

  MT_TaskInit( taskID++ );

#endif

  APS_Init( taskID++ );

#if defined ( ZIGBEE_FRAGMENTATION )

  APSF_Init( taskID++ );

#endif

  ZDApp_Init( taskID++ );

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

  ZDNwkMgr_Init( taskID++ );

#endif

  ShyApp_Init( taskID );

然后就是出事话任务并每个任务分配一个ID号。我们可以发现分配的ID号正好对应任务数组的下标。

然后返回 进入void osal_start_system( void )启动系统的函数

    do {

      if (tasksEvents[idx])  // Task is highest priority that is ready.

      {

        break;

      }

    } while (++idx < tasksCnt);

在这里循环的判断任务事件标志是否为0,如果不为0 就跳出 

    if (idx < tasksCnt)

    {

      uint16 events;

      halIntState_t intState;

      HAL_ENTER_CRITICAL_SECTION(intState);

      events = tasksEvents[idx];

      tasksEvents[idx] = 0;  // Clear the Events for this task.

      HAL_EXIT_CRITICAL_SECTION(intState);

      events = (tasksArr[idx])( idx, events );

      HAL_ENTER_CRITICAL_SECTION(intState);

      tasksEvents[idx] |= events;  // Add back unprocessed events to the current task.

      HAL_EXIT_CRITICAL_SECTION(intState);

    }

跳出后就调用相应事件对应的任务号的任务。并将事件标志作为参数传入。

UINT16 ShyApp_ProcessEvent( byte task_id, UINT16 events )

{

  afIncomingMSGPacket_t *MSGpkt;

  afDataConfirm_t *afDataConfirm;

  // Data Confirmation message fields

  byte sentEP;

  ZStatus_t sentStatus;

  byte sentTransID;       // This should match the value sent

  (void)task_id;  // Intentionally unreferenced parameter

  if ( events & SYS_EVENT_MSG )

  {

    MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( ShyApp_TaskID );

    while ( MSGpkt )

    {

      switch ( MSGpkt->hdr.event )

      {

        case ZDO_CB_MSG:

          ShyApp_ProcessZDOMsgs( (zdoIncomingMsg_t *)MSGpkt );

          break;

          

        case KEY_CHANGE:

          ShyApp_HandleKeys( ((keyChange_t *)MSGpkt)->state, ((keyChange_t *)MSGpkt)->keys );

          break;

        case AF_DATA_CONFIRM_CMD:

          // This message is received as a confirmation of a data packet sent.

          // The status is of ZStatus_t type [defined in ZComDef.h]

          // The message fields are defined in AF.h

          afDataConfirm = (afDataConfirm_t *)MSGpkt;

          sentEP = afDataConfirm->endpoint;

          sentStatus = afDataConfirm->hdr.status;

          sentTransID = afDataConfirm->transID;

          (void)sentEP;

          (void)sentTransID;

          // Action taken when confirmation is received.

          if ( sentStatus != ZSuccess )

          {

            // The data wasn't delivered -- Do something

          }

          break;

        case AF_INCOMING_MSG_CMD:

          ShyApp_MessageMSGCB( MSGpkt );

          break;

        case ZDO_STATE_CHANGE:

          ShyApp_NwkState = (devStates_t)(MSGpkt->hdr.status);

//          if ( (ShyApp_NwkState == DEV_ZB_COORD)

//              || (ShyApp_NwkState == DEV_ROUTER)

//              || (ShyApp_NwkState == DEV_END_DEVICE) )

//          {

//            // Start sending "the" message in a regular interval.

//            osal_start_timerEx( ShyApp_TaskID,

//                                ShyApp_SEND_MSG_EVT,

//                              ShyApp_SEND_MSG_TIMEOUT );

//          }

      // Release the memory

      osal_msg_deallocate( (uint8 *)MSGpkt );

      // Next

      MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( ShyApp_TaskID );

    }

    // return unprocessed events

    return (events ^ SYS_EVENT_MSG);

  }

  // Send a message out - This event is generated by a timer

  //  (setup in ShyApp_Init()).

  if ( events & ShyApp_SEND_MSG_EVT )

  {

    // Send "the" message

    ShyApp_SendTheMessage();

    // Setup to send message again

    osal_start_timerEx( ShyApp_TaskID,

                        ShyApp_SEND_MSG_EVT,

                      ShyApp_SEND_MSG_TIMEOUT );

    // return unprocessed events

    return (events ^ ShyApp_SEND_MSG_EVT);

  }

  // Discard unknown events

  return 0;

}

找个任务处理函数分析,首先是按位与 判断当前是哪个事件,不同的事件对应不同的处理方式。

到这里系统大致的运行流程基本搞明白了。

OSAL 是一个基于事件处理机制的简易的系统。根据如果有任务事件就去处理相应的任务。如果没有事件则不处理。不停的这样循环。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ZIGBEE