zigbee基础知识笔记

发布时间:

精品文档

1.基础知识.......................................11.1IEEE地址...................................11.2.........................................21.3ProfileID.................................41.4网络地址与端点号、节点.....................41.5PANID......................................51.6zigbee设备................................52.绑定机制.......................................72.1描述符绑定.................................72.2设备绑定..................................23
1.基础知识1.1IEEE地址
IEEE地址是64位,在设备进入网络之前就分配好了的,应该在全球是唯一的,
而网络地址是在网络建立后,设备加入网络时,它的父节点给它分配的,在设备通信时,
首先由ieee地址找到设备的网络地址,然后根据网络地址实现设备之间的通信,
这样可以减少帧头长度,多传有效数据
通俗的说IEEE地址相当于你的手机号(11位的那个),
.

精品文档
短地址就相当于你们公司的小号(34位,一个公司的互打电话就用小号噻。
假设你的手机号138xxxxx666这个是唯一的,但你的小号,假设是666在你的公司网中是唯一的,但是在另一个网中,可能别人的小号也是6661.2
簇就是相当于端点房间里面的人,是接收最终的目标。这东西是2个字节编号,
在射频发送的时候,必须要指定接收模块的镞,发送模块不需要指定。
首先每一个端点可以看成是一个1个字节数字编号的开有一扇门的房间,
数据最终的目标是进入到无线数据包指定的目标端点房间,而取无线数据这个相关的代码在任务事件处理函数里,TI议栈有那么多的任务事件处理函数,所以必须要指定在哪个任务事件处理函数来取这个无线数据包里面的有用数据。端点就相当于一个房间的门牌号!!!
SimonApp_epDesc.endPoint=10;//SimonApp_ENDPOINT;此端点编号为10
SimonApp_epDesc.task_id=&SimonApp_TaskID;和我们应用层任务挂钩

.

精品文档
SimonApp_SimpleDesc里面,
这里面却只是起到一个信息表的作用!方便数据到来的时候查询相关信息表!const
SimonApp_ClusterList[SimonApp_MAX_CLUSTERS]={
SimonApp_CLUSTERID};
constSimpleDescriptionFormat_tSimonApp_SimpleDesc={
SimonApp_ENDPOINT,//intEndpoint;SimonApp_PROFID,//uint16AppProfId[2];
SimonApp_DEVICEID,//uint16AppDeviceId[2];
SimonApp_DEVICE_VERSION,//intAppDevVer:4;
SimonApp_FLAGS,//intAppFlags:4;
SimonApp_MAX_CLUSTERS,//byteAppNumInClusters;
.
cId_t

精品文档
(cId_t*SimonApp_ClusterList,//byte*pAppInClusterList;
SimonApp_MAX_CLUSTERS,//byteAppNumInClusters;
(cId_t*SimonApp_ClusterList//byte*pAppInClusterList;};
接收到数据以后,判断是属于哪一个端点、属于哪一个簇1.3ProfileID
这个是由Zigbee组织来分配的应用ID号,比如无线开关用0x0001
智能电表用ox0002,万用遥控器用0x0003等等。在这个例子里,这个ID号是专门用来做电灯开关的。
为什么要这么做呢?这里就体现了“标准”的意义,不同厂家功能的设备,
由于有了这个ID就能互相间使用了,你使用这种开关一样可以达到别的开关控制灯的效果1.4网络地址与端点号、节点
zigbee中,节点对应主机,相当于一个物理射频模块,一个端点对应一个任务号,即交由哪一个任务对象,端点号在端点描述符中,是要向操作系统注册端点描述符的,网络中的一个数据消息通过寻址(即网络地址)到达一个节点,
.

精品文档
节点收到消息后,操作系统查看消息端点对应的任务号,然后交由这个任务号的事件处理函数执行。1.5PANID
PANID就是个人网络id号,Zigbee协议规定,用一个14的个人域网来标识一个网络,1.6zigbee设备
Zigbee定义了三种功能的设备,每种设备都有自己的功能要求:
ZigBee协调器是启动和配置网络的一种设备。协调器可以保持间接寻址用的绑定表格,支持关联,同时还能设计信任中心和执行其它活动。
一个ZigBee网络只允许有一个ZigBee协调器。
ZigBee路由器是一种支持关联的设备,能够将消息转发到其它设备。
ZigBee网格或树型网络可以有多个ZigBee路由器。ZigBee星型网络不支持ZigBee路由器。
ZigBee终端设备可以执行它的相关功能,并使用ZigBee络到达其它需要与其通信的设备。它的存储器容量要求最少Zigbee协议栈类似ucos,有自己的任务调度,不过它是轮询,没有优先级,只要查询到每一层有相应的事件发生,就进行处理。具体代码如下:voidosal_run_system(void
.

精品文档
{
uint8idx=0;
osalTimeUpdate(;Hal_ProcessPoll(;do{
if(tasksEvents[idx]//Taskishighestprioritythatisready.{break;}
}while(++idx
if(idx{
uint16events;
halIntState_tintState;
HAL_ENTER_CRITICAL_SECTION(intState;events=tasksEvents[idx];
tasksEvents[idx]=0;//CleartheEventsforthis
.

精品文档
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;//Addbackunprocessedeventstothecurrenttask.HAL_EXIT_CRITICAL_SECTION(intState;}2.绑定机制
绑定机制即绑定之后就不用知道对方的地址就可以发送数据过去,对方的的地址可以在绑定表中查询,绑定非常灵活,也是难点,例如假设有两个按键,可以通过绑定将一个按键控制其他的三个灯,另一个按键控制两个窗帘。绑定比较常见的两种绑定是描述符绑定跟设备绑定。2.1描述符绑定
设置允许设备响应ZDO的描述符匹配请求
afSetMatch(sapi_epDesc.simpleDesc->EndPoint,TRUE;
.

精品文档
Zigbee协议栈默认是允许的
有了允许绑定就会有绑定请求,在myAllowBindTimeout定的时间内,终端设备调用zb_BindDevice(函数,请求绑定。由于zb_BindDevice(函数的第三个参数是NULL,所以是以,未知IEEE地址的绑定。zb_HandleKeys(函数中调用了,
zb_BindDevice(TRUE,
TOGGLE_LIGHT_CMD_ID,
NULL;
zb_BindDevice函数中调用了ZDP_MatchDescReq(函数,这个函数的参数,在上一篇文章中也做了介绍,这个函数是是初始化一个匹配描述符请求,也就是发现服务,或者叫自destination.addr.shortAddr=NWK_BROADCAST_SHORTADDR;终端发起请求:
afStatus_tZDP_MatchDescReq(zAddrType_t*dstAddr,uint16nwkAddr,uint16ProfileID,
byteNumInClusters,cId_t*InClusterList,
byteNumOutClusters,cId_t*OutClusterList,
byteSecurityEnable
.

精品文档
----->returnfillAndSend(&ZDP_TransID,dstAddr,Match_Desc_req,len;
----->returnAF_DataRequest(&afAddr,&ZDApp_epDesc,clusterID,
(uint16(len+1,(uint8*(ZDP_TmpBuf-1,
transSeq,ZDP_TxOptions,AF_DEFAULT_RADIUS;
Match_Desc_req发送至协调器的ZDO
协调器控制端:
控制接收到匹配请求后,对其匹配作出响应。目的设备收到
ZDAppTaskID

AF_INCOMING_MSG_CMDZDAppTaskID任务的事件处理函数ZDApp_event_loop(),然后调用ZDApp_ProcessOSALMsg()函数,在这个函数中调ZDP_IncomingData函数。caseAF_INCOMING_MSG_CMD:ZDP_IncomingData(*msgPtr;break;
.
(afIncomingMSGPacket_t

精品文档
在这里调用了ZDP_IncomingData(函数,下面是这个函数的源代码。这个函数表明了PDU数据从APS子层->ZDO层的数据传输。因为ZDO层是管理绑定的(绑定表建在APS,ZDOZDO_SendMsgCBs函数会生成sapi_TaskIDZDO_CB_MSGSAPI_ProcessZDOMsgs(Match_Desc_rsp选项
通过ZDO_SendMsgCBs(这个函数把ZDO信息发送到注册过ZDO信息的任务中去.比如sapiSAPI_Init(注册过两种
clusterId

ZDONWK_addr_rsp
Match_Desc_rspMatch_Desc_rep一般不会发送到sapi应用层中注意,即使发送了也不会处理,可以在如下代码中看到是发送了的,这里只会对请求/设置/通知命令才调用相应处理函数,如果是响应命令则不处理。但是要ZDO信息处理表中包含的命令才有相应的处理函数,有些没有的就不会调用
End_Device_Bind_req这个ZDO信息是注册在ZDAppTaskID任务中的.
DApp_ProcessOSALMsg-->DP_IncomingData--->ZDO_SendMsgCBs
ZDO_SendMsgCBs(&inMsg;ZDO接收信息发送到注册过
.

精品文档
ZDO信息的任务中去;具体流程是比较接收信息的簇ID与注册过的簇ID,有相同则调用osal_msg_send(触发相应任务事件事件这里默认为ZDO_CB_MSG,然后发将消息送SAPI应用层,因此可以看到SAPI_ProcessEvent(中有这个事件.注意这个函数只会传送信息到注册过相应ZDO信息的任务中去。
ZDO_SendMsgCBs部分代码如下:ZDO_MsgCB_t*pList=zdoMsgCBs;while(pList
//接收到的簇ID和注册过的簇ID进行比较if(pList->clusterID==inMsg->clusterID{
msgPtr->hdr.event=ZDO_CB_MSG;
osal_msg_send(pList->taskID,(uint8*msgPtr;ret=TRUE;}
通过代码我们可以看到,这个函数首先是查找一个链表,看看这个链表到底是指向什么的,有下面这样一句话,pList指向了zdoMsgCBs。它的结构定义也如下:ZDO_MsgCB_t*pList=zdoMsgCBs;
.

精品文档
ZDO_MsgCB_t*zdoMsgCBs=(ZDO_MsgCB_t*NULL;typedefstruct{
void*next;uint8taskID;uint16clusterID;}ZDO_MsgCB_t;
ZDO_MsgCB_t的赋值,也就是作为左值。
ZStatus_tZDO_RegisterForZDOMsg(uint8taskID,uint16clusterID
……………………..zdoMsgCBs=pNew;……………………………
这个函数的意思就是注册ZDO消息,我们可以回过头来看一ZDO_SendMsgCBs函数,这个函数中有了个while(pList;的循环,如果没有在ZDO_RegisterForZDOMsg()函数中注册的话,那意味着,这个循环是不成立的,也就是说为什么只有ZDO消息注册后才会真正的执行这个函数,但又有一个
.

精品文档
问题,在SAPI_Init(函数中,我们可以发现下面两句话voidSAPIApp_Init(bytetask_id{
ZDO_RegisterForZDOMsg(End_Device_Bind_rsp;ZDO_RegisterForZDOMsg(Match_Desc_rsp;}
oidZDApp_RegisterCBs(void{
#ifdefined(ZDO_IEEEADDR_REQUEST||defined(REFLECTOR
HalUARTWrite(0,"IEEADDR",sizeof("IEEADDR";//zc
ZDO_RegisterForZDOMsg(IEEE_addr_rsp;#endif
#ifdefined(ZDO_NWKADDR_REQUEST||defined(REFLECTOR
HalUARTWrite(0,"ZDO_NWKADDR",sizeof("
.
GenericApp_TaskID,
GenericApp_TaskID,
ZDAppTaskID,

精品文档
ZDO_NWKADDR";ZDO_RegisterForZDOMsg(NWK_addr_rsp;//zc#endif
#ifZG_BUILD_COORDINATOR_TYPE
HalUARTWrite(0,"register",sizeof("register";//c
ZDO_RegisterForZDOMsg(ZDAppTaskID,Bind_rsp;ZDO_RegisterForZDOMsg(ZDAppTaskID,Unbind_rsp;ZDO_RegisterForZDOMsg(End_Device_Bind_req;#endif
#ifdefined(REFLECTOR
HalUARTWrite(0,"LECT",sizeof("LECT";ZDO_RegisterForZDOMsg(ZDAppTaskID,Bind_req;ZDO_RegisterForZDOMsg(Unbind_req;//zc#endif}
在这里对这两个响应消息进行了注册,注意这里的任务ID都是sapi_TaskID,还有一个地方也对End_Device_Bind_req进行了注册,也就是在ZDApp_RegisterCBs(void函数中,
.
ZDAppTaskID,
ZDAppTaskID,
ZDAppTaskID,

精品文档
这个函数在初始化函数ZDApp_Init(taskID++;中被调用。当然这里还注册了很多其它的消息。问题就又来了,那既然这个链表是不为空的,这个函数的while(pList;就会成功执行,但下面还有一层验证就是簇ID,不要忘记我们的簇ID是什么,我们收到是Match_Desc_rep;而我们注册的是Match_Desc_rsp所以在这个链表中找不到这个簇ID所以也就不会触发msgPtr->hdr.event=ZDO_CB_MSG;继续向下执行。也就执行到了zdpMsgProcs[x].pFn(&inMsg处理函数
从这里我们也可以总结一下,我们知道在ZigBee中有四种格式的原语,分别是RequestIndicationResponseConfirm,这里注册的XX_XX_req,就表示的是请求消息,XX_XX_rsp就是响应消息。一定要注意的时这里只相差一个字母的区别
pfnZDPMsgProcessor声明为一种带一个参数的函数指针的类型别名,指向类似Fun(*inMsg这种类型的函数.如果用此别名来声明一个指针变量,如:pfnZDPMsgProcessorpFn,则当pFn获取函数的地址后,就可以像调用原函数一样来使用这个函数指针:pFn(*inMsg
typedefvoid(*pfnZDPMsgProcessor(zdoIncomingMsg_t
.

精品文档
*inMsg;typedefstruct{
uint16clusterID;pfnZDPMsgProcessorpFn;}zdpMsgProcItem_t;
定义一个zdpMsgProcItem_t类型的数组zdpMsgProcs[]数组zdpMsgProcs[]中的每个元素都是zdpMsgProcItem_t型的结构体:{clusterID,pFn}也就是一个是簇ID另一个是相对应的处理函数。
CONSTzdpMsgProcItem_tzdpMsgProcs[]={
{NWK_addr_req,zdpProcessAddrReq},{IEEE_addr_req,zdpProcessAddrReq},{
ZDO_ProcessNodeDescReq},{
ZDO_ProcessPowerDescReq},{
ZDO_ProcessSimpleDescReq},{
.
Node_Desc_req,
Power_Desc_req,
Simple_Desc_req,
Active_EP_req,

精品文档
ZDO_ProcessActiveEPReq},{
ZDO_ProcessMatchDescReq},…………(后面省略{0xFFFF,NULL}//Last};
既然ZDO_SendMsgCBs()函数不执行,那么就会查找ZDO信息处理表,x=6时发现命令相符,两个簇ID相同,则调ZDO_ProcessMatchDescReq(对描述符匹配请求进行处.
部分代码如下:
pRspSent->hdr.event=ZDO_MATCH_DESC_RSP_SENT;…………osal_msg_send((uint8*pRspSent;
//task_idSAPIApp_TaskIDSPAIApp_ProcessEvent中,但是处理函数并未找到对应的处理函数,
所以会执行下面语句:default:
HalUARTWrite(0,"default",sizeof("default";//自己加的
.
Match_Desc_req,
*epDesc->epDesc->task_id,

精品文档
break;
if(ZSuccess==ZDP_MatchDescRsp(inMsg->TransSeq,&(inMsg->srcAddr,ZDP_SUCCESS,
ZDAppNwkAddr.addr.shortAddr,(uint8*ZDOBuildBuf,inMsg->SecurityUse{
#ifdefined(LCD_SUPPORTED
HalLcdWriteScreen("MatchDescReq","RspSent";
//显示屏会证明执行到这里#endif}
ZDP_MatchDescRsp
可以看到这里管理器首先通过ZDP_MatchDescRsp(发送匹.ZDP_MatchDescRsp(ZDP_EPRsp(
#defineZDP_MatchDescRsp(TransSeq,dstAddr,Status,nwkAddr,Count,\
pEPList,SecurityEnable\ZDP_EPRsp(TransSeq,dstAddr,Status,\
nwkAddr,Count,pEPList,
.
epCnt,
Match_Desc_rsp,

精品文档
SecurityEnable
ZDP_EPRsp(clusterIDMatch_Desc_rsp调用FillAndSendTxOptions(FillAndSendTxOptions(
fillAndSend(
fillAndSend(中最终调用AF_DataRequest(来发送匹配响应给终端。发送完匹配响应后管理器触发一个确认事件ZDO_MATCH_DESC_RSP_SENT,来指示有个设备试图与自己绑.管理器是如何对这个确认事件进行处理的?如下:SAPI_ProcessEvent(中对ZDO_MATCH_DESC_RSP_SENT的处理:
caseZDO_MATCH_DESC_RSP_SENT:/*发送匹配响应*/
SAPI_AllowBindConfirm(*pMsg->nwkAddr;
管理器接收到终端发送的描述符匹配请求后,发送一个描述符匹配请求的响应给终端,并触发一个确认事件指示有个设备试图与本设备进行绑定.终端:
ZDAppTaskIDAF_INCOMING_MSG_CMD事件。调用ZDP_IncomingData(ZDO_SendMsgCBs(
.
((ZDO_MatchDescRspSent_t

精品文档
ZDO_SendMsgCBs函数会生成sapi_TaskIDZDO_CB_MSGSAPI_ProcessZDOMsgs(Match_Desc_rsp选项。
ZDP_IncomingData(
ZDO_SendMsgCBs(函数,因为在SAPI_Init(函数中,对Match_Desc_rsp进行了注册,这次在终端收到的是匹配请求


ZDO_RegisterForZDOMsg(
sapi_TaskID,
Match_Desc_rsp;Match_Desc_rep相对应,所以下面的zdpMsgProcs[]数组中到与Match_Desc_rsp相匹配,这时就触发ZDO_CB_MSGMatch_Desc_rep相反。ZDO_SendMsgCBs
osal_msg_send(pList->taskID,(uint8*msgPtr;taskIDSAPIApp_TaskID
SAPI_ProcessZDOMsgs部分代码如下:caseZDO_CB_MSG:
SAPI_ProcessZDOMsgs(*pMsg;break;caseMatch_Desc_rsp:{
.
(zdoIncomingMsg_t

精品文档
zAddrType_tdstAddr;ZDO_ActiveEndpointRsp_tZDO_ParseEPListRsp(inMsg;
if(sapi_bindInProgress!=0xffff//允许基于commandID的绑定{
//Createabindingtableentry创建一个绑定条目
dstAddr.addrMode=Addr16Bit;dstAddr.addr.shortAddr=pRsp->nwkAddr;//通过描述符匹配响应信息得到管理器的网络地址/*调用这个函数来实现两个设备的绑定*/if
(APSME_BindRequest(sapi_epDesc.simpleDesc->EndPoint,//EP
sapi_bindInProgress,//ID
&dstAddr,//目的地址模式
pRsp->epList[0]==ZSuccess//目的EP
//成功实现绑定后
.
*pRsp=

精品文档
{
//zb_BindDevice(中开启了一个定时器,用于接Match_Desc_rsp计时
//如果接收到,则停止这个定时器,如下;如果溢出,则触发相应任务事件
osal_stop_timerEx(sapi_TaskID,ZB_BIND_TIMER;
osal_start_timerEx(ZDO_NWK_UPDATE_NV,250;
sapi_bindInProgress=0xffff;//不允许绑定过程
//FindIEEEaddrZDP_IEEEAddrReq(ZDP_ADDR_REQTYPE_SINGLE,0,0;
//Sendbindconfirmcallbacktoapplication
//告诉应用绑定成功zb_BindConfirm(ZB_SUCCESS;}}}
.
ZDAppTaskID,
pRsp->nwkAddr,
sapi_bindInProgress,

精品文档
break;}}
最终过程如下:终端-->控制器控制器-->终端
终端发起绑定请求,控制器处理,并发送响应请求,终端收到响应请求,进行处理
可以看到通过接收到的描述符匹配响应信息,终端获得允许绑定模式下管理器的16位网络地址:
dstAddr.addr.shortAddr=pRsp->nwkAddr;APSME_BindRequest(来绑定终端设备与管理器.这样整个的绑定过程就结束,两个设备之间就可以进行相互的通信。这里采用的手动绑定的过程。很多情况下应该是自动绑定的。
2.2设备绑定
数据通打包成消息,最终通过无线发送出去,events&SYS_EVENT_MSG会成立,最终在事件处理器中会到
.

精品文档
caseAF_INCOMING_MSG_CMD:终端:afStatus_t*dstAddr,
uint16LocalCoordinator,
byteendPoint,uint16ProfileID,byteNumInClusters,cId_t*InClusterList,
byteNumOutClusters,cId_t*OutClusterList,
byteSecurityEnable
dstAddr.addrMode=Addr16Bit;
dstAddr.addr.shortAddr=0x0000;//CoordinatorZDP_EndDeviceBindReq(NLME_GetShortAddr(,GenericApp_epDesc.endPoint,
GENERICAPP_PROFID,
.
ZDP_EndDeviceBindReq(zAddrType_t
&dstAddr,

精品文档
GENERICAPP_MAX_CLUSTERS,(cId_t*GenericApp_ClusterList,
GENERICAPP_MAX_CLUSTERS,(cId_t*GenericApp_ClusterList,FALSE;ZDP_EndDeviceBindReq-->returnfillAndSend(
End_Device_Bind_req,
len------>AF_DataRequest(&afAddr,&ZDApp_epDesc,clusterID,
(uint16(len+1,(uint8*(ZDP_TmpBuf-1,
transSeq,ZDP_TxOptions,AF_DEFAULT_RADIUS;
协调器控制端:
协调器收到终端设备绑定请求End_Device_Bind_req这个信息会传送到ZDO层,在ZDO层的事件处理函数中,调
ZDApp_ProcessOSALMsg(
(osal_event_hdr_t
&ZDP_TransID,
dstAddr,
*msg_ptr;
ZDApp_event_loop--->ZDApp_ProcessOSALMsg-->caseAF_INCOMING_MSG_CMD:
.

精品文档
-->ZDP_IncomingData(*msgPtr
(afIncomingMSGPacket_t
ZDP_IncomingData它的代码部分如下:ZDO_SendMsgCBs(&inMsg
if(zdpMsgProcs[x].clusterID==inMsg.clusterID{
HalLedBlink(HAL_LED_1,9,50,1000;
HalUARTWrite(0,"endclusterID",sizeof("endclusterID";
LCD_write_CN_string(9,110,"ttttt";zdpMsgProcs[x].pFn(&inMsg;return;}
ZDOzdpMsgProcs[]End_Device_Bind_req,因此没有调用ZDO信息处理表中的处理函数,但是前面的ZDO_SendMsgCBs(会把这个终端设备绑定请求发送到登记过这个ZDO信息的任务中去。那这个登记注册的程序在哪里呢?
对于协调器来说,由于在voidZDApp_Init(bytetask_id函数中调用了ZDApp_RegisterCBs(;面的函数。进行注册了
.

精品文档
终端绑定请求信息。。
voidZDApp_RegisterCBs(void{
#ifdefined(ZDO_IEEEADDR_REQUEST||defined(REFLECTOR
HalUARTWrite(0,"IEEADDR",sizeof("IEEADDR";//zc
ZDO_RegisterForZDOMsg(IEEE_addr_rsp;#endif
#ifdefined(ZDO_NWKADDR_REQUEST||defined(REFLECTOR
HalUARTWrite(0,"ZDO_NWKADDR",sizeof("ZDO_NWKADDR";ZDO_RegisterForZDOMsg(NWK_addr_rsp;//zc#endif
#ifZG_BUILD_COORDINATOR_TYPE
HalUARTWrite(0,"register",sizeof("register";//c
ZDO_RegisterForZDOMsg(ZDAppTaskID,Bind_rsp;
.
ZDAppTaskID,
ZDAppTaskID,

精品文档
ZDO_RegisterForZDOMsg(ZDAppTaskID,Unbind_rsp;ZDO_RegisterForZDOMsg(End_Device_Bind_req;#endif
#ifdefined(REFLECTOR
HalUARTWrite(0,"LECT",sizeof("LECT";ZDO_RegisterForZDOMsg(ZDAppTaskID,Bind_req;ZDO_RegisterForZDOMsg(Unbind_req;//zc#endif}
GenericApp_Init(中初始化的是ZDO_RegisterForZDOMsg(End_Device_Bind_rsp;ZDO_RegisterForZDOMsg(Match_Desc_rsp;
因此,协调器节点的ZDApp接收到外界输入的数据后,由于注册了ZDO反馈消息,即ZDO_CB_MSGZDApp层任务事件处理函数将进行处理:也就是调用下面的程序,也就是ZDApp_event_loop-->ZDApp_ProcessOSALMsg--->caseZDO_CB_MSG-->ZDApp_ProcessMsgCBs
.
ZDAppTaskID,
ZDAppTaskID,
TransmitApp_TaskID,
TransmitApp_TaskID,

精品文档

caseEnd_Device_Bind_req:
HalUARTWrite(0,"End_bind_reqt",sizeof("End_bind_reqt";
if(ZG_DEVICE_COORDINATOR_TYPE{
ZDEndDeviceBind_tbindReq;
ZDO_ParseEndDeviceBindReq(inMsg,&bindReq;ZDO_MatchEndDeviceBind(&bindReq;
if(bindReq.numInClusters
osal_mem_free(bindReq.inClusters;if(bindReq.numOutClusters
osal_mem_free(bindReq.outClusters;}break;
ZDO_MatchEndDeviceBind(函数,如果协调器接收到接收到第一个绑定请求,则分配内存空间进行保存并计时,如果不是第一个绑定请求,则分别以第一个和第二个绑定请求为源绑定,进行比较匹配,如果比较匹配成功则发送匹配成功的End_Device_Bind_rspZDMatchSendState(
.


精品文档
ZDP_EndDeviceBindRsp(函数,对匹配请求响应进行了发送。如果匹配不成功则发送匹配失败的信息给两个终端。
ZDP_EndDeviceBindRsp-->
ZDP_SendData-->FillAndSendTxOptions-->fillAndSend->AF_DataRequest(&afAddr,&ZDApp_epDesc,clusterID,(uint16(len+1,(uint8*(ZDP_TmpBuf-1,
transSeq,ZDP_TxOptions,AF_DEFAULT_RADIUS;
ZDP_SendData(&TransSeq,dstAddr,End_Device_Bind_rsp,1,&Status,SecurityEnable
终端:
ZDApp_event_loop-->
msg_ptr=osal_msg_receive(ZDAppTaskID-->ZDApp_ProcessOSALMsg--->caseAF_INCOMING_MSG_CMDZDP_IncomingData(*msgPtr-->
ZDO_SendMsgCBs(zdoIncomingMsg_t*inMsg在此函数中,查找匹配
.
(afIncomingMSGPacket_t

精品文档
注册过的簇。
在之前的sapiapp_RegisterCBs(void中,因为ZDO_RegisterForZDOMsg(End_Device_Bind_rsp;
所以if(pList->clusterID==inMsg->clusterID成立
msgPtr->hdr.event=ZDO_CB_MSG;
osal_msg_send(pList->taskID,(uint8*msgPtr;caseZDO_CB_MSG:sapiapp_ProcessMsgCBs(*msgPtr-->
switch(inMsg->clusterID--->caseEnd_Device_Bind_rsq:群集跟簇的概念事相同的。
(zdoIncomingMsg_tGenericApp_TaskID,
.

zigbee基础知识笔记

相关推荐