ZigBee合同栈初始化网络启动流程ZigBee基本流程:由协调器组网(创立PANID),终端设备和路由设备发现网络以及加入网络。基本流程:main()-osal_init_system()-osalInitTasks()-ZDApp_Init(),进合同栈初始化函数ZDApp_Init()。1.1进入程序入口main()。ZMain.c中C++Codeintmain(void){//Turnoffinterruptsosal_int_disable(INTS_ALL);//InitializationforboardrelatedstuffsuchasLEDsHAL_BOARD_INIT();//Makesuresupplyvoltageishighenoughtorunzmain_vdd_check();//InitializeboardI/OInitBoard(OB_COLD);//InitialzeHALdriversHalDriverInit();//InitializeNVSystemosal_nv_init(NULL);//InitializetheMACZMacInit();//Determinetheextendedaddresszmain_ext_addr();//InitializebasicNVitemszgInit();#ifndefNONWK//SincetheAFisn'tatask,callit'sinitializationroutineafInit();#endif//Initializetheoperatingsystemosal_init_system();//Allowinterruptsosal_int_enable(INTS_ALL);//FinalboardinitializationInitBoard(OB_READY);//Displayinformationaboutthisdevicezmain_dev_info();/*DisplaythedeviceinfoontheLCD*/#ifdefLCD_SUPPORTEDzmain_lcd_init();#endif#ifdefWDT_IN_PM1/*IfWDTisused,thisisagoodplacetoenableit.*/WatchDogEnable(WDTIMX);#endifosal_start_system();//NoReturnfromherereturn0;//Shouldn'tgethere.}//main()1.2给任务添加IDsapi.c中C++CodevoidosalInitTasks(void)//为各自进程添加ID用于任务查找{uint8taskID=0;tasksEvents=(uint16*)osal_mem_alloc(sizeof(uint16)*tasksCnt);osal_memset(tasksEvents,0,(sizeof(uint16)*tasksCnt));macTaskInit(taskID++);nwk_init(taskID++);Hal_Init(taskID++);//硬件抽象层初始化#ifdefined(MT_TASK)MT_TaskInit(taskID++);#endifAPS_Init(taskID++);ZDApp_Init(taskID++);//判断如果协调器节点建立网络、如果终端节点加入网络SAPI_Init(taskID);}1.3初始化ZigBee合同栈网络ZDApp.cC++CodevoidZDApp_Init(uint8task_id){//SavethetaskIDZDAppTaskID=task_id;//InitializetheZDOglobaldeviceshortaddressstorageZDAppNwkAddr.addrMode=Addr16Bit;ZDAppNwkAddr.addr.shortAddr=INVALID_NODE_ADDR;(void)NLME_GetExtAddr();//LoadthesaveExtAddrpointer.//CheckformanualHoldAutoStart//检测到有手工设立HAL_KEY_SW_1则会设立devState=DEV_HOLD,从而避开网络初始化ZDAppCheckForHoldKey();//InitializeZDOitemsandsetupthedevice-typeofdevicetocreate.ZDO_Init();//通过判断预编译来启动某些函数功能//RegistertheendpointdescriptionwiththeAF//Thistaskdoesn'thaveaSimpledescription,butwestillneed//toregistertheendpoint.afRegister((endPointDesc_t*)&ZDApp_epDesc);#ifdefined(ZDO_USERDESC_RESPONSE)ZDApp_InitUserDesc();#endif//ZDO_USERDESC_RESPONSE//Startthedevice?if(devState!=DEV_HOLD){ZDOInitDevice(0);}else{//BlinkLEDtoindicateHOLD_STARTHalLedBlink(HAL_LED_4,0,50,500);}ZDApp_RegisterCBs();}/*ZDApp_Init()*/如果设立devState为DEV_HOLD,则不会执行ZDOInitDevice;反之,系统会调用此函数是设备组网或者入网。看下这个函数完毕功能是什么样子。ZDOInitDevice是设备在网络中启动。它会读取NV中ZCD_NV_STARTUP_OPTION选项决定与否恢复网络状态。如果应用层强制进行新join操作,它应当在调用这个函数之前设立ZCD_NV_STARTUP_OPTION中ZCD_STARTOPT_DEFAULT_NETWORK_STATE位。可以调用zgWrieStartupOptions()函数完毕这些设立。1.4初始化设备(启动网络和设立网络类型)ZDApp.cC++Codeuint8ZDOInitDevice(uint16startDelay){uint8networkStateNV=ZDO_INITDEV_NEW_NETWORK_STATE;uint16extendedDelay=0;if(devState==DEV_HOLD){//InitializetheRAMitemstable,incaseanNVitemhasbeenupdated.zgInitItems(FALSE);}ZDConfig_InitDescriptors();//devtag.071807.todo-fixthistemporarysolution_NIB.CapabilityInfo=ZDO_Config_Node_Descriptor.CapabilityFlags;devState=DEV_INIT;//RemovetheHoldstate//函数读取NV项目ZCD_NV_LEAVE_CTRL值,ZDApp_LeaveCtrl指向这个值//InitializeleavecontrollogicZDApp_LeaveCtrlInit();//Checkleavecontrolresetsettings//设备断开会导致DEV_HOLD状态ZDApp_LeaveCtrlStartup(&devState,&startDelay);//Leavemaymaketheholdstatecomebackif(devState==DEV_HOLD){//设立启动选项//SettheNVstartupoptiontoforceanewjoin.zgWriteStartupOptions(ZG_STARTUP_SET,ZCD_STARTOPT_DEFAULT_NETWORK_STATE);//告知应用层触发事件//Notifytheapplicationsosal_set_event(ZDAppTaskID,ZDO_STATE_CHANGE_EVT);return(ZDO_INITDEV_LEAVE_NOT_STARTED);//Don'tjoin-(onetime).}#ifdefined(NV_RESTORE)//GetKeypaddirectlytoseeifaresetnvisneeded.//HolddowntheSW_BYPASS_NVkey(definedinOnBoard.h)//whilebootingtoskippastNVRestore.if(HalKeyRead()==SW_BYPASS_NV)networkStateNV=ZDO_INITDEV_NEW_NETWORK_STATE;else{//通过读取ZCD_NV_STARTUP_OPTION选项决定与否进行网络恢复//DetermineifNVshouldberestorednetworkStateNV=ZDApp_ReadNetworkRestoreState();}if(networkStateNV==ZDO_INITDEV_RESTORED_NETWORK_STATE){networkStateNV=ZDApp_RestoreNetworkState();}else{//WipeoutthenetworkstateinNVNLME_InitNV();NLME_SetDefaultNV();}#endifif(networkStateNV==ZDO_INITDEV_NEW_NETWORK_STATE)//如果是要启动新网络{ZDAppDetermineDeviceType();//依照选项设立设备网络类型,默认路由类型//Onlydelayifjoiningnetwork-notrestoringnetworkstateextendedDelay=(uint16)((NWK_START_DELAY+startDelay)+(osal_rand()&EXTENDED_JOINING_RANDOM_MASK));}//InitializethesecurityfortypeofdeviceZDApp_SecInit(networkStateNV);//触发启动网络//TriggerthenetworkstartZDApp_NetworkInit(extendedDelay);//setbroadcastaddressmasktosupportbroadcastfiltering用于解决合法广播地址NLME_SetBroadcastFilter(ZDO_Config_Node_Descriptor.CapabilityFlags);return(networkStateNV);}这个函数注意功能:初始化设备配备,ZDAppDetermineDeviceType()设立网络类型(协调、路由、终端),ZDApp_NetworkInit(extendedDelay)初始化网络并启动或加入网络。1.5定期启动网络ZDApp.c进入ZDApp_NetworkInit()函数,等待一段时间在执行ZDO_NETWORK_INIT,跳入事件解决ZDApp层ZDAPP_EVENT_LOOP()函数启动网络。C++CodevoidZDApp_NetworkInit(uint16delay){if(delay){//Waitawhilebeforestartingthedeviceosal_start_timerEx(ZDAppTaskID,ZDO_NETWORK_INIT,delay);//发送ZDO_NETWORK_INIT(网络初