基於 STM32WB 系列創建製造特定集群ZCL

關鍵字 :STM32WBZCL

Exegin ZSDK(Zigbee 軟體設計套件)包含適於大多數現有集群的模板,可提供廣泛的功能。但某些應用仍需開發自定義集群模板。本文描述了此類自定義集群模板的開發過程,以及新ZCL集群的構建,構建方式與 Exegin ZSDK 集群的相同。

ZCL 集群架構

在介紹實現新 ZCL 集群的機制之前,有必要回顧一些 ZCL 的基礎知識和展示一個可供全文引用的具體示例。 Zigbee 集群庫(ZCL)定義了應用在節點之間通過網絡和空中進行交互的機制。用於特定目的的功能被整理 到“集群”中,該集合定義了一組相關的屬性和指令。例如,“開/關”集群定義了可開啟/關閉器件的功能。 下圖展示了一個網絡的兩個節點。節點 N 和 M 二者都支持位於端點 1 和 9 上的集群 OO(例如:開/關)。該功能在客戶端和服務器端之間進行拆分。在“開/關”樣例中,開關可作為客戶端,而燈可作為服務器。利用節點 N 端點 1 上的開關,控制節點 M 端點 9 上的燈。

        ZCL 基於 APS 消息構建,APS 消息又使用 NWK 層功能。ZSDK 包括可在其上 構建 ZCL 集群的通用服務。ZCL 集群模板[R5]在此類通用服務的基礎上構建。下圖展示了與應用和 ZSDK 協 議棧相關的 ZCL 結構。

ZCL 集群特定功能(例如在 ZCL [R2]或 ZSE [R4]規範的集群定義中定義的功能)在集群模板中實現,如圖 2. ZCL 應用結構黃色部分所示。 集群客戶端或者服務器應用,可通過在模板中填充設備特定的細節來完成。例如,在節點 N 端點 1 中填充如何訪問物理開關的細節,和在節點 M 端點 9 中填充一些如何訪問燈泡的細節。

屬性端到端操作順序

如下所示的客戶端應用樣例通過調用 ZCL 集群基庫函數 ZbZclReadReq(),從遠程服務器讀取屬性。由此提供 了需要調用的客戶端集群、讀取請求結構和回調函數,結果如下所示。

調用 ZbZclReadReq()會將 ZCL 屬性請求通過空中發送到服務器。該樣例使用綁定,並假設節點 N 在 OnOff 集群上包含從其本地端點 1 到節點 M 端點 9 的綁定。如果服務器集群支持所請求的屬性,則會在 ZCL 屬性讀取響應指令中返回該屬性的值。如果該屬性不存在,則以 UNSUPPORTED_ATTRIBUTE 狀態(0x86)返回 ZCL 默認響應。屬性在初始化期間添加到集群(強制屬性),或使用 ZbZclAttrAppendList()進行添加。在收 到 ZCL 讀取屬性響應時,回調會被調用。定義屬性的結構採用 struct ZbZclAttrT。屬性被初始化為這些結構的列表,並提供給 ZbZclAttrAppendList()以 附加到集群上。下面展示了服務器集群應用或服務器模板的樣例。



使用以下指令將其添加到集群中:

ZbZclAttrAppendList(cluster, attr_list, ZCL_ATTR_LIST_LEN(attr_list))

前面關於服務器集群應用或服務器模板的示例中,將屬性回調函數設置為了 NULL。在這種情況下,ZCL 集群 基庫使用該屬性在收到那一刻的值,對讀取請求進行響應。服務器應用通過 ZCL 集群基庫調用(如 ZbZclAttrIntegerWrite())更新本地值。服務器應用先前設置的值為響應讀取請求時使用的值。服務器應用通 過集群基庫實現了和客戶端訪問的解耦。 另一種方法是為服務器提供一個回調函數,如以下服務器集群應用樣例中所示。



