Z-Stack Home Developer's Guide—2. Overview中文翻译【Z-Stack Home 1.2.0开发文档】
下面是Z-Stack Home 1.2.0開發(fā)資料中的Z-Stack Home Developer’s Guide—2. Overview的中文翻譯
2.1 簡(jiǎn)介
這章節(jié)將介紹 Z-Stack協(xié)議棧的示例程序。 每一個(gè)Z-Stack協(xié)議棧的示例程序都是為了實(shí)現(xiàn)一個(gè)特定的應(yīng)用程序 使用zigbee協(xié)議棧可以非常簡(jiǎn)單的開始。
這個(gè)章節(jié)將作為一個(gè)通用的概述。 需要一個(gè)動(dòng)手的用戶指南, 請(qǐng)參閱Z-Stack Home Sample Application User’s Guide [3]。
每個(gè)樣本應(yīng)用程序都使用ZDO公共接口的最小子集,以使設(shè)備在ZigBee網(wǎng)絡(luò)中具有相當(dāng)?shù)目尚行浴?另外, 所有的樣例程序都利用基本的OSAL API 函數(shù): 網(wǎng)絡(luò)和內(nèi)部任務(wù)之間的交流, 通過發(fā)送和接受消息, 設(shè)置和接受任務(wù)事件, 設(shè)置和接受定時(shí)器回調(diào), 使用動(dòng)態(tài)內(nèi)存, 以及其他的。 除此之外, 每個(gè)示例程序會(huì)使用HAL API 函數(shù), 例如。 為了控制 LED’s。 因此, 任何樣例應(yīng)用程序都是復(fù)制和粘貼的一個(gè)很好的例子, 或者作為用戶應(yīng)用程序的基本代碼 可以添加額外的應(yīng)用程序?qū)ο蟆?/p>
任何應(yīng)用程序?qū)ο蠖家欢ㄊ俏挥谖ㄒ欢它c(diǎn)的頂部; 任何端點(diǎn)都是由一個(gè)簡(jiǎn)單的描述符定義的。
示例應(yīng)用程序中的簡(jiǎn)單描述符中用于端點(diǎn)的數(shù)字可以任意選擇的。
每個(gè)示例應(yīng)用程序?qū)嵗粋€(gè)應(yīng)用程序?qū)ο?#xff0c; 因此, 僅支持相應(yīng)的Profile。 但是請(qǐng)注意,2個(gè)或者更多的應(yīng)用程序?qū)ο罂梢栽谙嗤脑O(shè)備上實(shí)例化。 當(dāng)在同一個(gè)設(shè)備中實(shí)例化多個(gè)應(yīng)用程序?qū)ο髸r(shí),每個(gè)應(yīng)用程序?qū)ο蟊仨殞?shí)現(xiàn)一個(gè)唯一的Profile Id,并在頂部設(shè)置唯一的端點(diǎn)編號(hào)。 示例應(yīng)用程序滿足唯一Id和端點(diǎn)編號(hào)需求并且能組成到一個(gè)設(shè)備中只要比較小的修改。
以下段落描述了OSAL 任務(wù):
2.1.1 Initialization
OSAL是有意的作為分配源,這樣通過Z-Stack用戶整個(gè)OSAL的功能就可以被修改了。
設(shè)計(jì)的目標(biāo)是為使用Z-Stack as distributed修改OSAL并不是必須的。 有一個(gè)除外—OSAL Task 初始化函數(shù), osalInitTasks(), 一定要被用戶實(shí)現(xiàn)。 示例程序在專用的文件中已經(jīng)實(shí)現(xiàn), 名字的命名規(guī)則: OSAL_”Application Name”.c (比如 OSAL_SampleLight.c)。 BSP將調(diào)用osalInitTasks()函數(shù) 作為開發(fā)板上電的一部分和Z-Stack初始化過程。
2.1.2 Organization
詳細(xì)的描述在 Z-Stack OSAL API [5] 文檔中, OSAL實(shí)現(xiàn)了一個(gè)合作, 循環(huán)任務(wù)服務(wù)循環(huán)。每一個(gè)Z-Stack主子系統(tǒng)運(yùn)行作為一個(gè)OSAL任務(wù)。 用戶運(yùn)行的應(yīng)用程序必須創(chuàng)建至少一個(gè)OSAL任務(wù)。 添加他們的任務(wù)到任務(wù)數(shù)組[tasksArr 定義在 OSAL_”Application Name”.c] 文件中,調(diào)用他們的應(yīng)用程序的初始化函數(shù)在osalInitTask()中。
樣例程序很清晰的展示了用戶如何添加一個(gè)任務(wù)到OSAL系統(tǒng)中。
2.1.3 Task Priority
這些任務(wù)執(zhí)行的順序是根據(jù)他們?cè)谌蝿?wù)數(shù)組中的位置[tasksArr in OSAL_”Application Name”.c]。 任務(wù)數(shù)組的第一個(gè)任務(wù)擁有最高優(yōu)先級(jí)。
2.1.4 System Services
OSAL 和 HAL 系統(tǒng)服務(wù) 是 鍵盤 (按下開關(guān)) 通知 和 串口活動(dòng)通知。系統(tǒng)服務(wù)是專一的, 也就是說,每一個(gè)都可以被注冊(cè)為一個(gè)單一的OSAL任務(wù)。 不同的系統(tǒng)服務(wù)可以通過相同的OSAL任務(wù)注冊(cè), 或者不同的OSAL 任務(wù)。 默認(rèn),任何的系統(tǒng)服務(wù)都沒有注冊(cè)Z-Stack任務(wù) – 他們都是留給用戶自己注冊(cè)。
2.1.5 Application Design
用戶可以一個(gè)應(yīng)用程序?qū)嵗齽?chuàng)建一個(gè)任務(wù)也可以所有的應(yīng)用程序?qū)嵗齽?chuàng)建一個(gè)任務(wù)。 以下是在進(jìn)行上述設(shè)計(jì)選擇時(shí)的一些考慮事項(xiàng)。
2.1.5.1 One OSAL Task per many Application Objects
以下是一個(gè)任務(wù)對(duì)應(yīng)多個(gè)App實(shí)例的優(yōu)點(diǎn)和缺點(diǎn):
優(yōu)點(diǎn): 在接收單一的任務(wù)事件(開關(guān)或串行端口)時(shí)所采取的操作被簡(jiǎn)化了。
優(yōu)點(diǎn): 許多OSAL任務(wù)結(jié)構(gòu)所需的堆空間被保存
缺點(diǎn): 當(dāng)接收到傳入的AF消息或AF數(shù)據(jù)確認(rèn)時(shí)所采取的操作是復(fù)雜的。
– 多路復(fù)用的負(fù)擔(dān)是在單個(gè)用戶任務(wù)上的。
缺點(diǎn): 匹配描述符請(qǐng)求(即自動(dòng)匹配)的服務(wù)發(fā)現(xiàn)過程更加復(fù)雜
–必須維護(hù)一個(gè)靜態(tài)的本地標(biāo)志,以便在ZDO_NEW_DSTADDR消息時(shí)正確地執(zhí)行
2.1.5.2 One OSAL Task per one Application Object
這個(gè)一個(gè)task對(duì)應(yīng)一個(gè)App對(duì)象的優(yōu)缺點(diǎn)剛好和上面的一個(gè)task對(duì)應(yīng)許多的App對(duì)象相反:
- 優(yōu)點(diǎn): 傳入的AF消息或AF數(shù)據(jù)確認(rèn)已經(jīng)取消多路復(fù)用靠協(xié)議棧的底層, 因此接收應(yīng)用程序?qū)ο笫穷A(yù)期接收方。
- 缺點(diǎn): 許多OSAL任務(wù)結(jié)構(gòu)所需的堆空間發(fā)生了
- 缺點(diǎn): 如果兩個(gè)或更多應(yīng)用程序?qū)ο笫褂孟嗤莫?dú)占資源時(shí),當(dāng)接收到一個(gè)單獨(dú)的任務(wù)事件時(shí)所采取的操作可能會(huì)更加復(fù)雜。
2.1.6 Mandatory Methods
任何的OSAL任務(wù)都必須實(shí)現(xiàn)2個(gè)方法:一個(gè)是任務(wù)初始化函數(shù)另一個(gè)是處理任務(wù)事件的函數(shù)。
2.1.6.1 Task Initialization
在樣例程序中,任務(wù)初始化的函數(shù)命名規(guī)則:zcl“Application Name”_Init (比如 zclSampleLight_Init())。任務(wù)初始化函數(shù)應(yīng)該完成以下:
- 初始化本地變量或相應(yīng)的應(yīng)用程序?qū)ο蟆?任何長期在堆內(nèi)存的變量應(yīng)該在這里分配空間,為了讓OSAL更高效的管理堆空間。
- 通過在AF層注冊(cè)來實(shí)例化相應(yīng)的應(yīng)用程序?qū)ο?#xff08;比如 afRegister())。
- 使用可適用的OSAL或HAL系統(tǒng)服務(wù)注冊(cè) (比如 RegisterForKeys())。
2.1.6.2 Task Event Handler
在示例程序中,事件處理函數(shù)的命名規(guī)則:zcl“Application Name”_event_loop (比如 zclSampleLight_event_loop())。任何OSAL任務(wù)都可以除了強(qiáng)制性事件之外,還可以定義15個(gè)事件。
2.1.7 Mandatory Events
一個(gè)任務(wù)事件,SYS_EVENT_MSG (0x8000),被保留,是OSAL 任務(wù)設(shè)計(jì)的。
2.1.7.1 SYS_EVENT_MSG (0x8000)
全局的系統(tǒng)消息發(fā)送通過SYS_EVENT_MSG,具體指定在ZComDef.h文件中。任務(wù)事件處理程序應(yīng)該處理以下這些全局系統(tǒng)消息的最小子集。建議處理以下消息應(yīng)該直接從樣例程序代碼學(xué)習(xí)或者研究樣例程序的程序流程。
2.1.7.1.1 AF_DATA_CONFIRM_CMD
這表明 每個(gè)over-the-air數(shù)據(jù)請(qǐng)求成功,通過調(diào)用AF_DataRequest()。ZSuccess確認(rèn)數(shù)據(jù)請(qǐng)求成功地通過無線傳輸。數(shù)據(jù)請(qǐng)求是用AF_ACK_REQUEST標(biāo)志設(shè)置的,然后ZSuccess確認(rèn)消息是在最終目的地成功接收。否則,ZSuccess只會(huì)確認(rèn)消息是成功地傳送到下一站。
2.1.7.1.2 AF_INCOMING_MSG_CMD
這是一個(gè)傳入的AF消息的指示
2.1.7.1.3 KEY_CHANGE
表明有按鍵活動(dòng)
2.1.7.1.4 ZDO_STATE_CHANGE
表明網(wǎng)絡(luò)狀態(tài)發(fā)生改變
2.1.7.1.5 ZDO_CB_MSG
這是發(fā)送到示例應(yīng)用程序的每一個(gè)注冊(cè)的ZDO響應(yīng)消息[ZDO_RegisterForZDOMsg]
2.2 Network Formation
作為一個(gè)協(xié)調(diào)器編譯的樣例應(yīng)用程序?qū)⒃谝粋€(gè)通道上形成一個(gè)網(wǎng)絡(luò),通過指定DEFAULT_CHANLIST。協(xié)調(diào)器將建立一個(gè)隨機(jī)的Pan ID基于自己的own IEEE地址或者通過ZDAPP_CONFIG_PAN_ID,如果它沒有定義為0xFFFF。作為路由器或終端編譯的樣例應(yīng)用程序設(shè)備將嘗試在DEFAULT_CHANLIST指定的一個(gè)通道上加入一個(gè)網(wǎng)絡(luò)。路由器將被限制只加入Pan ID定義。注意,獲得的結(jié)果是不確定的,由于 當(dāng)ZDAPP_CONFIG_PAN_ID沒有定義為0xFFFF,協(xié)調(diào)器和路由或終端設(shè)備 之間的行為是不同的。如果ZDAPP_CONFIG_PAN_ID定義為一個(gè)有效的值小于等于0xFFFE,那么協(xié)調(diào)器只會(huì)嘗試建立一個(gè)帶指定Pan ID的網(wǎng)絡(luò)。因此,如果協(xié)調(diào)器被限制為一個(gè)通道,指定的Pan Id已經(jīng)在該通道上建立了,新開始的協(xié)調(diào)員將會(huì)連續(xù)的變化,直到它達(dá)到一個(gè)惟一的Pan Id。新加入的路由器或終端設(shè)備將無法知道建立PanID的值,因此只會(huì)加入指定的Pan Id。同樣具有挑戰(zhàn)性的場(chǎng)景出現(xiàn)在 當(dāng)允許的信道掩碼允許多個(gè)通道,協(xié)調(diào)器不能使用第一個(gè)通道由于Pan ID沖突 — 路由器或終端設(shè)備將加入指定的Pan ID 在第一個(gè)channel 被scan,如果被允許的話。
2.2.1 Auto Start
一個(gè)設(shè)備將自動(dòng)開始嘗試形成或加入一個(gè)網(wǎng)絡(luò)作為BSP 啟動(dòng)序列的一部分。如果在連接之前,設(shè)備應(yīng)該等待計(jì)時(shí)器或其他外部事件,HOLD_AUTO_START一定要被定義。為了在以后的時(shí)間手動(dòng)啟動(dòng)連接過程,調(diào)用ZDOInitDevice()。
2.2.2 Network Restore
成功加入網(wǎng)絡(luò)的設(shè)備可以“恢復(fù)網(wǎng)絡(luò)”(而不是重置通過OTA信息)即使在失去電源或電池之后。這種自動(dòng)恢復(fù)可以通過定義NV_RESTORE或NV_INIT實(shí)現(xiàn)。
2.2.3 Join Notification
該設(shè)備被告知網(wǎng)絡(luò)形成或連接(或網(wǎng)絡(luò)狀態(tài)的任何變化)的狀態(tài),通過前面提到的ZDO_STATE_CHANGE消息。
2.3 Common Application Framework / Program Flow
本節(jié)描述所有樣本應(yīng)用程序通用的初始化和主任務(wù)處理概念。在 轉(zhuǎn)到樣例程序之前,應(yīng)該先閱讀本部分內(nèi)容。對(duì)于本節(jié)中的代碼示例,我們將使用SampleLightApp,在 Z-Stack Home已經(jīng)提供了。
2.3.1 Initialization
在系統(tǒng)啟動(dòng)和初始化期間,任務(wù)的初始化函數(shù)將被調(diào)用。這個(gè)函數(shù)的結(jié)構(gòu)如下所示,加上一些代碼示例:
zclSampleLight_TaskID = task_id;
任務(wù)ID由OSAL分配,并通過任務(wù)的init函數(shù)的參數(shù)賦予任務(wù)。應(yīng)用程序必須記住這個(gè)任務(wù)id,因?yàn)樗鼤?huì)在以后進(jìn)行自我觸發(fā) 通過使用OSAL定時(shí)器,事件,消息(比如 當(dāng)任務(wù)給它自己發(fā)送一個(gè)消息)。這種自我觸發(fā)通常是將長時(shí)間處理分割成更小的塊,然后在他們之間延期調(diào)用。這種“合作”行為允許其他任務(wù)共享CPU時(shí)間并防止“饑餓”.
zclHA_Init( & zclSampleLight_SimpleDesc );
這個(gè)SampleLightApp程序?qū)ο髮?shí)例化通過上面的代碼,這允許Af層知道如何路由到目標(biāo)profile/endpoint的數(shù)據(jù)包 — 它將通過發(fā)送一個(gè)OSAL SYS_EVENT_MSG 消息(AF_INCOMING_MSG_CMD)到任務(wù)來做到這一點(diǎn)。
RegisterForKeys( zclSampleLight_TaskID );
示例程序用上面的代碼注冊(cè) 按鍵通知的系統(tǒng)服務(wù)。
2.3.2 Event Processing
當(dāng)樣例應(yīng)用程序發(fā)生OSAL事件時(shí),事件處理函數(shù),將從OSAL任務(wù)處理循環(huán)中調(diào)用。任務(wù)事件處理程序的參數(shù)是一個(gè)16位位掩碼;在任何對(duì)函數(shù)的調(diào)用中都可以設(shè)置一個(gè)或多個(gè)位。如果設(shè)置了多個(gè)事件,那么它強(qiáng)烈建議一個(gè)任務(wù)只對(duì)其中一個(gè)事件采取行動(dòng)(可能最關(guān)鍵的一個(gè),幾乎總是,SYS_EVENT_MSG時(shí)優(yōu)先級(jí)最高的一個(gè))。未處理的事件將導(dǎo)致新的調(diào)用這個(gè)任務(wù)事件處理程序在所有其他處理程序之后都有機(jī)會(huì)處理它們的事件。
if ( events & SYS_EVENT_MSG )
{
MSGpkt = (afIncomingMSGPacket_t*)osal_msg_receive(zclSampleLight_TaskID );
while ( MSGpkt )
{
…
請(qǐng)注意,盡管建議一個(gè)任務(wù)只在可能的多個(gè)未決事件中的一個(gè)上執(zhí)行任務(wù)處理功能的調(diào)用,它也被推薦(并在示例應(yīng)用程序中實(shí)現(xiàn))處理所有可能出現(xiàn)的SYS_EVENT_MSG消息,所有這些消息都位于OSAL的“時(shí)間片”中。
switch ( MSGpkt->hdr。event )
建議一個(gè)任務(wù)實(shí)現(xiàn)SYS_EVENT_MSG消息可能類型的最小子集,這個(gè)推薦的子集如下所述:
case KEY_CHANGE:
zclSampleLight_HandleKeys ( ((keyChange_t *)MSGpkt)->state,
((keyChange_t *)MSGpkt)->keys );
break;
如果一個(gè)OSAL任務(wù)已經(jīng)注冊(cè)了按鍵通知,所有的按鍵將受到一個(gè) KEY_CHANGE系統(tǒng)事件消息。程序流程有兩種可能的路徑,它會(huì)導(dǎo)致一個(gè)任務(wù)接收到這個(gè)KEY_CHANGE消息。
從物理按鍵上產(chǎn)生的程序流如下所列:
- HAL發(fā)現(xiàn)了按鍵狀態(tài)(通過H/W中斷或者 H/W輪休 )
- HAL 的OSAL任務(wù)發(fā)現(xiàn)了 按鍵狀態(tài)改變?nèi)缓笳{(diào)用 OSAL 按鍵改變的回調(diào)函數(shù)。
- OSAL 按鍵改變回調(diào)函數(shù)將發(fā)送 OSAL 系統(tǒng)事件消息(KEY_CHANGE)到這個(gè)注冊(cè) 接受key change event(RegisterForKeys)通知 的Task ID。
case AF_DATA_CONFIRM_CMD:
// The status is of ZStatus_t type [defined in ZComDef.h]
// The message fields are defined in AF.h
afDataConfirm = (afDataConfirm_t *)MSGpkt;
sentEP = afDataConfirm->endpoint;
sentStatus = afDataConfirm->hdr。status;
sentTransID = afDataConfirm->transID;
任何對(duì)AF_DataRequest()的調(diào)用都會(huì)返回ZSuccess,這將導(dǎo)致“回調(diào)”
AF_DATA_CONFIRM_CMD系統(tǒng)事件消息。
發(fā)送的事務(wù)Id(sentTransID)是識(shí)別消息的一種方法。盡管示例應(yīng)用程序只會(huì)使用單個(gè)事務(wù)Id計(jì)數(shù)器,為每個(gè)不同的短點(diǎn)保留一個(gè)單獨(dú)的Transaction Id計(jì)數(shù)器可能是有用的 或者 即使是為了消息確認(rèn),端點(diǎn)中的每個(gè)集群ID也是如此,重試,拆開,在組裝,等。注意任何事務(wù)ID狀態(tài)變量(counter)通過調(diào)用AF_DataRequest()增長當(dāng)這個(gè)函數(shù)調(diào)用成功(因此,它是一個(gè)傳入?yún)?shù) 通過引用,而不是值傳遞)。
AF_DataRequest()的返回值是ZSuccess表示,這條信息已經(jīng)被網(wǎng)絡(luò)層接受,網(wǎng)絡(luò)層試圖將它發(fā)送到Mac層,Mac試圖將通過OTA發(fā)送。
發(fā)送的狀態(tài)(句子狀態(tài))是OTA這個(gè)消息的結(jié)果。ZSuccess表示 消息被傳送到網(wǎng)絡(luò)中下一跳的ZigBee設(shè)備。如果AF_DataRequest() 調(diào)用使用AF_ACK_REQUEST標(biāo)志,然后ZSuccess表示消息被遞送到目標(biāo)地址。除非消息的尋址模式是間接的(比如 消息被發(fā)送到網(wǎng)絡(luò)反射器來執(zhí)行
綁定表格查找并將消息重新發(fā)送到匹配設(shè)備),在這種情況下,ZSuccess表示消息被傳送到網(wǎng)絡(luò)反射器。有幾種可能的發(fā)送狀態(tài)值表示失敗。
case ZDO_STATE_CHANGE:
zclSampleLight_NwkState = (devStates_t)(MSGpkt->hdr。status);
if ( (zclSampleLight_NwkState == DEV_ZB_COORD) ||
(zclSampleLight_NwkState == DEV_ROUTER) ||
(zclSampleLight_NwkState == DEV_END_DEVICE) )
{
giLightScreenMode = LIGHT_MAINMODE;
。。。
}
break;
每當(dāng)網(wǎng)絡(luò)狀態(tài)發(fā)生變化時(shí),所有任務(wù)都會(huì)被通知系統(tǒng)事件消息ZDO_STATE_CHANGE
// Release the memory
osal_msg_deallocate( (uint8 *)MSGpkt );
請(qǐng)注意,OSAL消息系統(tǒng)的設(shè)計(jì)要求任務(wù)接受者釋放 為消息分配的內(nèi)存。
任務(wù)的事件處理函數(shù)應(yīng)該嘗試獲取下一個(gè)未決的SYS_EVENT_MSG消息:
// Get the next message
MSGpkt = (afIncomingMSGPacket_t*)osal_msg_receive(zclSampleLight_TaskID);
}
處理完一個(gè)事件后,處理函數(shù)應(yīng)該返回未處理的事件,比如 在處理完SYS_EVENT_MSG事件后,應(yīng)該返回以下內(nèi)容:
// Return unprocessed events
return ( events ^ SYS_EVENT_MSG);
}
總結(jié)
以上是生活随笔為你收集整理的Z-Stack Home Developer's Guide—2. Overview中文翻译【Z-Stack Home 1.2.0开发文档】的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux centOS基本配置搭建
- 下一篇: Android Studio 3.1.4