自動啟動模式分析_第1頁
自動啟動模式分析_第2頁
自動啟動模式分析_第3頁
自動啟動模式分析_第4頁
自動啟動模式分析_第5頁
已閱讀5頁,還剩7頁未讀 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

本文格式為Word版,下載可任意編輯——自動啟動模式分析自動啟動模式分析以SampleApp例程協(xié)調器為例(2023-12-2313:38)分類:ZigBee技術學習

在上一篇文章中,分析了一下定義了HOLD_AUTO_START編譯選項后,程序的流程,這里分析一下在沒有定義這個編譯選項后,程序的啟動流程,也就是自動啟動模式的流程。SampleApp例程為例。在ZDApp.c文件中,可以看到下面的定義:#ifdefined(HOLD_AUTO_START)

devStates_tdevState=DEV_HOLD;//初始化-不會自動啟動#else

devStates_tdevState=DEV_INIT;//初始化-沒有連接到任何東西#endif

不管什么樣的啟動方式,都會在ZDApp_Init()函數(shù)中得到體顯,下面是這個函數(shù)的源代碼。由于這個函數(shù)是必需要被執(zhí)行到。也就是在用戶的初始化函數(shù)之前被初始化。

voidZDApp_Init(bytetask_id){

uint8capabilities;//SavethetaskID

ZDAppTaskID=task_id;

//InitializetheZDOglobaldeviceshortaddressstorageZDAppNwkAddr.addrMode=Addr16Bit;

ZDAppNwkAddr.addr.shortAddr=INVALID_NODE_ADDR;

(void)NLME_GetExtAddr();//LoadthesaveExtAddrpointer.加載IEEE地址//Checkformanual\

//開啟電源時,檢測到有手工設置SW_1則會設置devState=DEV_HOLD,從而不進行網(wǎng)絡初始化

ZDAppCheckForHoldKey();

//InitializeZDOitemsandsetupthedevice-typeofdevicetocreate.

ZDO_Init();//初始化ZDO條目,并設置設備的啟動方式是協(xié)調器,還是別的//RegistertheendpointdescriptionwiththeAF

//Thistaskdoesn'thaveaSimpledescription,butwestillneed//toregistertheendpoint.

afRegister((endPointDesc_t*)#ifdefined(ZDO_USERDESC_RESPONSE)ZDApp_InitUserDesc();

#endif//ZDO_USERDESC_RESPONSE

//setbroadcastaddressmasktosupportbroadcastfilteringNLME_GetRequest(nwkCapabilityInfo,0,NLME_SetBroadcastFilter(capabilities);

//Startthedevice?是否啟動設備?假使devState不是DEV_HOLD時,則啟動設備,在上面的代碼分析中,也可以看到,假使定義了HOLD_AUTO_START宏,則devState等于DEV_HOLD,不會啟動設備。假使按下了SW_1鍵devState也

等于DEV_HOLD,也不會啟動網(wǎng)絡。也就是說有兩種方式可以設置非自動啟動模式,一種是通過按鍵,一種通過宏定義if(devState!=DEV_HOLD){

ZDOInitDevice(0);//在本例程中沒有定義HOLD_AUTO_START所以這個會成功執(zhí)行}else{

//假使定義了HOLD_AUTO_START,則等待延時或外部事件啟動網(wǎng)絡,并且LED4燈,也就是藍色的燈閃爍

//BlinkLEDtoindicateHOLD_STARTHalLedBlink(HAL_LED_4,0,50,500);}

ZDApp_RegisterCBs();}/*ZDO_Init()*/

其中ZDOInitDevice()函數(shù)是最重要的,也是設備的初始化。下面是ZDOInitDevice()函數(shù)的源代碼。

uint8ZDOInitDevice(uint16startDelay){

//初始化設備網(wǎng)絡狀態(tài)為ZDO_INITDEV_NEW_NETWORK_STATE:新的網(wǎng)絡狀態(tài).可能意味著ZCD_NV_STARTUP_OPTION不能恢復,或沒有任何網(wǎng)絡狀態(tài)恢復uint8networkStateNV=ZDO_INITDEV_NEW_NETWORK_STATE;uint16extendedDelay=0;

devState=DEV_INIT;//RemovetheHoldstate重新設置設備狀態(tài)//Initializeleavecontrollogic

//函數(shù)讀取NV項目ZCD_NV_LEAVE_CTRL的值,ZDApp_LeaveCtrl指向這個值ZDApp_LeaveCtrlInit();

//Checkleavecontrolresetsettings

//設備的斷開會造成DEV_HOLD狀態(tài),這里面設置的.ZDApp_LeaveCtrlStartup(//Leavemaymaketheholdstatecomeback

//以上兩個函數(shù)設置了對設備離開時的控制,假使有延時則延時,沒有則//把設備狀態(tài)設為DEV_HOLD

//ZDO_INITDEV_LEAVE_NOT_STARTED:該設備沒有在網(wǎng)絡中,下次調用才啟用.if(devState==DEV_HOLD)

return(ZDO_INITDEV_LEAVE_NOT_STARTED);//Don'tjoin-(onetime).#ifdefined(NV_RESTORE)

//GetKeypaddirectlytoseeifaresetnvisneeded.

//HolddowntheSW_BYPASS_NVkey(definedinOnBoard.h)//whilebootingtoskippastNVRestore.if(HalKeyRead()==SW_BYPASS_NV)

//SW_BYPASS_NV按鍵處于按下狀態(tài)時,則避開網(wǎng)絡層的NV存儲

networkStateNV=ZDO_INITDEV_NEW_NETWORK_STATE;//設備網(wǎng)絡狀態(tài)為新的網(wǎng)絡狀態(tài)else{

//DetermineifNVshouldberestored

//函數(shù)返回的設備網(wǎng)絡狀態(tài)要么是新的網(wǎng)絡狀態(tài);要么是恢復的網(wǎng)絡狀態(tài);以此//來確定要不要讀取NV里相應條目來恢復網(wǎng)絡從前狀態(tài)networkStateNV=ZDApp_ReadNetworkRestoreState();}

//假使設備的網(wǎng)絡狀態(tài)為恢復的網(wǎng)絡狀態(tài)

if(networkStateNV==ZDO_INITDEV_RESTORED_NETWORK_STATE){

networkStateNV=ZDApp_RestoreNetworkState();}else{

//WipeoutthenetworkstateinNV//恢復設備從前的網(wǎng)絡狀態(tài)參數(shù)

//設置devStartMode=MODE_RESUMENLME_InitNV();

NLME_SetDefaultNV();}

#endif

//假使設備的網(wǎng)絡狀態(tài)為新的網(wǎng)絡狀態(tài),

if(networkStateNV==ZDO_INITDEV_NEW_NETWORK_STATE){

//根據(jù)預編譯來設置設備新的網(wǎng)絡狀態(tài)參數(shù)ZDAppDetermineDeviceType();

//Onlydelayifjoiningnetwork-notrestoringnetworkstate

extendedDelay=(uint16)((NWK_START_DELAY+startDelay)+(osal_rand()}

//Initializedevicesecurity

ZDApp_SecInit(networkStateNV);//Triggerthenetworkstart

ZDApp_NetworkInit(extendedDelay);return(networkStateNV);}

在這里又分了兩種狀況,一種是定義了編譯選項NV_RESTORE,另一種就是沒有定義該編譯選項。

下面首先看一下沒有定義該選項的狀況:(1)NV_RESTORE編譯選項定義首先,判斷按鍵HAL_KEY_SW_5是否按下,假使HAL_KEY_SW_5按鍵按下,則設置networkStateNV=ZDO_INITDEV_NEW_NETWORK_STATE;假使沒有

按下,通過調用ZDApp_ReadNetworkRestoreState()函數(shù)設置networkStateNV的值,通過讀取ZCD_NV_STARTUP_OPTION項的值,來決定networkStateNV選項的值。假使這個函數(shù)的返回值為

ZDO_INITDEV_RESTORED_NETWORK_STATE。則調用ZDApp_RestoreNetworkState();函數(shù),該函數(shù)的源代碼如下:uint8ZDApp_RestoreNetworkState(void){

bytenvStat;

#if(SECURE!=0)

nwkActiveKeyItemskeyItems;#endif

//InitializeNWKNVitemsnvStat=NLME_InitNV();

//假使設備的狀態(tài)為恢復的網(wǎng)絡狀態(tài),即

ZDO_INITDEV_RESTORED_NETWORK_STATE狀態(tài),則進行這個函數(shù)進行恢復。假使短地址為0x0000則為協(xié)調器結點,然后設備規(guī)律設備的類型為

NODETYPE_COORDINATOR,并設置devStartMode=MODE_RESUME;說明設備為恢復狀態(tài)。

if(nvStat!=NV_OPER_FAILED){

if(NLME_RestoreFromNV()){

//Areweacoordinator

ZDAppNwkAddr.addr.shortAddr=NLME_GetShortAddr();if(ZDAppNwkAddr.addr.shortAddr==0){

ZDO_Config_Node_Descriptor.LogicalType=NODETYPE_COORDINATOR;}

devStartMode=MODE_RESUME;}else

nvStat=NV_ITEM_UNINIT;#if(SECURE!=0)

nwkFrameCounterChanges=0;

osal_memset(

osal_nv_item_init(ZCD_NV_NWKKEY,sizeof(nwkActiveKeyItems),(void*)

#ifdefined(ZDO_COORDINATOR)ZDApp_RestoreNwkKey();

#endif//ZDO_COORDINATOR#endif//SECURE

//ThedefaultforRxOnWhenIdleistrueforRTR_NWKandfalseforenddevices//[setupintheNLME_RestoreFromNV()].Changeithereifyouwantsomething//otherthandefault.

}

if(nvStat==ZSUCCESS)

return(ZDO_INITDEV_RESTORED_NETWORK_STATE);else

return(ZDO_INITDEV_NEW_NETWORK_STATE);}

//假使networkStateNV=ZDO_INITDEV_NEW_NETWORK_STATE,則會調用下面的函數(shù)

voidZDAppDetermineDeviceType(void){

if(zgDeviceLogicalType==ZG_DEVICETYPE_ENDDEVICE)return;

#ifdefined(SOFT_START)

if(zgDeviceLogicalType==ZG_DEVICETYPE_COORDINATOR){

devStartMode=MODE_HARD;//Startasacoordinator

ZDO_Config_Node_Descriptor.LogicalType=NODETYPE_COORDINATOR;}else{

if(zgDeviceLogicalType==ZG_DEVICETYPE_ROUTER){

softStartAllowCoord=FALSE;//Don'tallowcoordtostart假使是路由器則不充許作為協(xié)調器啟動

continueJoining=TRUE;}

devStartMode=MODE_JOIN;//Assumejoining}

#endif//SOFT_START}

可以看到,假使編譯等式SOFT_START也有定義的話,設備的類型為協(xié)調器,則會設置devStartMode=MODE_HARD;也就是說設備為開始狀態(tài)。假使是不是協(xié)調器而是路由器的話,devStartMode=MODE_JOIN;設備為重新參與的狀態(tài)。在ZDOInitDevice()函數(shù)的最終,通過調用ZDApp_NetworkInit(extendedDelay);進行網(wǎng)絡的初始化操作。

(2)voidZDApp_NetworkInit(uint16delay){

if(delay){

//Waitawhilebeforestartingthedevice

osal_start_timerEx(ZDAppTaskID,ZDO_NETWORK_INIT,delay);}else{

{

msgPtr=(osal_event_hdr_t*)osal_msg_allocate(bufLen);if(msgPtr){

msgPtr->event=ZDO_STATE_CHANGE;//CommandIDmsgPtr->status=(byte)state;

osal_msg_send(*(epDesc->epDesc->task_id),(byte*)msgPtr);}}

epDesc=epDesc->nextDesc;}}

在這個函數(shù)中設置了事件ZDO_STATE_CHANGE也就是狀態(tài)變化事件,這樣整個的流程就到了用戶的事件處理函數(shù)中,在好多的例子中我們都可以看到這個事件的處理,也是網(wǎng)絡建立成功后,或者參與網(wǎng)絡成功后,首先要做的事件處理過程。

2.假使協(xié)調器沒有預編譯NV_RESTORE,networkStateNV

==ZDO_INITDEV_NEW_NETWORK_STATE,但由于協(xié)調器編譯了ZDO_COORDINATOR而沒有編譯SOFT_START,因此ZDAppDetermineDeviceType()不起作用.因此

ZDO_Config_Node_Descriptor.LogicalType和devStartMode這兩個關鍵參數(shù)保持初始化時的值:

ZDO_Config_Node_Descriptor.LogicalType=NODETYPE_COORDINATOR,devStartMode=MODE_HARD。

uint8ZDOInitDevice(uint16startDelay){

uint8networkStateNV=ZDO_INITDEV_NEW_NETWORK_STATE;uint16extendedDelay=0;

devState=DEV_INIT;//RemovetheHoldstate//InitializeleavecontrollogicZDApp_LeaveCtrlInit();

//Checkleavecontrolresetsettings

ZDApp_LeaveCtrlStartup(//Leavemaymaketheholdstatecomebackif(devState==DEV_HOLD)

return(ZDO_INITDEV_LEAVE_NOT_STARTED);//Don'tjoin-(onetime).#ifdefined(NV_RESTORE)

//GetKeypaddirectlytoseeifaresetnvisneeded.

//HolddowntheSW_BYPASS_NVkey(definedinOnBoard.h)//whilebootingtoskippastNVRestore.i

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論