在提供回調時,每當讀取或寫入屬性時都會調用服務器應用。實現方法是:在上述屬性定義中,設置 ZCL_ATTR_FLAG_CB_READ 和 ZCL_ATTR_FLAG_CB_WRITE 標誌。建議應用同時設置讀取標誌和寫入標誌並提供回調來處理所示的讀取和寫入,或者將回調設置為 NULL 但不設置這些標誌。在沒有回調的情況下,該值完全在協議棧中進行管理。在設置回調和兩種標誌的情況下,該值完全在應用中進行管理。儘管可行,但不建議在應用中對僅讀取或僅寫入請求進行處理,因為如果不仔細注意,讀取和寫入的值很可能不同。 一旦服務器調用完成,集群基庫就準備好響應消息,並通過無線方式將其發送回客戶端。在這個例子中,基庫發送的響應消息內容是讀的狀態和值,或者是寫的狀態。客戶端協議棧接收響應消息。客戶端的集群基庫處理 這個響應消息,如果有回調(比如上述例子中的 read_onoff_callback 函數)則將狀態、和讀過來的值一併包含在回調函數中,傳遞到上層。

當客戶端向服務器發送命令請求時,該過程類似於第 4 節“屬性端到端操作順序”中詳細介紹的端到端操作序列。然而,與使用 ZCL 基本函數發送命令不同,客戶端模板提供了一個特定於命令的請求函數,能夠處理該命令的ZCL負載。 表 2、表 3 和表 4 展示了客戶端向服務器發送 GetCalendar 指令請求的演示樣例。如果該操作成功,則會生成 PublishCalendar 響應返回到客戶端。

客戶端指令生成

GetCalendar 指令:



PublishCalendar 響應:



當客戶端應用決定請求日曆時,會發送 Get Calendar。這在以下集群客戶端應用樣例中展示。

 

如果 ZbZclCalClientCommandGetCalReq()的參數有效,則返回的狀態為 ZB_STATUS_SUCCESS,並嘗試 發送 GetCalendar 請求,如表 2. GetCalendar 指令所示。否則,返回錯誤狀態,而且不會發送請求。 當返回 ZB_STATUS_SUCCESS 時,回調函數將會被調用以指示客戶端嘗試的結果;如果結果是成功的,回調函數的參數中將包含服務器的響應消息。

該回調需要考慮規範中定義的服務器行為。對於某些 ZCL 請求指令,所需的響應為詳述的響應,如對上述 GetCalendar 請求的 PublishCalendar 響應。在其他情況下,ZCL 響應主要為一種狀態,有時帶有附加信息。當未定義 ZCL 消息響應時,ZCL 規範要求服務器返回通用默認響應消息。

此外,由於響應通過無線傳輸,因此客戶端請求可能存在以下狀況:

  • 服務器未收到
  • 服務器可能拒絕該請求或無法處理該請求
  • 或者該響應未到達客戶端

回調可以檢測到其中每種狀況,並根據需要採取適當的操作。應用的操作取決於這些可能狀況中的每一種以及應用的特定要求。

客戶端可採取以下操作:

  • 即發即棄
  • 重試
  • 或採取更激進的操作,如酌情重新加入或啟動頻率敏捷程序。

實際的選擇完全取決於應用的要求。

下面通過前述樣例,展示在回調中發送 ZbZclCalClientCommandGetCalReq()的可能客戶端結果。

  • 當 請 求 成 功 並 且 服 務 器 響 應 並 成 功 發 送 了 空 中 ZCL 消息時,rsp.status 的值為 ZCL_STATUS_SUCCESS。另外:
     a. 幀類型為 “cluster”,即( rsp.hdr.frameCtrl.frameType & ZCL_FRAMECTRL_TYPE ) == ZCL_FRAMETYPE_CLUSTE

     b.  ZCL 指令 ID 為響應的預期指令 ID。在這種情況下,預期為 Publish Calendar:rsp.hdr.cmdId == ZCL_CAL_SVR_PUBLISH_CALENDAR
     c. 執行這些檢查後,應用程序可使用提供的幫助程序函數來解析響應。在這種情況下,為了解析 Publish Calendar 響 應 , 應 用 程 序 可 使 用 有 效 負 載 rsp->payload 和 rsp->length 來調用 ZbZclCalClientParsePublishCalendar()

