ZStack
Z-Stack 是德州儀器(Texas Instrument)的半開(kāi)源 Zigbee 協(xié)議棧。Z-Stack 2.5.1a 是其發(fā)布的最后一個(gè)獨(dú)立發(fā)行版;所謂「獨(dú)立發(fā)行版」,即,提供的版本里,既包括了諸如智能家居的 Home Automation profile 相關(guān)內(nèi)容,也包括了諸如集中抄表的 Smart Energy profile 相關(guān)內(nèi)容,通俗地講,大雜燴。往后的 Z-Stack,則是捆綁在單獨(dú)的 profile 里,不再提供單獨(dú)下載。

基本介紹 編輯本段
Zigbee 原本是為了解決低功耗局域網(wǎng)的互操作性問(wèn)題,而誕生的一個(gè)基于 802.15.4 層的協(xié)議。假設(shè),你家里的燈泡采取了 SmartBlub 協(xié)議(胡謅的名字),空氣凈化設(shè)備使用了私有 AirCleaner 協(xié)議,集中控制器則是 SmartController 協(xié)議,那么恭喜你,雞同鴨講的窘狀,在你家的「智能家居」之間發(fā)生了。遇上如此惱火的事情,你當(dāng)然會(huì)把這群「智能設(shè)備」罵一遍。為了避免高素質(zhì)的你受委屈,Zigbee 誕生了:燈泡們,空調(diào)們,大伙都使用 Zigbee 協(xié)議,大家好才是真的好!然而,世界是復(fù)雜的。除了智能家居,還有很多需要互聯(lián)互通互操作的領(lǐng)域,如能源管理,醫(yī)療,建筑自動(dòng)化。你會(huì)問(wèn),如此多迥異的應(yīng)用場(chǎng)景,彼此也會(huì)有不同的拓?fù)浜屯ㄐ判枨螅惶?Zigbee 協(xié)議,可以滿足全部的場(chǎng)景嗎?Zigbee 響亮地吼道「五大受損一個(gè)對(duì)策」,Zigbee 為了應(yīng)對(duì)這些不同的場(chǎng)景,其不得不折騰了若干不同的 profile(配置)。
使用方法 編輯本段
一般情況下用戶只需要額外添加三個(gè)文件就可以完成一個(gè)項(xiàng)目。一個(gè)是主文件,存放具體的任務(wù)事件處理函數(shù);一個(gè)是這個(gè)主文件的頭文件;另外一個(gè)是以O(shè)sal開(kāi)頭的操作系統(tǒng)接口文件,是專(zhuān)門(mén)存放任務(wù)處理函數(shù)數(shù)組tasksArr[]的文件。這樣就實(shí)現(xiàn)了Z-Stack代碼的公用,用戶只需要添加這幾個(gè)文件,編寫(xiě)自己的任務(wù)處理函數(shù)就可以了。
1.學(xué)習(xí)ZigBee操作系統(tǒng)抽象層應(yīng)用程序編程接口。
2.剖析一個(gè)簡(jiǎn)單的例程學(xué)習(xí)使用Z-Stack。
下面工作一一弄明白:
(1)頭文件----參考例程添加頭文件。
(2)系統(tǒng)初始化和使用----函數(shù)Init和ProcessEvent。
(3)任務(wù)建立,調(diào)用,切換
(4)中斷配置----熟悉編程接口即可。
(5)定時(shí)器使用----熟悉編程接口即可。
(6)驅(qū)動(dòng)文件編寫(xiě)和調(diào)用
(7)網(wǎng)絡(luò)建立和加入-->組網(wǎng)
(8)電源管理----節(jié)能配置----熟悉編程接口即可。
(9)編寫(xiě)程序----使用五向按鍵控制四個(gè)LED燈(先看懂Simple例程)。
有選擇的讀代碼:
需要讀的代碼:APP(全部代碼);HAL和Zmain的全部或部分代碼。
其他:熟悉編程接口和使用方法。
一、Z-Stack 操作系統(tǒng)抽象層應(yīng)用程序編程接口:
1、信息管理API:
信息管理 API 為任務(wù)和處理單元之間的信息交換提供了一種具有不同處理環(huán)境的機(jī)制(例如,在一個(gè)控制循環(huán)中調(diào)用中斷服務(wù)常規(guī)程序或函數(shù))。這個(gè) API 中的函數(shù)可以使任務(wù)分配或回收信息緩沖區(qū),給其它任務(wù)發(fā)送命令信息以及接收回復(fù)信息。API包括四個(gè)函數(shù):
(1) osal_msg_allocate ():分配一個(gè)信息緩沖;
(2) osal_msg_deallocate():回收一個(gè)信息緩沖區(qū);
(3) osal_msg_send():發(fā)送命令或數(shù)據(jù)信息;
(4) osal_msg_receive():檢索/接收一條已收到的命令信息;
1、任務(wù)同步API:
這個(gè) API 使得任務(wù)等待事件發(fā)生,并在等待期間返回控制。這個(gè) API 中的函數(shù)可以用來(lái)為一個(gè)任務(wù)設(shè)置事件,并無(wú)論設(shè)置了什么事件都通知任務(wù)。僅有一個(gè)函數(shù)osal_set_event():用來(lái)為一個(gè)任務(wù)設(shè)置事件標(biāo)志。
2、定時(shí)器管理API:
這個(gè)API使得內(nèi)部的(Z-Stack)任務(wù)和外部的(應(yīng)用層)任務(wù)都可以使用定時(shí)器。API提供了啟動(dòng)和停止一個(gè)定時(shí)器的功能,這定時(shí)器可設(shè)定遞增的一毫秒。
(1)osal_start_timer():?jiǎn)?dòng)一個(gè)定時(shí)器;
(2)osal_start_timerEx():增加了taskID參數(shù)。它允許訪問(wèn)者調(diào)用程序?yàn)榱硪粋€(gè)任務(wù)設(shè)置定時(shí)器;
(3)osal_stop_timer():調(diào)用函數(shù)用來(lái)停止一個(gè)已啟動(dòng)的定時(shí)器;
(4)osal_stop_timerEx():用來(lái)停止一個(gè)已啟動(dòng)的定時(shí)器;
(5)osal_GetSystemClock():讀取系統(tǒng)時(shí)鐘。
4、中斷管理 API:
此API使得一個(gè)任務(wù)可以與外部中斷相互交流。API 中的函數(shù)允許和每個(gè)中斷去聯(lián)絡(luò)一個(gè)具體的服務(wù)例程。中斷可以啟用或禁用。在服務(wù)例程內(nèi)部,可以為其它任務(wù)設(shè)置事件。
(1)osal_int_enable():?jiǎn)⒂靡粋€(gè)中斷;
(2)osal_int_disable():禁用一個(gè)中斷。
5、任務(wù)管理 API:
在OSAL系統(tǒng)中,API常用于添加和管理任務(wù)。每個(gè)任務(wù)由初始化函數(shù)和事件處理函數(shù)組成。OSAL調(diào)用osalInitTasks()(應(yīng)用程序提供)去初始化這任務(wù)且 OSAL 運(yùn)用一個(gè)任務(wù)列表(const pTaskEventHandlerFntasksArr[])去為每個(gè)任務(wù)(也是應(yīng)用程序提供)調(diào)用事件處理程序。
(1)osal_init_system():初始化OSAL系統(tǒng),在使用任何其它OSAL函數(shù)之前必須先調(diào)用此函數(shù)啟動(dòng)OSAL系統(tǒng)。
(2)osal_start_system():任務(wù)系統(tǒng)中的主循環(huán)函數(shù)。它將檢查所有的任務(wù)事件且為含有該事件的任務(wù)調(diào)用任務(wù)事件處理函數(shù)。假如有特定任務(wù)的事件,這個(gè)函數(shù)將為該任務(wù)調(diào)用事件處理例程來(lái)處理事件。相應(yīng)任務(wù)的事件處理例程一次處理一個(gè)事件。一個(gè)事件被服務(wù)后,剩余的事件將等待下一次循環(huán)。如果這沒(méi)有事件(服務(wù)與所有任務(wù)),這個(gè)函數(shù)使處理器程序處于睡眠模式。
6、內(nèi)存管理 API:
該API 代表一個(gè)簡(jiǎn)單的內(nèi)存分配系統(tǒng)。這些函數(shù)允許動(dòng)態(tài)存儲(chǔ)內(nèi)存分配。
(1) osal_mem_alloc():一個(gè)簡(jiǎn)單的內(nèi)存分配函數(shù),如果分配成功則返回一個(gè)指向緩沖區(qū)的指針;
(2) osal_mem_free():釋放存儲(chǔ)空間便于再次運(yùn)用。
7、電源管理 API:
當(dāng)它安全關(guān)閉接收器和外部硬件時(shí),這個(gè)系統(tǒng)為應(yīng)用程序或任務(wù)提供了一種告知OSAL的方法。接著使處理器轉(zhuǎn)入睡眠。
(1)osal_pwrmgr_device():當(dāng)升高電源或需要改變電源時(shí)(例如電池支持的協(xié)調(diào)器)這個(gè)函數(shù)應(yīng)由中心控制實(shí)體(比如ZDO)調(diào)用。
(2)osal_pwrmgr_task_state():無(wú)論這個(gè)任務(wù)是否想要保護(hù)電源,每個(gè)任務(wù)都將調(diào)用此函數(shù)。任務(wù)將調(diào)用此函數(shù)來(lái)表決是否需要OSAL保護(hù)電源或推遲電源保護(hù)。默認(rèn)情況下,當(dāng)一個(gè)任務(wù)被創(chuàng)建時(shí),它自己的電源狀態(tài)設(shè)置為保護(hù)模式。如果該任務(wù)一直想要保護(hù)電源,就根本不必調(diào)用此函數(shù)。
8、非易失性存儲(chǔ)器(NV)的 API:
描述了OSAL非易失性存儲(chǔ)器系統(tǒng)。該系統(tǒng)為應(yīng)用程序提供了一種把信息永久保存到設(shè)備內(nèi)存的方法。它還能用于ZigBee規(guī)范要求的把某些項(xiàng)目永久保存到協(xié)議棧。NV函數(shù)的職能是讀寫(xiě)任意數(shù)據(jù)類(lèi)型的用戶自定義項(xiàng)目,比如結(jié)構(gòu)體和數(shù)組。用戶能通過(guò)設(shè)置適當(dāng)?shù)钠坪烷L(zhǎng)度來(lái)讀和寫(xiě)一個(gè)整體的項(xiàng)目或元素。API獨(dú)立于NV存儲(chǔ)介質(zhì),并且能用于實(shí)現(xiàn)閃存或EEPROM。
每個(gè)易失性的項(xiàng)目都僅有一個(gè)ID,當(dāng)一些ID值由?;蚱脚_(tái)保留或運(yùn)用時(shí),應(yīng)用程序中有特定一系列的ID值。假如應(yīng)用程序創(chuàng)建自己的易失性項(xiàng)目,它必須從應(yīng)用范圍的值內(nèi)選擇一個(gè)標(biāo)識(shí)符。參考下面的列表:
(1)osal_nv_item_init():初始化NV項(xiàng)目,這個(gè)函數(shù)檢查存在NV的項(xiàng)目,假如不存在,它將通過(guò)這個(gè)函數(shù)去創(chuàng)建或初始化。
(2)osal_nv_read():從NV中讀出數(shù)據(jù)。這個(gè)函數(shù)能用來(lái)從NV 中帶有偏移的索引指向的項(xiàng)目讀出整個(gè)項(xiàng)目或一個(gè)元素。讀出的數(shù)據(jù)復(fù)制到*buf中。
(3)osal_nv_write():寫(xiě)入數(shù)據(jù)到NV,這個(gè)函數(shù)用來(lái)通過(guò)帶有偏移的索引指向項(xiàng)目的偏移量來(lái)寫(xiě)入整個(gè)NV項(xiàng)目。
(4)osal_offsetof():計(jì)算一個(gè)結(jié)構(gòu)體內(nèi)元素的內(nèi)存偏移量,以字節(jié)為單位。
啟動(dòng)過(guò)程 編輯本段
1、Zigbee啟動(dòng)過(guò)程詳見(jiàn)前面Page3。
2、Zigbee啟動(dòng)過(guò)程總結(jié):
(1)Zmain.c文件中包含程序入口main()函數(shù)。
(2)main()函數(shù)主要做了做了兩件工作,一個(gè)是系統(tǒng)初始化,即有啟動(dòng)代碼來(lái)初始化硬件系統(tǒng)和軟件架構(gòu)需要的各個(gè)模塊,另一個(gè)作用是執(zhí)行操作系統(tǒng)實(shí)體---main函數(shù)最后調(diào)用函數(shù)Osal_start_system()來(lái)啟動(dòng)操作系統(tǒng)。
(3)用戶如何編寫(xiě)應(yīng)用程序:
一般用戶只需額外添加三個(gè)文件即可完成一個(gè)項(xiàng)目:主文件---SampleApp.c,存放具體的任務(wù)事件處理函數(shù);主文件的頭文件---SampleApp.h;第三個(gè)是以O(shè)sal開(kāi)頭的操作系統(tǒng)接口文件---OSAL_SampleApp.c,是專(zhuān)門(mén)存放任務(wù)處理函數(shù)數(shù)組tasksArr[]的文件。這樣就實(shí)現(xiàn)了Z-Stack代碼的公用,用戶只需要添加這幾個(gè)文件,編寫(xiě)自己的任務(wù)處理函數(shù)就可以了。
(4)SampleApp例程中分為四個(gè)部分:DemoEB、CoordinatorEB、RouterEB和EndDeviceEB,在按鍵發(fā)送閃爍試驗(yàn)中僅僅使用了DemoEB。
3、一個(gè)完整的初始化過(guò)程(按鍵發(fā)送閃爍實(shí)驗(yàn)):
main()-->osal_init_system()-->osalInitTasks()-->SampleApp_Init(task_id)
涉及的文件為:ZMain.c、OSAL.c、OSAL_SampleApp.c和SampleApp.c,也就是啟動(dòng)文件-->系統(tǒng)文件-->系統(tǒng)接口文件-->應(yīng)用程序。
4、一個(gè)完整的任務(wù)/事件處理過(guò)程(按鍵發(fā)送閃爍實(shí)驗(yàn)):
main() --> osal_start_system() --> osal_run_system() --> tasksArr --> SampleApp_ProcessEvent();同樣是:?jiǎn)?dòng)文件-->系統(tǒng)文件-->系統(tǒng)接口文件-->應(yīng)用程序;其中osal_start_system是個(gè)無(wú)限循環(huán):for(;;)。
1、操作系統(tǒng)接口文件---OSAL_SampleApp.c(按鍵發(fā)送閃爍實(shí)驗(yàn)):
主要是定義了結(jié)構(gòu)體:函數(shù)指針數(shù)組tasksArr(包含SampleApp_ProcessEvent)和任務(wù)初始化函數(shù)osalInitTasks;其中tasksArr在OSAL.c中被調(diào)用:events=(tasksArr[idx])(idx,events)à此語(yǔ)句就是調(diào)用了函數(shù)指針數(shù)組中的一個(gè)函數(shù),(tasksArr[idx])為函數(shù)名,(idx,events)位函數(shù)的參數(shù)(任務(wù)號(hào)和事件),events為返回值。
2、SampleApp_Init()---按鍵發(fā)送閃爍實(shí)驗(yàn):
(1)通用應(yīng)用程序任務(wù)初始化函數(shù),這個(gè)函數(shù)在初始化過(guò)程中被調(diào)用,該函數(shù)應(yīng)該包含任何特定于應(yīng)用程序的初始化(即硬件初始化/設(shè)置,表的初始化,電源初始化等等)。
(2)自己編寫(xiě)應(yīng)用初始化函數(shù)可以在這個(gè)函數(shù)基礎(chǔ)上添加其他初始化函數(shù)。
3、SampleApp_ProcessEvent()---按鍵發(fā)送閃爍實(shí)驗(yàn):
(1)通用應(yīng)用程序任務(wù)事件處理函數(shù)。這個(gè)函數(shù)被調(diào)用處理任務(wù)的所有事件。事件類(lèi)型包括定時(shí)器、信息和其他用戶定義的事件(如Key事件)。
(2)自己編寫(xiě)事件處理函數(shù)可以在這個(gè)函數(shù)基礎(chǔ)上添加其他用到的事件。
7、SimpleApp:
(1)分為四部分:ControllerEB、CollectorEB、SensorEB和SwitchEB;其中按鍵控制LED例程使用了ControllerEB(協(xié)調(diào)器)和SwitchEB(終端節(jié)點(diǎn));無(wú)線測(cè)溫實(shí)驗(yàn)使用了SensorEB(終端節(jié)點(diǎn))和CollectorEB(協(xié)調(diào)器);
(2)sapi.c和sapi.h:相當(dāng)于操作系統(tǒng)接口文件---OSAL_SampleApp.c;
(3)按鍵控制LED全過(guò)程:
按下SimpleControllerEB的up鍵建立zigbee網(wǎng)絡(luò)-->按下SimpleControllerEB的up鍵允許別的模塊對(duì)其綁定-->按下SimpleSwitchEB的up鍵搜索網(wǎng)絡(luò)并加入到網(wǎng)絡(luò)-->再次按下SimpleSwitchEB的up鍵與SimpleControllerEB建立綁定-->交替按下SimpleSwitchEB的right鍵來(lái)控制SimpleControllerEB模塊的LED1的交替亮滅。
(4)按鍵控制LED程序解讀:
---SimpleControllerEB的zb_AllowBind(myAllowBindTimeout ) -->允許綁定
---SimpleSwitchEB的zb_BindDevice()-->建立綁定
---SimpleSwitchEB的zb_SendDataRequest(0xFFFE, TOGGLE_LIGHT_CMD_ID, ******)-->發(fā)送閃燈指令
---sapi.c中的SAPI_ProcessEvent調(diào)用osal_msg_receive-->接收指令并執(zhí)行
---SAPI_ProcessEvent函數(shù)位于函數(shù)數(shù)組tasksArr中被輪詢調(diào)用。
---AF_INCOMING_MSG_CMD-->SAPI_ReceiveDataIndication-->zb_ReceiveDataIndication-->最終調(diào)用HalLedSet(HAL_LED_1, HAL_LED_MODE_TOGGLE)使LED1閃爍
8、網(wǎng)絡(luò)建立(組網(wǎng)—建立網(wǎng)絡(luò)和節(jié)點(diǎn)加入網(wǎng)絡(luò)):
osal_init_system()-->osalInitTasks()-->ZDApp_Init(taskID++)--> ZDOInitDevice(0)--> ZDApp_NetworkInit( extendedDelay )用于啟動(dòng)連接網(wǎng)絡(luò) --> osal_start_timerEx --> osal_start_system() --> osal_run_system()--> tasksArr --> ZDApp_event_loop(位于函數(shù)數(shù)組tasksArr中)--> ZDO_StartDevice --> NLME_NetworkFormationRequest(路由器或終端節(jié)點(diǎn)請(qǐng)求)--> ZDO_NetworkFormationConfirmCB(協(xié)調(diào)器確認(rèn))--> osal_set_event --> 回到ZDApp_event_loop--> ZDO_UpdateNwkStatus -->網(wǎng)絡(luò)已建立。
9、按鍵發(fā)送閃爍實(shí)驗(yàn)---先看懂再改寫(xiě):
(1) SampleApp_Init:初始化讀跳線(IO口電平)判斷節(jié)點(diǎn)/設(shè)備類(lèi)型。
(2) SampleApp_ProcessEvent:事件處理函數(shù),會(huì)被循環(huán)調(diào)用;功能是接收其他節(jié)點(diǎn)發(fā)來(lái)的消息或指令,其中包括按鍵指令(有按鍵按下),然后調(diào)用按鍵處理函數(shù)進(jìn)行相應(yīng)的操作;接收消息事件是指接收到消息或者指令。
(3) SampleApp_HandleKeys:按鍵操作函數(shù),處理所有的按鍵事件(按鍵是指本節(jié)點(diǎn)的按鍵)。
(4) SampleApp_SendFlashMessage(SAMPLEAPP_FLASH_DURATION):此函數(shù)發(fā)送閃爍命令(組播),調(diào)用函數(shù)AF_DataRequest發(fā)送數(shù)據(jù)。
(5) aps_FindGroup ( SAMPLEAPP_ENDPOINT,SAMPLEAPP_FLASH_GROUP ):該節(jié)點(diǎn)是否位于本組之中;
aps_RemoveGroup(SAMPLEAPP_ENDPOINT, SAMPLEAPP_FLASH_GROUP ):如果節(jié)點(diǎn)位于本組,則從本組中移除。
(6)SampleApp_MessageMSGCB:調(diào)用HalLedBlink函數(shù)實(shí)現(xiàn)閃燈,閃爍四次,周期為250ms,占空比50%。
(7)按鍵操作總結(jié):
KEY_CHANGE事件:按鍵按下也被封裝成一條消息,但并非是其他節(jié)點(diǎn)發(fā)送的消息;消息不代表無(wú)線通信接收到數(shù)據(jù)。
10、無(wú)線測(cè)溫實(shí)驗(yàn)---先看懂再改寫(xiě):
(1)發(fā)送流程:main() --> osal_start_system() --> osal_run_system() --> tasksArr -->SAPI_ProcessEvent --> zb_HandleOsalEvent --> myApp_ReadTemperature --> zb_SendDataRequest --> AF_DataRequest。
(2)接收流程:main() --> osal_start_system() --> osal_run_system() --> tasksArr -->SAPI_ProcessEvent --> AF_INCOMING_MSG_CMD --> SAPI_ReceiveDataIndication --> zb_ReceiveDataIndication --> osal_memcpy --> MT_ProcessEvent --> MT_ProcessIncomingCommand --> 串口發(fā)送函數(shù)HalUARTWrite。
(3)函數(shù)解讀:
11、透明傳輸實(shí)驗(yàn)---先看懂再改寫(xiě):
(1)初始化:
main() --> osal_init_system() --> osalInitTasks() --> SerialApp_Init()
(2)發(fā)送流程:
main() --> osal_start_system() --> osal_run_system() --> tasksArr --> SerialApp_ProcessEvent -->SerialApp_Send()--> HalUARTRead--> AF_DataRequest
(3)接收流程:
main() --> osal_start_system() --> osal_run_system() --> tasksArr --> SerialApp_ProcessEvent --> AF_INCOMING_MSG_CMD --> SerialApp_ProcessMSGCmd
附件列表
詞條內(nèi)容僅供參考,如果您需要解決具體問(wèn)題
(尤其在法律、醫(yī)學(xué)等領(lǐng)域),建議您咨詢相關(guān)領(lǐng)域?qū)I(yè)人士。
如果您認(rèn)為本詞條還有待完善,請(qǐng) 編輯
上一篇 華為云盤(pán)古 下一篇 阻抗匹配