CC2530 事件轮询流程

原创 2015年07月11日 09:09:24

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 );

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






剖析NodeJs的事件轮询机制

前言:一直以来,对NodeJs的事件轮询机制一知半解。查阅了些许资料后,总算揭开了其神秘的面纱。一、首先,看看Nodejs官网上对nodejs的描述: Node takes the event mod...
  • yezhenxu1992
  • yezhenxu1992
  • 2016年03月27日 22:04
  • 2187

事件轮询(Event Loop)

今天在看Node.js的时候接触到了轮询的概念,原来一直不知道,轮询一直存在于JavaScript中,每天都在接触它,然而并不知道,哈哈。 一、概念理解   事件轮询(Event Loop)是一个...
  • qq_21630623
  • qq_21630623
  • 2017年09月12日 15:47
  • 224

Java异步事件:轮询与中断

CPU几乎把所有的时间都花费在从内存获取指令并运行它们的过程中。然而,CPU和主存仅仅只是计算机硬件系统中众多组件的其中两个。一个完整的系统还包含其他的设备,比如:硬盘或者固态硬盘,用来存储程序和数据...
  • pangjiuzala
  • pangjiuzala
  • 2015年09月19日 20:06
  • 2017

js和node.js的事件轮询

一、为什么JavaScript是单线程? JavaScript语言的一大特点就是单线程,也就是说,同一个时间只能做一件事。那么,为什么JavaScript不能有多个线程呢?这样能提高...
  • qq_21157805
  • qq_21157805
  • 2016年01月19日 12:45
  • 450

JS中的异步以及事件轮询机制

一、JS为何是单线程的?      JavaScript语言的一大特点就是单线程,也就是说,同一个时间只能做一件事。那么,为什么JavaScript不能有多个线程呢?这样能提高效率啊。(在JAVA和c...
  • heshan1992
  • heshan1992
  • 2017年08月18日 09:44
  • 187

轮询算法设计及其代码框架

在实际的软件开发项目中,经常会遇到某模块需要向其它模块发消息的情况。为了减轻消息接收者的负担,我们会采用一种叫做轮询的机制来发送消息。本文介绍轮询算法的流程及其代码框架。1.算法流程 假设消息发送模...
  • zhouzxi
  • zhouzxi
  • 2015年06月01日 09:03
  • 2821

轮询算法中效率和延迟的均衡

    所谓的轮询算法是对事件的一种检测机制,如I/O设备的状态改变等。常见的事件检测机制有轮询,中断,DMA,通道等,其中轮询和中断是事件通知的两种基本方式,DMA和通道都是一种数据传输方式。能用中...
  • Matrix_Designer
  • Matrix_Designer
  • 2011年06月07日 09:00
  • 897

Linux centos系统下PHP脚本轮询

今天在搞一个PHP脚本,需要实现的功能是从一个服务器每1秒轮询一次一个URL。 当我在命令行模式下运行PHP脚本的时候,发现报错:mysql_connect函数不存在。 最后发现根本原因是 php t...
  • yzhfd518
  • yzhfd518
  • 2014年07月29日 17:04
  • 294

zigbee cc2530 AD 转换温度 学习总结

/* 本程序讲解AD控制(片内温度计) 主讲  王加辉 */ #include #include"stdio.h" #define uchar  unsigned ...
  • doudoududu1314
  • doudoududu1314
  • 2017年08月10日 22:37
  • 353

CC2530协议栈工作流程

什么是 ZigBee 协议栈呢?它和 ZigBee 协议有什么关系呢? 协议是一系列的通信标准,通信双方需要共同 按照这一标准进行正常的数据发射和接收。协议 栈是协议的具体实现形式,通俗点来理解就...
  • z502521809
  • z502521809
  • 2016年10月30日 18:07
  • 2441
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:CC2530 事件轮询流程
举报原因:
原因补充:

(最多只允许输入30个字)