#ifdcfincd(MT_TASK)
MT_TaskInit(taskir)++);
#cndif
APS_Init(taskir)++);
ZDApp_Init(taskID++);〃判断如果协调器节点逹立网络、如果终端节点加入网络
SAPI_Init(laskID);
}
1.3初始化ZigBee协议栈网络
ZDApp.c
C++Code
voidZr)App_Init(uint8taskjd)
{
//SavethetaskID
ZDAppTasklD=task_id;
//InitializetheZDOglobaldeviceshortaddressstorage
ZDAppNwkAddr.addrModc=Addrl6Bit;
ZDAppNwkAddr.addr.shortAddr=INVALir>_N()DE_ADDR;
(void)NLME_GctExtAddrQ;//LoadthesavcExtAddrpointer.
//CheckformanualnHoldAutoStartu
//检测到有手工设置HAL_KEY_SW_1则会设置dcvStatc二DEV_H()LD,从而避开网络初始化
ZDAppChcckForHoIdKcyO;
//InitializeZD()itemsandsetupthedevice・typeofdevicetocreate・
ZDOJnitO;//通过判断预编译来开启一些函数功能
//RegistertheendpointdescriptionwiththeAF
//ThistaskdocsnrthaveaSimpledescription,butwestillneed
//toregistertheendpoint.
afRcgistcr((cndPointDcsc_t*)&ZDApp^epDese);
#ifdcfincd(ZD()_USERPESC_RESPONSE)
ZDAppJniiUscrDcscO;
#cndif//ZD()_USERPESC_RESPONSE
//Startthedevice?
if(d^Statc!
=DEV_HOLD)
ZDOInitDevice(0);
{
}else
//BlinkLEDtoindicateH()LD_START
HalLcdBliiik(HAL_LED_4,0,50,500);
}
ZDApp_RcgistcrCBsO;
}/*ZDAppJnitO*/
如果设®d^Statc为DEV_H()LD,则不会执行ZDOlnitPc^ce;反之,系统会调用此函数是设备组网或者入网。
看下这个函数完成的功能是什么样于的。
ZDOlniiD^icc是设备在网络中启动。
它会读取NV中的ZCD_NV_STARTLP_OPTION选项决定是否恢复网络状态。
如果应用层强制进行新的Qin操作,它应该在调用这个函数之前设置ZCD_NV_STARTUP_()PTI()N中的ZCr)_STARTOPT_r)EFAULT_NETW()RK_STATE位。
可以调用zgWricSiariup()ptions()函数完成这些设置。
1.4初始化设备(启动网络和设■:
网络类型)
ZDApp.c
C++Code
uini8ZDOInitDevicc(uintl6startDelay)
{
uint8networkSuteW=ZD()_INITDEV_NEW_NETW()RK_STATE;
uint!
6cxtcndcdDclay=0;
if(dcvSimc二二DEV_H()LD)
//InitializetheRAMitemstable,incaseanNVitemhasbeenupdated・zglnidtcms(FALSE);
}
Zr)Config_Init:
r)cscriptorsO;
//dcvtag.071807.todo-flythistemporansolution
_NIB.Capabilit}lnfo二Zr)O_Config_Nodc_r>cscripior.CapabiIiuFlags;
devStatu=DEVJNIT;//RemovetheHoldstale
个值
//函数读取NV项目ZCP_NV_LEAVE_CTRL的值,ZDApp_Lc他Ctrl指向这
//Initializeleavecontrollogic
Zr)App_LcavcCtrllnitO;
//Checkleavecontrolresetsetrings//设备的断开会造成DEV.HOLP状态
Zr)App_LcavcCtrlStartup(&devState,&startf)clay);
//Leavemaymaketheholdstatecomeback
if(dcvSi毗二二PEV_H()LP)
〃设賈启动选项
//SettheW<7startupoptiontoforcea"new"join・
2gWritcSiartupOptions(ZG_STARTL'P_SET,
ZCD_STARTOPT_DEFAULT_NETW()RK_STATE);
//通知应用层触发事件
//Notifytheapplications
osal_sct_cvcnt(ZDAppTasklD,ZDO_STATE_CHANGE_EVT);
reixirn(ZDOJN1TPEV_LEAVE_NOT_STARTEP);//DonrLjoin-(one
time).
}
#ifdefined(NV_RESTORE)
//GetKeypaddirectlytoseeifaresetnvisneeded・
//HolddowntheSVC_BYPASS_NVkey(definedinOnBoard.h)
//whilebootingtoskippastNVRestore・
if(HalKcyRcadO==SW_BYPASS_NV)
nciworkStatcW二ZP()JN1TOEV_NEW_NET\V()RK_STATE;
else
//通过读取ZCD_NV_STARTL;P_()PTI()N选项决定是否进行网络恢复
//DetermineiFNVshouldberestored
nctworkStateNV=ZDApp_RcadNct^-orkRcstorcStatcO;
if(nciworkStaicNV==ZP()JN1TPEV_REST()REP„NETOX)RK_STATE)
HeworkStateNV二ZDApp^RcstorcNciworkStatcO;
//WipeoutthenetworkstateinNV
NLMEJnitNVO;
NLME.SctDcfaultNVO;
}
#cndifif(nciworkStaicNV==ZP()JN1TPEV_NEW_NETW()RK_STATE)//如果是
要启动新的网络
ZPAppDcicrmincPc^ccTypcO;//根据选项设置设备的网络类型,默认路由
类型
//Onlydelayifjoiningnetwork-notrestoringnetworkstatecxtcndcdDclay=(uiful6)((NWK_START_DELAY+startDclay)+(osal_rand()&EXTENDEDJOINING_RANDONLMASK));
}
//Initializethesecurityfortypeofdevice
ZDApp_SccInit(nct5xrorkStateNV);
//触发启动网络
//Triggerthenetworkstart
ZDApp_NctworUnit:
(cxtcndcdDclay);
//seibroadcastaddressmasktosupportbroadcastfiltering用于处理合法的广插地址
NLME_SetBroadcastFiltcr(ZDO_Config_Node_r)cscriptor.Capabilit\Flags);return(nc^orkSutcNV);
}
这个函数注意功能:
初始化设备配置,ZnAppDctermincDcxnccTypcO设直网络类型(协调、路由、终端),ZPApp.NctworklnitfcxtcndcdDclay)^ZJ始化网络并开启或加入网络。
1.5定时开启网络
ZDApp.c
进入ZDApp_NciWorklniiO函数,等待一段时间在执行ZDO_NETVC()RK_1NIT,跳入事
件处理ZDApp层ZDAPP_EVENT_LOOP0函数开启网络。
C++Code
voidZDApp_Nc^orklnit(uintl6delay)
{
if(delay)
{
//Waitawhilebeforestartingthedevice
osaLsiart_timcrEx(ZDAppTasklD,ZD()_NETW()RK_IN】T,delay);
〃发送ZnO_NETW()RK_INlT(网络初始化)消息到ZDApp层,转到
ZDApp层,Zr)App_cvcnt_loopO函数。
osaLsct_cvcnt(ZPAppTasklD,ZP()_NEW()RKJN1T);
}
1.6启动设备
ZDApp.c
ZDApp.eventJoop0函数是回调函数,循环处理主事件。
设备逻辑类型,启动模式,信
标时间,超帧长度
C++Code
UINT16ZDApp_cvcnt_loop(uint8taskjd,UINT16events)
{
uint8*msg_ptr;
if(events&SYS_EVENT_MSG)
{
while((msg_ptr=osal_msg_rcccivc(ZDAppTasklD)))
{
Zr>App_Proccss()SALMsg((osal_cvcm_hdr_r*)msg_ptr);
//Releasethememory
osal_msg_dcallocatc(msg_ptr);
}reixirn(eventsASYS.EVENT.MSG);
//Initializeappsandstartthenetwork
devState=DEVJNIT;
〃设备逻辑类型,启动模式,信标时间,超帧长度,接着转到去启动设备,
转到ZDO.StartDcviccO
Zr)O_StariDcvicc((uini8)Zn()_Config_Nodc_DcscripLor.LogicalTypc,
devStartMode,
DEFAULT_BEACON_()RDER,DEFAULT.SLPERFRAME.ORDER);
//Returnunprocessedevents
return(eventsAZDO.NETOORKJNIT);
}
if(ZSTACK_R()UTER_BUILD)
{
if(events&ZD()_NETWORK_START)
ZDApp_Nc^orkStartEvtOi
//Returnunprocessedeventsreturn(events八ZD()_NETW()RK_START);
}
if(events&ZDO_ROUTER_START)
{
if(nwkStatus==ZSucecss)
{
if(devStaw==DEV_END_DEVICE)
d^Statc=DEV.ROC'TER;
osal_pwrmgr_dcvicc(PWUMGR.ALWAYS.ON);
}
else
{
//remainasenddevice!
!
}
osaLsct_cvcnt(ZDAppTaskID,ZIX)_STATE_CHANGE_EVT);
return(events八ZD()_R()UTER_START);
Zr)O_UpdatcN\vkStaius(devState);
//Atstartup,dooneMTOroutediscoveryifthedeviceisaconcentratorif(zgConccntratorEnablc==TRUE)
//Startnextevent
osaLstart_timcrEx(NWK.TaskIP,NWK_\IT()_RTG_REQ_EVT,100);
//Returnunprocessedeventsreturn(events八ZD()_STATE_CHANGE_EVT);
if(events&ZP()_C()MMAND_CNF)
//Userdefinedlogic
if(events&ZD()_NWK_UPDATE_NV)
{
Zr)App_SavcNctworkStatcEvtQ;
//Returnunprocessedevents
return(events八ZD()_NVCK_UPDATE_NV);
}
if(events&ZDO_DEVICE_RESET)
{
//ThedevicehasbeenintheUNAUTHstate,soreset
//Note:
therewillbenoreturnfromthiscall
SystemReSetQ;
}
if(ZG_SECURE_ENABLED)
rcitirn(Zf)App_ProccssSccEvcnt(task_id,events));
else
//Discardormakemorehandlersreturn0;
1.7开启网络
ZDObjcci.c
C++CodevoidZD()_StartDcvicc(bytelogicalTypc,dc\rStartModcs_tstartModc,bytebcacon()rdcr,bytesupcrframcOrdcr)
{
ZStatus_tret;
#ifdefined(ZIGBEE_FREQ_AGIL1TY)
staticuint8diseRctries=0;
#cndif
#ifdefined(ZIGBEE.COMMISSIONING)
staticuint8scanCnt=0;
#endif
ret=ZUnsupportedMode;if(ZG_B(JILD_CO()RD1NAT()R_TYPE&&logicalTypc二二
NODETYPE_CO()RDINAT()R)〃当设备作为协调器时,执行这个条件语句。
{
if(startModc==MODE_HARD)
{
dcvStaic=DEV_COORD_STARTING;
〃向网络层发送网络形成请求。
当网络层执行
NLME-NciworkFormationRcqucst()逹立网络后,将给予ZDO层反馈信息。
//接着转去执行ZDApp层的ZD()_NctworkFormationConfirmCB()函数
ret=NLME_NctworkFormationRcqucst(zgConfigPANin,
zgApsUscExtcndcdPANID,zgDcfaultChanndList,
zgOcfauItStartingScaiiDuration,bcacon()rdcr,
supcrframcOrdcr,false);
}
elseif(startModc==MODE.RESUME)
{
//JuststartthecoordinatordevSute二PEV_C()ORP_START!
NG;ret二NLNfE_StartR()utcrRequcsr(bcaconOrdcr,bcacon()rdcr,false);
else
{
#ifdcfincd(LCD.SUPPORTEP)
HalLcdVCVitcScrccn("StariPcvnccERR","MOPEunknown11);
#cndif
}
}
if(ZG_BUILP」()IMNG_TYPE&&(logicalTypc==N()DETYPE_R()UTER||logicalTypc二二N()DETYPE_DEVICE))〃当设备作为节点时,执行迂个条件语句。
{
if((siariModc二二MOPEJOIN)||(startModc二二MODE.REJOIN))
{
dcvStaic二DEV_NVCK_D1SC;
#ifdcfincd(MANAGEP.SCAN)
ZD()ManagpdScan_Ncxt();
ret=NLME_NciworkDiscover\Requcst(managedScanChanndMask,
BEACON_ORDER_15_MSEC);
#clsc
ret二NLME_NctworkDiscoveryRequcst(zgDcfaultChanndList,zgOcfaultStarringScaiiDuration);
#ifdefined(ZIGBEE_FREQ_AGIL1TY)
if(!
(Zr)O_Config_Nodc_r)cscriptor.Capabilit\'Flags&
CAPINFO_RCVR_ONJOLE)&&
(ret二二ZSucccss)&&(++discRcirics==4))
{
//FordeviceswithRxOnWhciiIdlcequalstoFALSE,anyReworkchannel
//changewillnotberecited・()nthesedevicesorroutersthathave
//lostthenetwork,anactivescanshallbeconductedontheDefault
//ChannellistusingtheextendedPANIDtofindtheRework.Ifthe
//extendedPANIDisrftfoundusingtheDefaultChannellist,anscan
//shouldbecompletedusingallchannels.
zgDcfaultChaiinclList=MAX_CHANN