Sampleapp函数解析
- 格式:doc
- 大小:56.00 KB
- 文档页数:7
Z-Stack1.4.3-1.2.1中SampleApp中重要函数解析 (2010-11-30 10:26)分类:ZigBee 技术学习在上几篇文章中我们分析了,整个OSAL的流程,还有添加自己的任务,以及如何运行到自己定义的任务。
这一篇文章主要是分析一下,自己定义的任务中要完成的功能,需要的事件函数是怎样的。
这个例子就是一个简单的点对点的数据发送,其中涉及到较少的网络配置,其中最主要的两个函数是SampleApp_ProcessEvent(uint8 task_id,uint16 events),和SampleApp_Init(taskID),一个是任务的处理函数,一个是初始化函数。
SampleApp_Init(taskID)这个函数在前面的文章中也已经分析过了,现在主要关注一下SampleApp_ProcessEvent(uint8 task_id,uint16 events)函数的实现。
每个应用任务都通过SampleApp_ProcessEvent()函数来处理任务中的事件。
一旦SampleApp_TaskID任务的某个OSAL 事件发生,那么就可以通过调用SampleApp_ProcessEvent()函数来处理。
在SampleApp_ProcessEvent()中有一个事件处理循环,循环检测是哪个事件发生。
/******************************************************************** ** @fnSampleApp_ProcessEvent** @brief Generic Application Task event processor. This function* is called to process all events for the task. Events* include timers, messages and any other user defined events.* 这个函数被用来调用处理所有的事件,事件有定时器消息用户自己定义的* @paramtask_id - The OSAL assigned task ID.任务ID号* @param events - events to process. This is a bit map and can* contain more than one event. 处理的事件,这是一个位图** @return none*/uint16 SampleApp_ProcessEvent( uint8 task_id, uint16 events ){afIncomingMSGPacket_t *MSGpkt;//系统事件号SYS_EVENT_MSG = 0x8000if ( events & SYS_EVENT_MSG ){//检索收到的命令,没有收到返回NULLMSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( SampleApp_TaskID ); while ( MSGpkt ) //如果不为空时,判断消息的类型{switch ( MSGpkt->hdr.event ) //这里是判断SYS_EVENT_MSG事件类型,不同的SYS_EVENT_MSG类型需要不同的处理。
{/* Received when a key is pressed这里判断是否是键盘事件,如果键盘事件就调用键盘处理函数。
如果一个OSAL任务已经被登记组侧,那么任何键盘事件都将接受一个KEY_CHANGE事件信息。
可能有如下几种方式得到键盘事件信息1)、HAL检测到键盘按下(中断或者查询检测)2)、HAL的OSAL任务检测到一个键盘状态改变调用回叫函数产生3)、OSAL键盘改变回叫函数发送一个OSAL系统事件信息(KEY_CHANGE)。
*/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;// Received whenever the device changes state in the network 网络中的设备状态发生改变时,产生的事件消息case ZDO_STATE_CHANGE:SampleApp_NwkState = (devStates_t)(MSGpkt->hdr.status); //获得当前的状态if ( (SampleApp_NwkState == DEV_ZB_COORD) //判断其类型|| (SampleApp_NwkState == DEV_ROUTER)|| (SampleApp_NwkState == DEV_END_DEVICE) ){// Start sending the periodic message in a regular interval. 发送周期信息osal_start_timerEx(SampleApp_TaskID,SAMPLEAPP_SEND_PERIODIC_MSG_EVT,SAMPLEAPP_SEND_PERIODIC_MSG_TIMEOUT );}else{// Device is no longer in the network}break;default:break;}// Release the memory 释放内存osal_msg_deallocate( (uint8 *)MSGpkt );// Next - if one is available 得到任务中下一个等待处理的事件MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( SampleApp_TaskID );}// return unprocessed events 返回没有处理的事件return (events ^ SYS_EVENT_MSG);}// Send a message out - This event is generated by a timer// (setup in SampleApp_Init()). 向外发送信息,该事件是由定时器产生if ( events & SAMPLEAPP_SEND_PERIODIC_MSG_EVT ){// Send the periodic message 发送周期信息SampleApp_SendPeriodicMessage();// Setup to send message again in normal period (+ a little jitter) 第三个参数是定时的时间osal_start_timerEx(SampleApp_TaskID,SAMPLEAPP_SEND_PERIODIC_MSG_EVT,(SAMPLEAPP_SEND_PERIODIC_MSG_TIMEOUT + (osal_rand() & 0x00FF)) );// return unprocessed events 返回没有处理的事件return (events ^ SAMPLEAPP_SEND_PERIODIC_MSG_EVT);}// Discard unknown eventsreturn 0;}说明:(1)afIncomingMSGPacket_t *MSGpkt; 其中afIncomingMSGPacket_t是一个结构体,这个结构体中包括传输的帧的格式。
typedefstruct{osal_event_hdr_thdr;uint16groupId;uint16clusterId;afAddrType_tsrcAddr;byteendPoint;bytewasBroadcast;byteLinkQuality;byteSecurityUse;uint32 timestamp;afMSGCommandFormat_tcmd;} afIncomingMSGPacket_t;(2) 这里的SYS_EVENT_MSG是系统事件,也是协议栈已经定义好的系统事件,在文件ZcomDef.h中,事件号是一个16bit的常量,使用叫作独热码(one-hot code)编码,也是一个位表示一个事件,方便进行event的提取,这样一个task最多可以有16个event,SYS_EVENT_MSG已经占用了0x8000,故自定义的个事件只能有15个,事件的提取和清除可以用简单的位操作指令实现,事件的提取可以用位与操作events & SYS_EVENT_MSG,事件的清除可以用异或操作实现,evets ^ SYS_EVENT_MSG ,系统事件包括了各种系统消息(message),系统事件中的消息号是一个8bit常量,也就是一事件可以包括255个消息,定义在ZcomDef.h 中。
#define SYS_EVENT_MSG 0x8000 // A message is waiting event/******************************************************************** ** Global System Messages*/#define SPI_INCOMING_ZTOOL_PORT 0x21 // Raw data from ZTool Port (not implemented)#define SPI_INCOMING_ZAPP_DATA 0x22 // Raw data from the ZAPP port (see serialApp.c)#define MT_SYS_APP_MSG 0x23 // Raw data from an MT Sys message#define MT_SYS_APP_RSP_MSG 0x24 // Raw data output for an MT Sys message #define AF_DATA_CONFIRM_CMD 0xFD // Data confirmation#define AF_INCOMING_MSG_CMD 0x1A // Incoming MSG type message#define AF_INCOMING_KVP_CMD 0x1B // Incoming KVP type message#define AF_INCOMING_GRP_KVP_CMD 0x1C // Incoming Group KVP type message#define KEY_CHANGE 0xC0 // Key Events#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用户自己定义的系统事件的消息范围为0xE0—0xFF,下面是几个比较常用的系统事件的消息。