CC2530 事件轮询流程

来源:互联网 发布:ubuntu wine中文乱码 编辑:程序博客网 时间:2024/05/20 15:58

CC2530芯片中的操作系统抽象层(OSAL)是一个多任务操作系统,在开发时首先需要将任务静态添加至系统进行编译,当任务执行后会产生对应的事件,当系统初始化时,需要初始化新添加的任务:

void osalInitTasks( void ){  uint8 taskID = 0;//这里可以看出系统最多有256个任务    tasksEvents = (uint16 *)osal_mem_alloc( sizeof( uint16 ) * tasksCnt);//每项任务对应事件数组中的每一项  osal_memset( tasksEvents, 0, (sizeof( uint16 ) * tasksCnt));  //初始化系统默认任务………..  GenericApp_Init( taskID );//这里就初始化新添加的任务}
添加任务处理函数:

// The order in this table must be identical to the task initialization calls below in osalInitTask.typedef unsigned short (*pTaskEventHandlerFn)( unsigned char task_id, unsigned short event );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 //添加任务处理函数};
系统运行后开始轮询所有任务的事件:

void osal_run_system( void ){  uint8 idx = 0;  osalTimeUpdate();  Hal_ProcessPoll(); //轮询获取事件 //出现系统事件就直接调用前面注册的事件处理函数  do {    if (tasksEvents[idx])  // Task is highest priority that is ready.    {      break;    }  } while (++idx < tasksCnt);  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);    activeTaskID = idx;    events = (tasksArr[idx])( idx, events );    activeTaskID = TASK_NO_TASK;    HAL_ENTER_CRITICAL_SECTION(intState);    tasksEvents[idx] |= events;  // Add back unprocessed events to the current task.    HAL_EXIT_CRITICAL_SECTION(intState);  }}
事件分为两种:系统事件和自定义事件,系统事件如:

#define ZDO_NEW_DSTADDR           0xD0    // ZDO has received a new DstAddr for this app#define ZDO_STATE_CHANGE          0xD1    // ZDO has changed the device's network state#define ZDO_MATCH_DESC_RSP_SENT   0xD2    // ZDO match descriptor response was sent#define ZDO_CB_MSG                0xD3    // ZDO incoming message callback#define ZDO_NETWORK_REPORT        0xD4    // ZDO received a Network Report message#define ZDO_NETWORK_UPDATE        0xD5    // ZDO received a Network Update message#define ZDO_ADDR_CHANGE_IND       0xD6    // ZDO was informed of device address change
而自定义事件后,任务就需要通过osal_set_event函数将对应目的任务设置事件,事件和数据被封装成消息,任务最终通过osal_msg_send函数发送对应的消息。

uint8 osal_msg_send( uint8 destination_task, uint8 *msg_ptr )
消息定义如下:

typedef struct{  void   *next;  uint16 len;  uint8  dest_id;} osal_msg_hdr_t;typedef struct{  uint8  event;  uint8  status;} osal_event_hdr_t;
而上面消息只是头部,在消息分配函数中,消息内容默认放在消息头部后面:

uint8 * osal_msg_allocate( uint16 len ){  osal_msg_hdr_t *hdr;  if ( len == 0 )    return ( NULL );  hdr = (osal_msg_hdr_t *) osal_mem_alloc( (short)(len + sizeof( osal_msg_hdr_t )) );  if ( hdr )  {    hdr->next = NULL;    hdr->len = len;    hdr->dest_id = TASK_NO_TASK;    return ( (uint8 *) (hdr + 1) );  }  else    return ( NULL );}

而消息接受函数返回除头部以外的数据部分:

uint8 *osal_msg_receive( uint8 task_id );

这个过程下来,事件流程就清晰了,轮询产生事件,事件调用处理函数,函数中获取消息,处理数据,整个事件驱动流程完成。






0 0