博客
关于我
浅谈ZigBee消息机制
阅读量:133 次
发布时间:2019-02-26

本文共 3895 字,大约阅读时间需要 12 分钟。

本章简单的介绍一下ZigBee的消息机制,如果说的有问题还请多多指正。

通俗的说,ZigBee的消息机制就好比这有一排抽屉,当我要向某个任务或者事件发送消息时,就把该消息和对应的数据放到抽屉中,在任务轮训时,某个任务轮训按个查看抽屉中是否有自己需要的消息,有就取出并且处理,没有就结束,等待下一次轮训。

ZigBee消息链表如下图所示:(注:消息机制实现代码在osal.c中)


图1 ZigBee消息队列

值得注意的是,消息队列中每条消息都有一个系统消息头,结构体为osal_msg_hdr_t,包括三个数据类型,包括下一条消息的指针、消息长度和任务ID。消息头下有一个事件消息头,结构体为osal_event_hdr_t,该消息头包括事件的掩码和状态。使用过程中特别注意,通过系统函数获取的消息指针为事件消息头(osal_event_hdr_t)对应的地址,具体可看图1。

 

下面以串口接收到数据解包后将数据发到应用层为例,来介绍一下ZigBee的消息机制是怎么实现的。

【MT_UART.c】串口接收到数据后,首先要申请该消息对应的空间内存,申请多少要看数据有多少。

App_pMsg = (mtOSALSerialData_t *)osal_msg_allocate( sizeof (mtOSALSerialData_t) + MT_RPC_FRAME_HDR_SZ + App_LEN_Token );


其中 [MT_RPC_FRAME_HDR_SZ + App_LEN_Token]为串口数据长度,MT_RPC_FRAME_HDR_SZ包括数据长度、命令码0、命令码1三个数据,App_LEN_Token表示应用层数据,在此不再赘述。申请的该指针返回的为mtOSALSerialData_t,对应的图2中event的地址。

 

再看osal_msg_allocate( uint16 len )这个函数。


<span style="font-family: Arial, Helvetica, sans-serif;">uint8 * osal_msg_allocate( uint16 len )</span>
{  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 );}

该函数在申请内存时,添加了sizeof( osal_msg_hdr_t )长度,该长度及图1中消息时间头,并且赋予了该消息头的next指针,长度len和dest_id任务ID。函数返回的指针为hdr+1,从我们正常的角度看,即申请了一片内存,返回内存指针,在内存指针前加上了任务消息头。因此这就是在处理任务消息头时都要-1的原因。


图3 任务消息处理函数

 

这样就生成一条消息。但是该工作并没有完成,需要将该消息放入消息对垒并且通知对应的任务ID取出该消息。

 

通过查看串口代码,可发现当数据校验正确后,要调用该函数。

osal_msg_send( App_TaskID, (byte *)App_pMsg );

该函数代码如下:

uint8 osal_msg_send( uint8 destination_task, uint8 *msg_ptr ){  if (