注意: 某些 ZCL 指令響應包含嵌入式狀態代碼,這些代碼也必須予以檢查。

       當請求成功,且無來自服務器的已定義 ZCL 消息響應,或者指令出現錯誤時,服務器將以“默認響應” 消息進行響應。與前述情況一樣,rsp.status 的值為 ZCL_STATUS_SUCCESS。另外:
      a.幀類型改為 ZCL_FRAMETYPE_PROFILE
      b. 並且指令 ID 為 ZCL_COMMAND_DEFAULT_RESPONSE
      c. 可使用 ZbZclParseDefaultResponse()解析默認響應
      d. 如果默認響應狀態並非 ZCL_STATUS_SUCCESS,則說明了來自服務器的指令響應失敗。

      注意: ZCL 消息的幀控制的“禁用默認響應”標誌通常置為 1,使得僅在無其他 ZCL 響應時,默認響應才會“成 功”。然而,如果置為 0,則始終發送默認響應,即使響應為 ZCL 消息時也是如此。

       3. 如果請求傳輸錯誤或如果服務器無響應,則 rsp.status 的值為 ZCL_STATUS_FAILURE。在這種情況下, 必須檢查rsp.aps_status 的值,該值包含 APS 或 NWK 層狀態代碼。一些樣例包括:
       a. aps_status 為 ZB_APS_STATUS_NO_ACK。這表明客戶端已成功發送請求,並且是在網絡級收到 該請求,但服務器並未在 APS 層確認收到。當服務器可以解釋請求但拒絕請求時,通常會發送帶 有上述錯誤狀態的默認響應。當服務器無法解釋消息時,例如:

  • 服務器上不存在目標端點
  • 或者消息不符合最低安全/加密要求
  • 服務器不確認或無法確認收到
  • 未發送APS層確認。

       然後發生超時,並向應用返回 ZB_APS_STATUS_NO_ACK aps_status。
       b. 如果在發送請求時,客戶端甚至無法到達路由中的 下一跳 , 則 aps_status 變 為 ZB_WPAN_STATUS_NO_ACK。協議棧有幾個層次都內置了重傳機制,如果出現這種 aps_status, 則原因很可能是客戶端完全失去了與網絡的連接。

服務器端指令接收和處理

       當客戶端無線發送了 GetCalendar 請求並且服務器收到該請求時,協議棧收到消息(參見第 3 節中的節點 M),通過 NWK 和 APS 層傳遞到 ZCL 集群基庫。當應用創建該集群的實例時,集群模板中的代碼註冊模板 級指令處理程序和一組集群服務器應用回調,每個回調對應一個指令。



在上述集群模板樣例中,ZCL 集群基庫調用 zcl_calendar_server_command()回調,其中包含代碼可解包每個 支持的命令。對於不支持的指令,回調必須返回 ZCL_STATUS_UNSUPP_MFR_CLUSTER_COMMAND (或對於 ZCL 規範[R2]中定義的集群而言,則返回 ZCL_STATUS_UNSUPP_CLUSTER_COMMAND)。這 些返回碼觸發 ZCL 集群基庫將相應的默認響應發送回客戶端。

否則,當支持該指令時,集群模板指令處理程序會將ZCL指令有效負載解析為 struct ZbZclCalClientGetCalendarT 數據結構,並調用所提供的集群服務器應用 get_calendar()回調。 對於 GetCalendar 指令,get_calendar() 回調負責確定哪些日曆與請求 ZbZclCalClientGetCalendarT *req 中 的條件匹配,並通過調用 ZbZclCalServerSendPublishCalendar()返回匹配的日曆。實施時會形成 ZCL PublishCalendar消息並將其返回給客戶端。然後,該服務器回調退出,以 ZCL_STATUS_SUCCESS_NO_DEFAULT_RESPONSE 結束服務器端業務,並通知 ZCL 集群基庫其已發送 響應(ZCL PublishCalendar),且必須僅在需要時發送“成功”默認響應。

如果集群服務器應用回調成功,但未發送“ZCL 消息”響應,則回調應以 ZCL_STATUS_SUCCESS 結束, 生成“成功”默認響應。否則,必須返回不成功 ZCL_STATUS,並始終生成具有相應狀態代碼的默認響應。 然而,在實施 ZCL 規範時,只有規範所述的狀態代碼才必須返回。

詳細文檔說明,可參考以下鏈接:

https://www.st.com/content/ccc/resource/technical/document/application_note/group1/cd/07/0c/7e/ee/b3/46/b9/DM00704235/files/DM00704235.pdf/jcr:content/translations/zh.DM00704235.pdf

★博文內容參考自 網站,與平台無關,如有違法或侵權,請與網站管理員聯繫。

★文明上網,請理性發言。內容一周內被舉報5次,發文人進小黑屋喔~

參考來源

false: https://www.st.com/content/ccc/resource/technical/document/application_note/group1/cd/07/0c/7e/ee/b3/46/b9/DM00704235/files/DM00704235.pdf/jcr:content/translations/zh.DM00704235.pdf

評論