概述
ZStack OSAL的事件(event)与消息(message)——part 1 (有关event的那些事)
在这里 http://blog.csdn.net/ceci_prayer/article/details/9787349
二、消息
消息可以理解为带有附加信息的事件。最典型的一类便是按键消息,它同时产生了一个哪个按键被按下了附加信息。所以在OnBoard_SendKeys这个
函数中,不仅向GenericApp发送了事件,还通过调用osal_msg_send函数向GenericApp发送了一个消息,这个消息记录了这个事件的附加信息。
一般来说,一个消息总是和一个事件对应。当协议栈接收到消息后,在ProcessEvent函数中有以下语句:
if ( events & SYS_EVENT_MSG )
{
MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( GenericApp_TaskID );
while ( MSGpkt )
{
switch ( MSGpkt->hdr.event )
{
case ……
}
可以看出,消息是被当作系统事件接收的,接收到之后会找到消息对应的event,之后进行相应的处理。
消息的使用与事件类似,但是使用了不同的函数触发:
byte osal_msg_send( byte destination_task, byte *msg_ptr )
这个函数有两个参数分别为接收事件任务的ID,另一个是指向消息的指针。它的功能是向一个任务发送命令或数据消息,此外,这个函数也会触发目标任务的SYS_EVENT_MSG(系统消息任务)。
----------------------------以上是之前学习内容的分割线-----------------------------------
之前对于消息的分析是正确的,但过于笼统了。今天我重新梳理了一下关于消息(message)的思路,在这里记录一下。
首先我们需要明确一个概念,,msg是用来干什么的?msg和event有什么不同?
我们已经知道了,event是一个事件,当这个事件发生以后,会触发相应的事件处理函数。即event是事先定义好的,但不知道会在哪个确定时间点被触发。
而消息不同。顾名思义,消息是用来传递信息的,即有两个主体(如下图中的task1和task2),在这两个主体想要通信的时候,就会用到消息。
上面这个图是我自已总结的有关zstack中消息的用法(如果有不正确的地方希望大家指正^_^)。
step1:osal_msg_allocate
可以看出,task1想要给task2发送消息(这两个任务可能属于一个设备,也可能属于不同的设备,这一点稍后再说),于是task1就得先产生一个msg,这时候就要用到osal_msg_allocation给这个消息分配一个缓存:
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 );
}
注意加粗的代码。首先看一下这个函数的参数len,是什么呢?查手册可以知道,len是msg的长度。那osal_msg_hdr_t *hdr又是什么呢?看一下osal_msg_hdr_t这个数据结构的定义:
typedef struct
{
void *next;
uint16 len;
uint8 dest_id;
} osal_msg_hdr_t;
这个实际上是消息的头部。再看下一句:
hdr = (osal_msg_hdr_t *) osal_mem_alloc( (short)(len + sizeof( osal_msg_hdr_t )) );
这句代码是给消息分配缓存区的,而缓存区的大小是len + sizeof( osal_msg_hdr_t )),也就是消息的大小+消息头的大小。
到这里我们隐约能感觉到,一个消息应该是由两部分组成:消息头和消息的实际内容,消息头是协议栈定义好的,而消息的内容则应该是我们自己添加的。大家再关注一下osal_msg_allocate的代码,可以看出,除了分配缓存以外,它还赋给了消息头一个初始值,但是却没有对消息本身做什么处理。因为消息是要留给大家自己定义的,所以osal_msg_allocate将指向消息头hdr下一位的指针做为函数的返回值,以便大家添加自己的消息代码。
至于消息的具体定义,可以分为两种:系统消息和用户消息。系统消息什么的拜托协议栈就好啦,而用户消息就需要大家根据实际的要求动手了^0^
(在接下来的内容中,完整的消息被认为是已经定义好的,直接拿来用就可以了。)
step2:osal_msg_send
if ( msg_ptr == NULL )
return ( INVALID_MSG_POINTER );
if ( destination_task >= tasksCnt )
{
osal_msg_deallocate( msg_ptr );
return ( INVALID_TASK );
}
// Check the message header
if ( OSAL_MSG_NEXT( msg_ptr ) != NULL ||
OSAL_MSG_ID( msg_ptr ) != TASK_NO_TASK )
{
osal_msg_deallocate( msg_ptr );
return ( INVALID_MSG_POINTER );
}
OSAL_MSG_ID( msg_ptr ) = destination_task;
// queue message
osal_msg_enqueue( &osal_qHead, msg_ptr );
// Signal the task that a message is waiting
osal_set_event( destination_task, SYS_EVENT_MSG );
return ( SUCCESS );
}
step3:osal_msg_receive
{
afIncomingMSGPacket_t *MSGpkt;
if ( events & SYS_EVENT_MSG )
{
MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( SampleApp_TaskID );
while ( MSGpkt )
{
switch ( MSGpkt->hdr.event )
{
// Received when a key is pressed
case KEY_CHANGE:
SampleApp_HandleKeys( ((keyChange_t *)MSGpkt)->state, ((keyChange_t *)MSGpkt)->keys );
break;
// Received when a messages is received (OTA) for this endpoint
case AF_INCOMING_MSG_CMD:
SampleApp_MessageMSGCB( MSGpkt );
break;
{
osal_event_hdr_t hdr; /* OSAL Message header */
uint16 groupId; /* Message's group ID - 0 if not set */
uint16 clusterId; /* Message's cluster ID */
afAddrType_t srcAddr; /* Source Address, if endpoint is STUBAPS_INTER_PAN_EP,
it's an InterPAN message */
uint16 macDestAddr; /* MAC header destination short address */
uint8 endPoint; /* destination endpoint */
uint8 wasBroadcast; /* TRUE if network destination was a broadcast address */
uint8 LinkQuality; /* The link quality of the received data frame */
uint8 correlation; /* The raw correlation value of the received data frame */
int8 rssi; /* The received RF power in units dBm */
uint8 SecurityUse; /* deprecated */
uint32 timestamp; /* receipt timestamp from MAC */
afMSGCommandFormat_t cmd; /* Application Data */
} afIncomingMSGPacket_t;
{
uint8 event;
uint8 status;
} osal_event_hdr_t;
最后
以上就是冷静月饼为你收集整理的ZStack OSAL的事件(event)与消息(message)——part 2的全部内容,希望文章能够帮你解决ZStack OSAL的事件(event)与消息(message)——part 2所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复