




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
精簡OS實驗一、操作系統(tǒng)(OS)基本術語二、操作系統(tǒng)表象層(OSAL)運行機理三、OSAL消息隊列標題四、代碼分析一、操作系統(tǒng)(OS)基本術語1)資源(Resource)任何任務所占用的實體都可以稱為資源,如一個變量、數(shù)組、結構體等。2)共享資源(SharedResource)至少可以被兩個任務使用的資源稱為共享資源,為了防止共享資源被破壞,每個任務在操作共享資源時,必須保證是獨占該資源。保護共享資源常用的方法有A.關中斷(ZIGBEE協(xié)議棧最常用)B.使用測試并置位指令(T&S指令)C.禁止任務切換D.使用信號量3一、操作系統(tǒng)(OS)基本術語3)任務(Task)一個任務,又稱作一個線程,是一個簡單的程序的執(zhí)行過程,在任務執(zhí)行過程中,可以認為PU完全屬于該任務。在任務設計時,需要將問題盡可能地分為多個任務,每個任務獨立完成某種功能,同時被賦予一定的優(yōu)先級,擁有自己的CPU寄存器和堆棧空間。一般將任務設計為一個無限循環(huán)。4)多任務運行(Muti-taskRunning)
實際上只有一個任務在運行,但是CPU可以使用任務調度策略將多個任務進行調度,每個任務執(zhí)行特定的時間,時間片到了后,就進行任務切換。5)內核(Kernel)在多任務系統(tǒng)中,內核負責管理各個任務,主要包括:為每個任務分配CPU時間;任務調度;負責任務間的通信。4一、操作系統(tǒng)(OS)基本術語6)互斥(MutualExclusion)多任務間通信最簡單,常用的方法是使用共享數(shù)據(jù)結構。對于單片機系統(tǒng),所有任務都在單一的地址空間下,使用共享的數(shù)據(jù)結構包括全局變量、指針、緩沖區(qū)等。雖然共享數(shù)據(jù)結構的方法簡單,但是必須保證對共享數(shù)據(jù)結構的寫操作具有唯一性,以避免晶振和數(shù)據(jù)不同步。
7)消息隊列(MessageQueue)消息隊列用于任務間傳遞消息,通常包含任務間同步的信息。通過內核提供的服務、任務或中斷服務程序將一條消息放入信息隊列,然后,其他任務可以使用內核提供的服務從消息隊列中獲取屬于自己的消息。為了降低傳遞消息的開支,通常傳遞指向消息的指針。5OSAL主要功能任務注冊、初始化和啟動任務間的同步、互斥中斷處理存儲器分配和管理6OSAL就是一種支持多任務運行的系統(tǒng)資源分配機制二、OSAL運行機理
二、OSAL運行機理
如前面的圖中從宏觀上表現(xiàn)了ZigBee協(xié)議的結構。但并沒有OSAL的蹤跡。ZigBee協(xié)議棧與ZigBee協(xié)議之間并不能完全劃等號。ZigBee協(xié)議棧僅僅是ZigBee協(xié)議的具體實現(xiàn),因此,存在于ZigBee協(xié)議棧中使用的OSAL并沒有出現(xiàn)在ZigBee協(xié)議中。在ZigBee協(xié)議中可以找到使用OSAL的某些“根源”。在基于ZigBee協(xié)議棧的應用程序開發(fā)過程中,用戶只需要實現(xiàn)應用層的程序開發(fā)即可。從前面的圖可以看出應用程序框架中包含了最多240個應用程序對象,每個應用程序對象運行在不同的端口上,因此,端口的作用是用來區(qū)分不同的應用程序對象。可以把一個應用程序對象看做為一個任務,因此,需要一個機制來實現(xiàn)任務的切換、同步與互斥,這就是OSAL產(chǎn)生的根源。
因此,從上面的分析可以得出下面的結論:
OSAL就是一種支持多任務運行的系統(tǒng)資源分配機制。OSAL與標準的操作系統(tǒng)還是一定區(qū)別的,OSAL實現(xiàn)了類似操作系統(tǒng)的某些功能,例如:任務切換、提供了內存管理功能等,但OSAL并不能稱之為真正意義上的操作系統(tǒng)。在左側工作空間窗口打開App文件夾,可以看到三個文件,分別是“Coordinator.c”、“Coordinator.h”、“OSAL_GenericApp.c”。整個程序所實現(xiàn)的功能都包含在這三個文件當中。二、OSAL運行機理
首先打開Coordinator.c文件,可以看到兩個比較重要的函數(shù)GenericApp_Init和GenericApp_ProcessEvent。GenericApp_Init是任務的初始化函數(shù),GenericApp_ProcessEvent則負責處理傳遞給此任務的事件。GenericApp_ProcessEvent函數(shù)的主要功能是判斷由參數(shù)傳遞的事件類型,然后執(zhí)行相應的事件處理函數(shù)。因此,在ZigBee協(xié)議棧中,OSAL負責調度各個任務的運行,如果有事件發(fā)生了,則會調用相應的事件處理函數(shù)進行處理,OSAL的工作原理示意圖如圖所示。
二、OSAL運行機理
二、OSAL運行機理
通過不斷地查詢時間表來判斷是否有事件的發(fā)生,如果有事件發(fā)生,則查找函數(shù)表找到對應的事件處理函數(shù)對事件進行處理,事件表使用數(shù)組實現(xiàn),數(shù)組的每一項對應一個任務事件,每一位表一個事件;函數(shù)表使用函數(shù)指針數(shù)組來指向事件處理函數(shù)。二、OSAL運行機理---事件和任務的事件處理函數(shù)建立聯(lián)系的方法左圖給出了事件和任務的事件處理函數(shù)建立聯(lián)系的流程。具體方法是:建立一個事件表,保存各個任務的對應事件,建立另一個函數(shù)表,保存各個任務事件處理函數(shù)的地址,然后將這兩張表建立某種對應關系,當某一事件發(fā)生時則查找函數(shù)表找到對應的事件處理函數(shù)即可。二、OSAL運行機理---三個重要變量taskCnt——該變量保存了任務的總個數(shù),該變量的聲明為:unit8tasksCnt,其中unit8的定義為:typedefunsignedcharuint8。taskEvents——這是一個指針,指向事件表首地址的指針,該變量的聲明為:uint16*tasksEvents,其中unit16的定義為:typedefunsignedshortuint16。taskArr——這是一個數(shù)組,該數(shù)組的每一項事件處理函數(shù)數(shù)組,每一項都是一個函數(shù)指針,指向了事件處理函數(shù)。該數(shù)組的聲明為:pTaskEventHandlerFntaskArr[]其中pTaskEventHandlerFn的定義(需要特別注意)如下:Typedefunsignedshort(*pTaskEventHandlerFn)(unsignedchartask_id,unsignedshortevent)這是定義了一個函數(shù)指針。因此,tasksArr數(shù)組的每一項都是一個函數(shù)指針,指向了事件處理函數(shù)。二、OSAL運行機理---OSAL的程序實現(xiàn)流程這里我們總結一下OSAL的工作原理:通過taskEvents指針訪問事件表的每一項,如果有事件發(fā)生,則查找函數(shù)表找到事件處理函數(shù)進行處理,處理完畢后,繼續(xù)訪問事件表,查看是否有事件發(fā)生,無限循環(huán)。三、代碼分析---Z-Stack的main函數(shù)Z-Stack的main函數(shù)在Zmain.c中,總體上來說,它一共做了兩件工作:①系統(tǒng)初始化,即有啟動代碼來初始化硬件系統(tǒng)和軟件架構需要的各個模塊;②開中斷執(zhí)行操作系統(tǒng)實體。三、代碼分析---Z-Stack協(xié)議棧OSAL初始化流程簡析Z-Stack軟件層次
整個Z-Stack的主要工作流程,大致分為系統(tǒng)啟動,驅動初始化,OSAL初始化和啟動,進入任務輪循幾個階段。三、代碼分析---Z-Stack軟件啟動流程
系統(tǒng)上電后,通過執(zhí)行Zmain文件夾中ZMain.c的主函數(shù)開始系統(tǒng)初始化。當順利完成上述初始化時,執(zhí)行osal_start_system()函數(shù)開始運行OSAL系統(tǒng)。三、代碼分析---OSAL輪詢操作系統(tǒng)
OSAL(OperatingSystemAbstractionLayer)操作系統(tǒng)抽象層定義了其它模塊中的事件的處理機制。它將每一模塊內的所有事件放在一個任務中進行處理,任務間的通信通過傳遞系統(tǒng)消息來完成,這使得協(xié)議棧中的事件處理更類似于一個操作系統(tǒng);同時它還定義了堆內存管理、NV(non-volatile,非可變)存儲系統(tǒng)的管理、電源管理、時鐘管理等。三、代碼分析---OSAL的任務調度OSAL是協(xié)議棧的核心,Z-Stack的任何一個子系統(tǒng)都作為OSAL的一個任務。任務調度函數(shù)按照優(yōu)先級檢測各個任務是否就緒。如果存在就緒的任務則調用tasksArr[]中相對應的任務處理函數(shù)去處理該事件,直到執(zhí)行完所有就緒的任務。如果任務列表中沒有就緒的任務,則可以使處理器進入睡眠狀態(tài)實現(xiàn)低功耗。事件標志位輪詢多級任務調度機制圖1-2OSAL事件輪詢機制2025/3/3019/24OSAL的操作系統(tǒng)輪詢和調度機制示意圖三、代碼分析---OSAL的任務任何OSAL任務必須分為兩步:1.任務初始化分配任務內存空間,和指定唯一的標識號。2.處理任務事件處理任務事件通過創(chuàng)建“ApplicationName”_ProcessEvent()函數(shù)處理。三、代碼分析---OSAL中的任務初始化OSAL中有些任務是協(xié)議棧運行所必須的,因此在工程中都要加入到任務數(shù)組中去(默認)。三、代碼分析---OSAL中的任務事件處理OSAL中的任務事件處理函數(shù)統(tǒng)一放到一個函數(shù)指針數(shù)組中。三、代碼分析---OSAL消息隊列事件和消息的區(qū)別
事件:是驅動任務區(qū)執(zhí)行某些操作的條件,當系統(tǒng)中產(chǎn)生一個事件,OSAL將這個時間傳遞給相應的任務后,任務才能執(zhí)行一個相應的操作(調用時間處理函數(shù)去處理)
消息:事件和數(shù)據(jù)的封裝就成了一個消息。(事件的發(fā)生有伴隨這附加信息的產(chǎn)生,如天線接收到數(shù)據(jù)后,產(chǎn)生AF_INCOMING_MSG_CMD消息,但任務的時間處理這個事件時,還需要得到接收到的數(shù)據(jù))。然后,將消息發(fā)送到消息隊列中,在事件處理函數(shù)中就可以使用osal_msg_receive,從消息隊列中得到該消息。
MSGpkt=(afIncomingMSGPacket_t*)osal_msg_receive(GenericApp_TaskID);OSAL維護了一個消息隊列,每一個消息都會被放到這個消息隊列中去,當任務接收到事件后,可以從消息隊列中獲取屬于自己的消息,然后調用消息處理函數(shù)進行相應的處理即可。OSAL中消息隊列如圖所示。三、代碼分析---OSAL消息隊列三、代碼分析---OSAL任務中的事件與消息三、代碼分析---OSAL任務中的事件與消息?事件(EVENT)類型為uint16,位域表述,其形式為:SYS_EVENT_XXX一個OSAL任務最多定義除系統(tǒng)強制事件外的15個事件。事件中通常待用用于通訊的消息。消息(MSG)由uint8的ID標識,可有256個。三、代碼分析---OSAL任務中的事件與消息SYS_EVENT_MSG(0x8000)是強制事件。該事件主要用來發(fā)送全局的系統(tǒng)消息,包括以下信息:AF_INCOMING_MSG_CMD:用來指示接收到的AF信息。
KEY_CHANGE:用來確認按鍵動作。
ZDO_NEW_DSTADDR:用來指示自動匹配請求。
ZDO_STATE_CHANGE:用來指示網(wǎng)絡狀態(tài)的變化。通常我們都是在任務的事件循環(huán)中去處理以上事件和消息。三、代碼分析---網(wǎng)絡層重要APINWK層為更高層提供了如下功能:網(wǎng)絡管理地址管理網(wǎng)絡參數(shù)與功能函數(shù)除了管理功能,NWK還提供了應用程序沒有的數(shù)據(jù)服務。應用程序可以通過AF數(shù)據(jù)接口。AF數(shù)據(jù)接收:afIncomingData()AF數(shù)據(jù)發(fā)送:AF_DataRequest()網(wǎng)絡管理NLME_NetworkFormationRequest()此函數(shù)允許相鄰的更高層請求設備組建一個新網(wǎng)絡。NLME_NetworkDiscoveryRequest()此函數(shù)請求網(wǎng)絡層尋找相鄰路由器。NLME_JoinRequest()此函數(shù)允許相鄰的更高層請求設備將自己加入到一個網(wǎng)絡中。
NLME_ReJoinRequest()使用此函重新加入一個設備已經(jīng)加入過的網(wǎng)絡。三、代碼分析---網(wǎng)絡層重要API地址管理NLME_GetExtAddr()這個函數(shù)將返回指向IEEE設備64地址的指針。NLME_GetShortAddr()這個函數(shù)將返回設備的(16位短)網(wǎng)絡地址。NLME_GetCoordShortAddr()這個函數(shù)將返回設備父節(jié)點的(16位短)網(wǎng)絡地址。NLME_GetCoordExtAddr()這個函數(shù)是將獲得設備的父節(jié)點設備的IEEE(64位)地址。三、代碼分析---網(wǎng)絡層重要APIAF數(shù)據(jù)發(fā)送三、代碼分析---網(wǎng)絡層重要API三、代碼分析---SampleApp自組無線網(wǎng)實例解析SampleApp工程簡介是協(xié)議棧自帶的ZigBee無線網(wǎng)絡自啟動(組網(wǎng))樣例,該實驗實現(xiàn)的功能主要是協(xié)調器自啟動(組網(wǎng)),節(jié)點設備自動入網(wǎng),之后兩者建立無線通訊。無線數(shù)據(jù)觸發(fā)方式:周期定時發(fā)送信息按鍵事件觸發(fā)信息三、代碼分析---SampleApp工程簡介網(wǎng)絡的管理網(wǎng)絡的創(chuàng)建、加入、恢復等管理通過ZDO層來調用下層相關服務(網(wǎng)絡原語)實現(xiàn)。Z-Stack協(xié)議棧中將ZDO層的服務以ZDAPP任務模塊來實現(xiàn)。工程中通過大量的條件編譯實現(xiàn)對啟動流程的控制。三、代碼分析---SampleApp工程簡介三、代碼分析---SampleApp工程簡介三、代碼分析---SampleApp工程簡介三、代碼分析---SampleApp工程簡介終端節(jié)點終端節(jié)點實現(xiàn)自動發(fā)現(xiàn)并加入ZigBee網(wǎng)絡。配置文件$PROJ_DIR$\..\..\..\Tools\CC2430DB\f8wEndev.cfg$PROJ_DIR$\..\..\..\Tools\CC2430DB\f8wConfig.cfg預編譯選項CC2430EB;NWK_AUTO_POLL;ZTOOL_P1;MT_TASK;三、代碼分析---SampleApp工程簡介三、代碼分析---SampleApp工程簡介三、代碼分析---SampleApp工程簡介發(fā)送periodic信息流程Periodic消息是通過系統(tǒng)定時器并定時廣播出去的,因此在SampleApp_ProcessEvent事件處理函數(shù)中有如下定時器代碼三、代碼分析---SampleApp工程簡介發(fā)送周期消息函數(shù)三、代碼分析---SampleApp工程簡介
AF數(shù)據(jù)的通訊:在應用層任務的SampleApp_ProcessEvent事件消息循環(huán)中,根據(jù)事件類型處理端點間的無線數(shù)據(jù)消息(AF_INCOMING_MSG_CMD)。三、代碼分析---OSAL添加新任務
在使用ZigBee協(xié)議棧進行應用程序開發(fā)時,如何在應用程序中添加一個新任務。打開OSAL_GenericApp.c文件。可以找到數(shù)組tasksArr[]和函數(shù)osalInitTasks。tasksArr[]數(shù)組里存放了所有任務的事件處理函數(shù)的地址;osalInitTasks是OSAL的任務初始化函數(shù),所有任務的初始化工作都在這里面完成,并且自動給每個任務分配一個ID。三、代碼分析---基于Z-Stack協(xié)議棧添加用戶
應用層任務的方法如何在應用層添加自己的任務?Z-Stack協(xié)議棧以OSAL貫穿始終,用戶要添加自己的應用,需要以任務的方式實現(xiàn)。協(xié)議棧中已經(jīng)將底層的任務模塊(必要任務)完成,且留有應用層相應的接口。OSAL_XXX.c文件中定義了當前工程的任務與OSAL操作系統(tǒng)的函數(shù)接口。voidosalInitTasks(void);constpTaskEventHandlerFntasksArr[];三、代碼分析---添加應用層任務完成兩個函數(shù):
1.任務初始化函數(shù)usrTask_Init(uint8task_id)主要完成內容有任務ID的設置、網(wǎng)絡狀態(tài)的初始化、端點的AF注冊等。
2.任務事件處理函數(shù)usrTask_ProcessEvent(uint8task_id,uint16events)主要完成的內容有傳遞到應用層任務的事件和消息的處理。主講:張老師ZigBee協(xié)議棧基礎實驗:數(shù)據(jù)傳輸實驗主講:張老師一、實驗原理二、重點代碼解析三、數(shù)據(jù)發(fā)送標題四、數(shù)據(jù)接收一、實驗原理——功能描述
實驗效果:
兩個ZigBee節(jié)點進行點對點通信,ZigBee節(jié)點2發(fā)送“LED”三個字符,ZigBee節(jié)點1收到數(shù)據(jù)后,對接收到的數(shù)據(jù)進行判斷,如果收到的數(shù)據(jù)是“LED”,則使開發(fā)板上的LED燈閃爍。實驗目的:建立對ZigBee協(xié)議以及ZigBee協(xié)議棧的形象、直觀的認識,加深對ZigBee協(xié)議的理解。一、實驗原理——協(xié)調器工作流程在Zigbee無線傳感器網(wǎng)絡中有三種設備類型:協(xié)調器、路由器和終端節(jié)點,設備類型是有Zigbee協(xié)議棧不同的編譯選項來選擇的。協(xié)調器主要負責網(wǎng)絡是組建、維護、控制終端節(jié)點的加入等。路由器主要負責數(shù)據(jù)包的路由選擇,終端節(jié)點負責數(shù)據(jù)的采集,不具備路由功能。協(xié)調器上電后,會按照編譯時給定的參數(shù),選擇合適的信道、合適的網(wǎng)絡號,建立ZigBee無線網(wǎng)絡,這部分內容讀者不需要寫代碼實現(xiàn),ZigBee協(xié)議棧已經(jīng)實現(xiàn)了。協(xié)調器流程圖一、實驗原理——終端節(jié)點工作流程終端節(jié)點上電后,會進行硬件電路的初始化,然后搜索是否有ZigBee無線網(wǎng)絡,如果有ZigBee無線網(wǎng)絡再自動加入(這是最簡單的情況,當然可以控制節(jié)點加入網(wǎng)絡時要符合編譯時確定的網(wǎng)絡號等),然后發(fā)送數(shù)據(jù)到協(xié)調器,最后使LED閃爍。終端節(jié)點流程圖二、重點代碼解析1.在Coordinator.h文件中輸入以下代碼:#ifndefCOORDINATOR_H#defineCOORDINATOR_H#include"ZComDef.h"#defineGENERICAPP_ENDPOINT10//定義終端號#defineGENERICAPP_PROFID0x0F04//定義配置ID#defineGENERICAPP_DEVICEID0x0001//定義設備ID#defineGENERICAPP_DEVICE_VERSION0//定義設備版本#defineGENERICAPP_FLAGS0//定義軟件標志#defineGENERICAPP_MAX_CLUSTERS1//定義簇最大數(shù)目1個#defineGENERICAPP_CLUSTERID1//定義簇1
externvoidGenericApp_Init(bytetask_id);externUINT16GenericApp_ProcessEvent(bytetask_id,UINT16events);#endif二、重點代碼解析2.UINT16GenericApp_ProcessEvent(bytetask_id,UINT16events)三、數(shù)據(jù)發(fā)送在ZigBee協(xié)議棧中進行數(shù)據(jù)發(fā)送可以調用AF_DataRequest函數(shù)實現(xiàn),該函數(shù)會調用協(xié)議棧里面與硬件相關的函數(shù)最終將數(shù)據(jù)通過天線發(fā)送出去,這里面涉及到對射頻模塊的操作,例如:打開發(fā)射機,調整發(fā)射機的發(fā)送功率等內容,這些部分協(xié)議棧已經(jīng)實現(xiàn)了,用戶無需自己寫代碼去實現(xiàn),只需要掌握AF_DataRequest函數(shù)的使用方法即可。AF_DataRequest數(shù)據(jù)發(fā)送函數(shù)中各個參數(shù)的具體含義(1)afStatus_tAF_DataRequest(afAddrType_t*dstAddr,
endPointDesc_t*srcEP,
uint16cID,uint16len,uint8*buf,uint8*transID,
uint8options,uint8radius)AF_DataRequest數(shù)據(jù)發(fā)送函數(shù)中各個參數(shù)的具體含義(2)①afAddrType_t*dstAddr——該參數(shù)包含了目的節(jié)點的網(wǎng)絡地址以及發(fā)送數(shù)據(jù)的格式,如廣播、單播或多播等。②endPointDesc_t*srcEP——在ZigBee無線網(wǎng)絡中,通過網(wǎng)絡地址可以找到某個具體的節(jié)點,如協(xié)調器的網(wǎng)絡地址是Ox0000,但是具體到某一個節(jié)點上,還有不同的端口(endpoint),每個節(jié)點上最多支持240個端口(endpoint)。每個節(jié)點上最多有240個端口,端口0是默認的ZDO(ZigBeeDeviceObject),端口0~240用戶可以自己定義,引入端口主要是由于TI實現(xiàn)的ZigBee協(xié)議棧中加入了一個小的操作系統(tǒng),這樣,每個節(jié)點上的所有端口共用一個發(fā)射/接收天線,不同節(jié)點上的端口之間可以進行通信。AF_DataRequest數(shù)據(jù)發(fā)送函數(shù)中各個參數(shù)的具體含義(3)
如節(jié)點1的端口l可以給節(jié)點2的端口1發(fā)送控制命令來點亮LED(這就是燈光控制實驗),節(jié)點l的端口l也可以給節(jié)點2的端口2發(fā)送命令進行數(shù)據(jù)采集操作,但是節(jié)點2上端口l和端口2的網(wǎng)絡地址是相同的,所以僅僅通過網(wǎng)絡地址無法區(qū)分,所以,在發(fā)送數(shù)據(jù)時不但要指定網(wǎng)絡地址,還要指定端口號。
因此,通過上面的論述可以得到如下的結論:①使用網(wǎng)絡地址來區(qū)分不同的節(jié)點;②使用端口號來區(qū)分同一節(jié)點上的端口。節(jié)點與端口的關系注意:端口(endpoint)的概念跟TCP/IP編程中端口的概念相類似。AF_DataRequest數(shù)據(jù)發(fā)送函數(shù)中各個參數(shù)的具體含義(4)③uint16cID——這個參數(shù)描述的是命令號,在ZigBee協(xié)議里的命令主要用來標識不同的控制操作,不同的命令號代表了不同的控制命令,如節(jié)點1的端口1可以給節(jié)點2的端口l發(fā)送控制命令,當該命令的ID為l時表示點亮LED,當該命令的ID為0時表示熄滅LED,因此,該參數(shù)主要是為了區(qū)別不同的命令。如終端節(jié)點在發(fā)送數(shù)據(jù)時使用的命令ID是GENERICAPP_CLUSTERID.該宏定義是在Coordinator.h文件中定義的,它的值為1。④uint16len——該參數(shù)標識了發(fā)送數(shù)據(jù)的長度。⑤uint8*buf——該參數(shù)是指向發(fā)送數(shù)據(jù)緩沖區(qū)的指針,發(fā)送數(shù)據(jù)時只需要將所要發(fā)送的數(shù)據(jù)緩沖區(qū)的地址傳遞給該參數(shù)即可,數(shù)據(jù)發(fā)送函數(shù)會從該地址開始按照指定的數(shù)據(jù)長度取得發(fā)送數(shù)據(jù)進行發(fā)送。AF_DataRequest數(shù)據(jù)發(fā)送函數(shù)中各個參數(shù)的具體含義(5)⑥uint8*transID——該參數(shù)是一個指向發(fā)送序號的指針,每次發(fā)送數(shù)據(jù)時,發(fā)送序號會自動加l(協(xié)議棧里面實現(xiàn)的該功能),在接收端可以通過發(fā)送序號來判斷是否丟包,同時可以計算出丟包率。例如,發(fā)送了10個數(shù)據(jù)包,數(shù)據(jù)包的序號為0~9,在接收端發(fā)現(xiàn)序號為2和6的數(shù)據(jù)包沒有收到,則丟包率計算公式為:
丟包率=丟包個數(shù)/所發(fā)送的數(shù)據(jù)包的總個數(shù)*100%=20%⑦uint80ptions和uint8radius——這兩個參數(shù)取默認值即可,options參數(shù)可以取AFDISCV_ROUTE,radius參數(shù)可以取AF_DEFAULT_RADIUS。四、數(shù)據(jù)接收終端節(jié)點發(fā)送數(shù)據(jù)后,協(xié)調器會收到該數(shù)據(jù),但是協(xié)議棧里面是如何得到通過天線接收到的數(shù)據(jù)的呢?當協(xié)調器接收到數(shù)據(jù)后,操作系統(tǒng)會將該數(shù)據(jù)封裝成一個消息,然后放入消息隊列中,每個消息都有自己的消息ID,標識接收到新數(shù)據(jù)的消息的ID是AF_INCOMING_MSG_CMD,其中AF_INCOMING_MSG_CMD的值是0xlA,這是在ZigBee協(xié)議棧中定義好的,用戶不可更改.ZigBee協(xié)議棧中AF_INCOMING_MSG_CMD宏的定義如下(在Zcomdef.h文件中定義的):
#defineAF_INCOMING_MSG_CMD0x1A四、數(shù)據(jù)接收因此,在協(xié)調器代碼中有如下代碼段:MSGpkt=(afIncomingMSGPacket_t*)osal_msg_receive(GenericApp_TaskID);
while(MSGpkt){
switch(MSGpkt->hdr.event)
{
caseAF_INCOMING_MSG_CMD:
GenericApp_MessageMSGCB(MSGpkt);
break;……首先使用osalmsgreceive函數(shù)從消息隊列中接收一個消息,然后使用switch-case語句對消息類型進行判斷(判斷消息ID),如果消息ID是AF_INCOMING_MSG_CMD則進行相應的數(shù)據(jù)處理。到此為止,讀者至少理清楚這條線索:當協(xié)調器收到數(shù)據(jù)后,用戶只需要從消息隊列中接收消息,然后從消息中取得所需要的數(shù)據(jù)即可,其他工作都由ZigBee協(xié)議棧自動完成了。主講:張老師BasicRF---無線點燈實驗主講:張老師一、實驗原理二、重點代碼解析三、數(shù)據(jù)發(fā)送標題四、數(shù)據(jù)接收一、實驗原理——功能描述
實驗效果:兩塊節(jié)點模塊通信,一個模塊作發(fā)射,另外一個模塊接收,發(fā)射模塊按下按鍵S1(或S2),改變接收模塊LED1(或LED2)的亮滅的狀態(tài)。實現(xiàn)無線點燈功能。一、實驗原理——
BasicRF
例程的軟件設計框圖Hardwarelayer:放在最底,是實現(xiàn)數(shù)據(jù)傳輸?shù)幕A。HardwareAbstractionlayer:提供了一種接口來訪問TIMER,GPIO,UART,ADC等。這些接口都通過相應的函數(shù)進行實現(xiàn)。BasicRFlayer:為雙向無線傳輸提供一種簡單的協(xié)議。Applicationlayer:是用戶應用層,它相當于用戶使用BasicRF層和HAL的接口,也就是說我們通過在Applicationlayer就可以使用到封裝好的BasicRF和HAL的函數(shù)。四、BasicRF
的工作過程——啟動1.創(chuàng)建一個
basicRfCfg_t
的數(shù)據(jù)結構,并初始化其中的成員,在basic_rf.h代碼中可以找到typedefstruct
{uint16myAddr;//16位的短地址(就是節(jié)點的地址)
uint16panId;//節(jié)點的PANID
uint8channel;//RF通道(必須在11-26之間)
uint8ackRequest;//目標確認就置true
#ifdefSECURITY_CCM//是否加密,預定義里取消了加密118
uint8*securityKey;
uint8*securityNonce;
#endif}basicRfCfg_t;
2.調用
basicRfInit()函數(shù)進行協(xié)議的初始化,在
basic_rf.c
代碼中可以找到uint8basicRfInit(basicRfCfg_t*pRfConfig)/***函數(shù)功能:對BasicRF的數(shù)據(jù)結構初始化,設置模塊的傳輸通道,短地址,PADID。**/
三、BasicRF
的工作過程——發(fā)送3.
創(chuàng)建一個
buffer,把
payload
放入其中。
Payload
最大為
103
個字節(jié)
4.
調用
basicRfSendPacket()函數(shù)發(fā)送,并查看其返回值。在
basic_rf.c
中可以找到uint8basicRfSendPacket(uint16destAddr,uint8*pPayload,uint8length)/****destAddr目的短地址pPayload指向發(fā)送緩沖區(qū)的指針length發(fā)送數(shù)據(jù)長度函數(shù)功能:給目的短地址發(fā)送指定長度的數(shù)據(jù),發(fā)送成功剛返回SUCCESS,失敗則返回FAILED******/
二、BasicRF
的工作過程——接收5.上層通過
basicRfPacketIsReady()函數(shù)來檢查是否收到一個新數(shù)據(jù)包
在basic_rf.c
中可以找到6.調用
basicRfReceive()函數(shù),把收到的數(shù)據(jù)復制到
buffer
中。代碼可以在
basic_rf.c
中可以找到uint8basicRfPacketIsReady(void)/*函數(shù)功能:檢查模塊是否已經(jīng)可以接收下一個數(shù)據(jù),如果準備好剛返回TRUE*/
uint8basicRfReceive(uint8*pRxData,uint8len,int16*pRssi)/*函數(shù)功能:接收來自BasicRF層的數(shù)據(jù)包,并為所接收的數(shù)據(jù)和RSSI值配緩沖區(qū)*/
主講:張老師測誤碼率實驗主講:張老師一、實驗原理二、重點代碼解析三、數(shù)據(jù)發(fā)送標題四、數(shù)據(jù)接收一、實驗原理——功能描述
實驗效果:兩塊WeBee模塊通信,一個模塊作發(fā)射,另外一個模塊接收,接收模塊通過串口不在PC機上顯示當前的誤包率、RSSI值和接收到數(shù)據(jù)包的個數(shù)。
實驗目的::PER(誤包率檢測)實驗是BasicRF的第二個實驗,和無線點燈一樣是沒有使用協(xié)議棧的點對點通訊。通過無線點燈大家應該對zigbee的發(fā)射和接收有個感性的認識,本次實驗講解不會像無線點燈一樣講得那么詳細,因為接收發(fā)射的過程基本上是一樣的,但也希望初學者能自己認真學習一下這個實驗,相信會對無線傳輸會有一個更清晰的認識。一、實驗原理——實驗現(xiàn)象由于距離比較近,所以掉包不明顯的,有興趣的可以把發(fā)送節(jié)點拿到較遠的地方,然后觀察掉包率。或者先打開發(fā)送模塊,打開接收模塊來測試掉包,會顯示出掉包情況。二、重點代碼解析1.首先還是要先找到main.c
main.c做了哪些事情:①一大堆的初始化(都是必須的);②
設置信道,發(fā)射和接收模塊的信道必須一致;③選擇為發(fā)射或者接收模式。發(fā)射函數(shù)defineMODE_SEND則進入appTransmitter();接收函數(shù)沒有
defineMODE_SEND則進入appReceiver()二、重點代碼解析2.為了獲取傳輸?shù)男阅軈?shù),接收器中包含了如下幾個數(shù)據(jù)(包含在rxStats變量中,其類型為perRxStats_t)參數(shù)含義rxStats.expectedSeqNum預計下一個數(shù)據(jù)包的序號,其值等于“成功接收的數(shù)據(jù)包”+“丟失的數(shù)據(jù)包”+1rxStats.rssiSum上32個數(shù)據(jù)包的RSSI值的和rxStats.rcvdPkts每次PER測試中,成功接收到的數(shù)據(jù)包的個數(shù)rxStats.lostPkts丟失數(shù)據(jù)包的個數(shù)三、數(shù)據(jù)發(fā)送appTransmitter函數(shù)完成的任務:①初始化BasicRF②設置發(fā)射功率③設定測試的數(shù)據(jù)包量④配置定時器和IO⑤初始化數(shù)據(jù)包載荷⑥進行循環(huán)函數(shù),不斷地發(fā)送數(shù)據(jù)包,每發(fā)送完一次,下一個數(shù)據(jù)包的序列號自加1再發(fā)送;四、數(shù)據(jù)接收
接收函數(shù)appReceiver的作用:①串口在此初始化②初始化BasicRF③不斷地接收數(shù)據(jù)包,并檢查數(shù)據(jù)包序號是否為期望值,作出相應處理④串口打印出,接收包的個數(shù)\誤包率及上32個數(shù)據(jù)包的RSSI值的平均值主講:張老師ZigBee協(xié)議棧實驗:廣播與單播實驗主講:張老師一、實驗原理二、重點代碼解析三、實驗結果驗證標題四、數(shù)據(jù)接收一、實驗原理——基礎知識儲備Zigbee網(wǎng)絡中進行數(shù)據(jù)通信主要有三種類型:廣播、單播、組播。一、實驗原理——通信方式的協(xié)議棧實現(xiàn)參數(shù)1:afAddrType_t*dstAddr該參數(shù)包含了目的節(jié)點的網(wǎng)絡地址、端點號及數(shù)據(jù)傳送的模式,如單播、廣播或多播等。typedefstruct
{
Union
{
uint16shortAddr;
//用于標識該節(jié)點網(wǎng)絡地址的變量
}addr;afAddrMode_taddrMode;
//用于指定數(shù)據(jù)傳送模式,單播、多播還是廣播
byteendPoint;
//端點號
}afAddrType_t;
//
其定義在AF.h中afAddrType_t是個結構體如下:一、實驗原理——通信方式的協(xié)議棧實現(xiàn)
ZigBee協(xié)議棧將數(shù)據(jù)通信過程高度抽象,使用一個函數(shù)完成數(shù)據(jù)的發(fā)送,以不同的參數(shù)來選擇數(shù)據(jù)發(fā)送方式(廣播、組播還是單播)。afStatus_tAF_DataRequest(afAddrType_t*dstAddr,//目的地址指針endPointDesc_t*srcEP,
//發(fā)送節(jié)點的端點描述符指針uint16cID,
//ClusID簇ID號uint16len,
//發(fā)送數(shù)據(jù)的長度uint8*buf,
//指向存放發(fā)送數(shù)據(jù)的緩沖區(qū)指針uint8*transID,//傳輸序列號,該序列號隨著信息的發(fā)送而增加
uint8options,//發(fā)送選項uint8radius
//最大傳輸半徑(發(fā)送的跳數(shù))
)ZigBee協(xié)議棧中數(shù)據(jù)發(fā)送函數(shù)原型如下:一、實驗原理——通信方式的協(xié)議棧實現(xiàn)
上述結構體中的afAddrMode_taddrMode就是用于指定數(shù)據(jù)傳送模式,是個枚舉類型,可以設置為以下幾個值。typedefenum{
afAddrNotPresent=AddrNotPresent,
//表示通過綁定關系指定目的地址
afAddr16Bit=Addr16Bit,
//單播發(fā)送
afAddrGroup=AddrGroup,
//組播
afAddrBroadcast=AddrBroadcast//廣播}afAddrMode_t;Enum{
AddrNotPresent=0,
AddrGroup=1,
Addr16Bit=2,
Addr64Bit=3,
AddrBroadcast=15};一、實驗原理——單播注意,其實單播有兩種方式一種是綁定傳輸,一種是目標地址的單播傳輸。my_DstAddr.addrMode=(afAddrMode_t)AddrNotPresent,一種是直接指定目標地址的單播傳輸,比如協(xié)調器就是0x0000。①單播綁定傳輸my_DstAddr.addrMode=(afAddrMode_t)Addr16Bit;
//單播發(fā)送my_DstAddr.endPoint=GENERICAPP_ENDPOINT;
//目的端口號my_DstAddr.addr.shortAddr=0;
//按照綁定的方式進行單播,不需要指定目標地址,需要先將兩個設備綁定,將兩個設備綁定后即可通信②直接指定目標地址的單播傳輸:是標準尋址模式,它將數(shù)據(jù)包發(fā)送給一個已經(jīng)知道網(wǎng)絡地址的網(wǎng)絡設備,將afAddrMode設置為Addr16Bit并且在數(shù)據(jù)包中攜帶目標設備地址。my_DstAddr.addrMode=(afAddrMode_t)Addr16Bit;
//單播發(fā)送my_DstAddr.endPoint=GENERICAPP_ENDPOINT;
//目的端口號my_DstAddr.addr.shortAddr=0x0000;
//目標設備網(wǎng)絡地址一、實驗原理——廣播當應用程序需要將數(shù)據(jù)包發(fā)送給網(wǎng)絡的每一個設備時,使用這種模式。地址模式設置為AddrBroadcast。目標地址my_DstAddr.addr.shortAddr可以根據(jù)需求設置為下面廣播地址的一種。NWK_BROADCAST_SHORTADDR_DEVALL(0xFFFF)——數(shù)據(jù)包將被傳送到網(wǎng)絡上的所有設備,包括睡眠中的設備。對于睡眠中的設備,數(shù)據(jù)包將被保留在其父親節(jié)點直到查詢到它,或者消息超時(NWK_INDIRECT_MSG_TIMEOUT在f8wConifg.cfg中)。NWK_BROADCAST_SHORTADDR_DEVRXON(0xFFFD)——數(shù)據(jù)包將被傳送到網(wǎng)絡上的所有在空閑時打開接收的設備(RXONWHENIDLE),也就是說,除了睡眠中的所有設備。NWK_BROADCAST_SHORTADDR_DEVZCZR(0xFFFC)——數(shù)據(jù)包發(fā)送給所有的路由器,包括協(xié)調器。my_DstAddr.addrMode=(afAddrMode_t)AddrBroadcast;//廣播發(fā)送my_DstAddr.endPoint=GENERICAPP_ENDPOINT;
//目的端口號my_DstAddr.addr.shortAddr=0xFFFF;
//協(xié)調器網(wǎng)絡地址一、實驗原理——實驗效果及原理圖
實驗效果預設為:協(xié)調器周期性以廣播的形式向終端節(jié)點發(fā)送數(shù)據(jù),終端節(jié)點收到數(shù)據(jù)后,使開發(fā)板上的LED狀態(tài)翻轉,同時向協(xié)調器發(fā)送字符串“EndDevicereceived!”,協(xié)調器收到終端節(jié)點發(fā)回的數(shù)據(jù)后,通過串口輸出到PC機,用戶可以通過串口調試助手查看該信息。一、實驗原理——協(xié)調器工作流程協(xié)調器周期性以廣播的形式向終端節(jié)點發(fā)送數(shù)據(jù),如何實現(xiàn)周期性地發(fā)送數(shù)據(jù)呢?這里又需要用定時函數(shù)osal_start-timcrEx0,定時5s,定時時間達到后,向終端節(jié)點發(fā)送數(shù)據(jù),發(fā)送完數(shù)據(jù)再定時5s,這樣就實現(xiàn)了周期性地發(fā)送數(shù)據(jù)。一、實驗原理——終端節(jié)點工作流程終端節(jié)點上電后,會進行硬件電路的初始化,然后搜索是否有ZigBee無線網(wǎng)絡,如果有ZigBee無線網(wǎng)絡再自動加入(這是最簡單的情況,當然可以控制節(jié)點加入網(wǎng)絡時要符合編譯時確定的網(wǎng)絡號等),然后判斷是否收到協(xié)調器發(fā)送的數(shù)據(jù),若收到,則將LED狀態(tài)取反,然后發(fā)送數(shù)據(jù)到協(xié)調器,否則繼續(xù)等待接收數(shù)據(jù)。二、重點代碼解析--協(xié)調器程序設計if(events&SEND_TO_ALL_EVENT)//數(shù)據(jù)發(fā)送事件處理{GenericApp_SendTheMessage();osal_start_timerEx(GenericApp_TaskID,SEND_TO_ALL_EVENT,5000);return(events^SEND_TO_ALL_EVENT);}
當網(wǎng)絡狀態(tài)發(fā)生變化時,啟動定時器定時5S,定時時間到達后,設置SEND_TO_ALL_EVENT事件,在SEND_TO_ALL_EVENT事件處理函數(shù)中,調用發(fā)送數(shù)據(jù)函數(shù)GenericApp_SendTheMessage(),發(fā)送完數(shù)據(jù)后,再次啟動定時器,定時5S……二、重點代碼解析--協(xié)調器程序設計if(events&SEND_TO_ALL_EVENT)//數(shù)據(jù)發(fā)送事件處理{GenericApp_SendTheMessage();osal_start_timerEx(GenericApp_TaskID,SEND_TO_ALL_EVENT,5000);return(events^SEND_TO_ALL_EVENT);}
當網(wǎng)絡狀態(tài)發(fā)生變化時,啟動定時器定時5S,定時時間到達后,設置SEND_TO_ALL_EVENT事件,在SEND_TO_ALL_EVENT事件處理函數(shù)中,調用發(fā)送數(shù)據(jù)函數(shù)GenericApp_SendTheMessage(),發(fā)送完數(shù)據(jù)后,再次啟動定時器,定時5S……二、重點代碼解析--協(xié)調器程序設計voidGenericApp_MessageMSGCB(afIncomingMSGPacket_t*pkt){unsignedcharbuf[20];unsignedcharbuffer[2]={0x0A,0x0D};switch(pkt->clusterId){caseGENERICAPP_CLUSTERID:osal_memcpy(buf,pkt->cmd.Data,20);HalUARTWrite(0,buf,20);HalUARTWrite(0,buffer,2);break;}}當收到終端節(jié)點發(fā)回的數(shù)據(jù)后,讀取該數(shù)據(jù),然后發(fā)送到串口。二、重點代碼解析--協(xié)調器程序設計voidGenericApp_SendTheMessage(void){unsignedchar*theMessageData="Coordinatorsend!";afAddrType_tmy_DstAddr;my_DstAddr.addrMode=(afAddrMode_t)AddrBroadcast;my_DstAddr.endPoint=GENERICAPP_ENDPOINT;my_DstAddr.addr.shortAddr=0xFFFF;AF_DataRequest(&my_DstAddr,&GenericApp_epDesc,GENERICAPP_CLUSTERID,osal_strlen(theMessageData)+1,theMessageData,&GenericApp_TransID,AF_DISCV_ROUTE,AF_DEFAULT_RADIUS);}使用廣播方式發(fā)送數(shù)據(jù),注意,此時發(fā)送模式是廣播,如下代碼所示:my_DstAddr.addrMode=(afAddrMode_t)AddrBroadcast;相應的網(wǎng)絡地址可以設為0xFFFF,如下代碼所示:my_DstAddr.addr.shortAddr=0xFFFF;二、重點代碼解析—終端節(jié)點程序設計voidGenericApp_MessageMSGCB(afIncomingMSGPacket_t*pkt){char*recvbuf;unsignedcharbuffer[2]={0x0A,0x0D};switch(pkt->clusterId){caseGENERICAPP_CLUSTERID:osal_memcpy(recvbuf,pkt->cmd.Data,osal_strlen("Coordinatorsend!")+1);if(osal_memcmp(recvbuf,"Coordinatorsend!",osal_strlen("Coordinatorsend!")+1)){HalUARTWrite(0,recvbuf,18);
HalUARTWrite(0,buffer,2);GenericApp_SendTheMessage();}}}上述代碼是對接收到的數(shù)據(jù)進行處理,當正確接收到協(xié)調器發(fā)送的字符串"Coordinatorsend!"時,調用函數(shù)GenericApp_SendTheMessage()發(fā)送返回消息。二、重點代碼解析—終端節(jié)點程序設計voidGenericApp_SendTheMessage(void){unsignedchar*theMessageData="EndDevicereceived!";afAddrType_tmy_DstAddr;my_DstAddr.addrMode=(afAddrMode_t)Addr16Bit;my_DstAddr.endPoint=GENERICAPP_ENDPOINT;my_DstAddr.addr.shortAddr=0x0000;AF_DataRequest(&my_DstAddr,&GenericApp_epDesc,GENERICAPP_CLUSTERID,osal_strlen(theMessageData)+1,theMessageData,&GenericApp_TransID,AF_DISCV_ROUTE,AF_DEFAULT_RADIUS);HalLedSet(HAL_LED_2,HAL_LED_MODE_TOGGLE);}向協(xié)調器發(fā)送單播數(shù)據(jù),注意加粗字體部分的代碼實現(xiàn)的是單播通信。注意:HalLedSet()函數(shù)可以設置LED的狀態(tài)進行翻轉。三、實驗結果驗證--終端節(jié)點的串口發(fā)送設置好串口調試助手,打開協(xié)調器電源,然后打開兩個終端節(jié)點的電源,此時可以看到如下實驗現(xiàn)象:①每隔5S,終端節(jié)點的串口顯示一個字符串"Coordinatorsend!"②同時終端節(jié)點的LED每隔5S點亮一次。三、實驗結果驗證--協(xié)調器節(jié)點的串口發(fā)送設置好串口調試租手,打開協(xié)調器電源,然后打開兩個終端節(jié)點的電源,此時可以看到如下實驗現(xiàn)象:①每隔5S,串口會顯示三個字符串"EndDevicereceived!";②同時終端節(jié)點的LED每隔5S點亮一次。主講:張老師ZigBee協(xié)議棧實驗:組播實驗主講:張老師一、實驗原理二、重點代碼解析三、實驗結果驗證標題四、數(shù)據(jù)接收一、實驗原理--加入組的流程
當應用程序需要將數(shù)據(jù)包發(fā)送給網(wǎng)絡上的一組設備時,使用組播模式。地址模式設置為afAddrGroup,并且addr.shortAddr設置為組ID。使用組播的方式需要加入特定的組。加入組的流程如下:①首先聲明一個組對象aps_Group_tSampleApp_Groupaps_Group_t結構體的定義:typedefstruct{
uint16ID;
//Uniquetothistable
uint8
name[APS_GROUP_NAME_LEN];//#defineAPS_GROUP_NAME_LEN
16}aps_Group_t;每個組有個特定的ID跟組名,組名存放在name數(shù)組中,name數(shù)組的第一個元素是組名的長度,第二個元素開始存放組名字符串。一、實驗原理--加入組的流程
②對SampleApp_Group賦值//Bydefault,alldevicesstartoutinGroup1SampleApp_Group.ID=0x0003;
//初始化組IDosal_memcpy(SampleApp_G,"Group3",7);
//將組名的長度寫入name數(shù)組的第一個元素位置處。
③在本任務里將端點加入到組中aps_AddGroup(SAMPLEAPP_ENDPOINT,&SampleApp_Group);一、實驗原理--加入組的流程
④設定通信的目標地址及模式//Setupfortheflashcommand'sdestinationaddress-Group1SampleApp_Flash_DstAddr.addrMode=(afAddrMode_t)afAddrGroup;SampleApp_Flash_DstAddr.endPoint=SAMPLEAPP_ENDPOINT;SampleApp_Flash_DstAddr.addr.shortAddr=SampleApp_Group.ID;通信時候,發(fā)送設備的輸出cluster設定為接收設備的輸入cluster,另外profileID設定相同,即可通信。一、實驗原理--加入組的流程⑤若要把一個設備加入到組中的端點從組中移除,調用aps_RemoveGroup:aps_Group_t*grp;grp=aps_FindGroup(SAMPLEAPP_ENDPOINT,SAMPLEAPP_FLASH_GROUP);if(grp){
//Removefromthegroupaps_RemoveGroup(SAMPLEAPP_ENDPOINT,SAMPLEAPP_FLASH_GROUP);}注意組可以用來關聯(lián)間接尋址。再綁定表中找到的目標地址可能是是單點傳送或者是一個組地址。另外,廣播發(fā)送可以看做是一個組尋址的特例。一、實驗原理——實驗效果及原理圖協(xié)調器周期性的以組播的形式向路由器發(fā)送數(shù)據(jù)路由器收到數(shù)據(jù)后,使開發(fā)板上的LED狀態(tài)翻轉,同時向協(xié)調器發(fā)送字符串“Routerreceived!",協(xié)調器收到路由器發(fā)回的數(shù)據(jù)后,通過串口輸出到PC機,用戶可以通過串口調試助手查看該信息。在路由器編程時,將兩個路由器和協(xié)調器加到一個組中,剩余一個路由器不加入該組,觀察實驗現(xiàn)象。一、實驗原理——工作流程組播通信實驗協(xié)調器程序流程圖組播通信實驗路由器程序流程圖二、重點代碼解析--協(xié)調器程序設計#include"aps_groups.h"http://使用加入組函數(shù)aps_AddGroup()函數(shù),需要包含頭文件aps_Group_tGenericApp_Group;aps_Group_tGenericApp_Group;voidGenericApp_Init(bytetask_id){。。。GenericApp_Group.ID=0x0001;GenericApp_G[0]=6;osal_memcpy(&(GenericApp_G[1]),"Group1",6);}以上代碼是任務初始化代碼,主要完成端口初始化和組號的初始化。二、重點代碼解析--協(xié)調器程序設計UINT16GenericApp_ProcessEvent(bytetask_id,UINT16events){。。。caseZDO_STATE_CHANGE:GenericApp_Nwkstate=(devStates_t)(MSGpkt->hdr.status);if(GenericApp_Nwkstate==DEV_ZB_COORD)//建立網(wǎng)絡后,加入組
{aps_AddGroup(GENERICAPP_ENDPOINT,&GenericApp_Group);
osal_set_event(GenericApp_TaskID,SEND_TO_ALL_EVENT);}。。。
if(events&SEND_TO_ALL_EVENT)//發(fā)送組播數(shù)據(jù),每次發(fā)送完就定時5秒
{GenericApp_SendTheMessage();osal_start_timerEx(GenericApp_TaskID,SEND_TO_ALL_EVENT,5000);return(events^SEND_TO_ALL_EVENT);}}二、重點代碼解析--協(xié)調器程序設計voidGenericApp_SendTheMessage(void){char*theMessageData="Coordinatorsend!";afAddrType_tmy_DstAddr;my_DstAddr.addrMode=(afAddrMode_t)AddrGroup;my_DstAddr.endPoint=GENERICAPP_ENDPOINT;my_DstAddr.addr.shortAddr=GenericApp_Group.ID;AF_DataRequest(&my_DstAddr,&GenericApp_epDesc,GENERICAPP_CLUSTERID,osal_strlen(theMessageData)+1,theMessageData,&GenericApp_TransID,AF_DISCV_ROUTE,AF_DEFAULT_RADIUS);}上述函數(shù)實現(xiàn)了組播發(fā)送,此時地址模式設置為AddrGroup,網(wǎng)絡地址設置為組ID,即GenericApp_Group.ID。二、重點代碼解析--協(xié)調器程序設計voidGenericApp_SendTheMessage(void){unsignedchar*theMessageData="Coordinatorsend!";afAddrType_tmy_DstAddr;my_DstAddr.addrMode=(afAddrMode_t)AddrBroadcast;my_DstAddr.endPoint=GENERICAPP_ENDPOINT;my_DstAddr.addr.shortAddr=0xFFFF;AF_DataRequest(&my_DstAddr,&GenericApp_epDesc,GENERICAPP_CLUSTERID,osal_strlen(theMessageData)+1,theMessageData,&GenericApp_TransID,AF_DISCV_ROUTE,AF_DEFAULT_RADIUS);}使用廣播方式發(fā)送數(shù)據(jù),注意,此時發(fā)送模式是廣播,如下代碼所示:my_DstAddr.addrMode=(afAddrMode_t)AddrBroadcast;相應的網(wǎng)絡地址可以設為0xFFFF,如下代碼所示:my_DstAddr.addr.shortAddr=0xFFFF;二、重點代碼解析—路由器節(jié)點程序設計UINT16GenericApp_ProcessEvent(bytetask_id,UINT16events){。。。caseZDO_STATE_CHANGE:GenericAPP_NwkState=(devStates_t)(MSGpkt->hdr.status);if(GenericAPP_NwkState==DEV_ROUTER){aps_AddGroup(GENERICAPP_ENDPOINT,&GenericApp_Group);}}
以上代碼是事件處理函數(shù)。當路由器成功加入網(wǎng)絡后,調用aps_AddGroup()函數(shù)加到組中。二、重點代碼解析—路由器節(jié)點程序設計voidGenericApp_SendTheMessage(void){unsignedchar*theMessageData="Routerreceived!";afAddrType_tmy_DstAddr;my_DstAddr.addrMode=(afAddrMode_t)Addr16Bit;my_DstAddr.endPoint=GENERICAPP_ENDPOINT;my_DstAddr.addr.shortAddr=0x0000;AF_DataRequest(&my_DstAddr,&GenericApp_epDesc,GENERICAPP_CLUSTERID,osal_strlen(theMessageData)+1,theMessageData,&GenericApp_TransID,AF_DISCV_ROUTE,AF_DEFAULT_RADIUS);HalLedSet(HAL_LED_2,HAL_LED_MODE_TOGGLE);}以單播的形式向協(xié)調器發(fā)送數(shù)據(jù)“Routerreceived!”,發(fā)送完數(shù)據(jù)后,調用HalLedSet()函數(shù)使LED的狀態(tài)翻轉。二、重點代碼解析—路由器節(jié)點程序設計然后,將加入組函數(shù)aps_AddGroup()注釋掉,如下代碼所示。caseZDO_STATE_CHANGE:GenericAPP_NwkState=(devStates_t)(MSGpkt->hdr.status);if(GenericAPP_NwkState==DEV_ROUTER){//aps_AddGroup(GENERICAPP_ENDPOINT,&GenericApp_Group);}break;將加入組函數(shù)aps_AddGroup()注釋掉后下載到另一塊開發(fā)板中三、實驗結果驗證--開發(fā)板A和B都下載加入到組的程序打開兩個路由器的電源,此時可以看到如下現(xiàn)象:每隔5S,串口會顯示2個字符串“Routerreceived!”,同時開發(fā)板A和開發(fā)板B的LED每隔5S都會點亮一次。三、實驗結果驗證
溫馨提示
- 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. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 調度服務協(xié)議書范本
- 貸款房子出售合同協(xié)議
- 貨架合同協(xié)議書范本
- 購銷合同修訂補充協(xié)議
- 資產(chǎn)買賣意向合同協(xié)議
- 超市煙草采購合同協(xié)議
- 2025幼兒園數(shù)學學習方案試題及答案
- 樓盤項目并購協(xié)議書范本
- 微信支付服務合同協(xié)議
- 員工簽訂勞務合同協(xié)議
- 2025天津東疆綜合保稅區(qū)管理委員會招聘10人筆試參考題庫附帶答案詳解
- 雅禮新苗杯試題及答案
- 醫(yī)院地震安全培訓
- 2025-2030中國低壓電器行業(yè)市場發(fā)展趨勢與前景展望戰(zhàn)略研究報告
- 2025上海海事大學輔導員考試題庫
- 餐飲部菜品制作流程優(yōu)化方案
- 非煤礦山安全生產(chǎn)作業(yè)指導書
- 2025年福建新華發(fā)行集團招聘筆試參考題庫含答案解析
- (新版)妊娠期惡心嘔吐及妊娠劇吐管理指南解讀
- 歐洲西部資料歐洲西部 詳細版課件
- 流數(shù)據(jù)分析技術全套課件
評論
0/150
提交評論