1. Matter介紹
Matter(以前稱為 Project Connected Home over IP 或 Project CHIP)是由CSA聯盟制定的一個應用層面的標準,旨在打造一個統一的智能家居應用標準,以消除智能家居市場的碎片化。在Matter出來之前,智能家居市場是比較混亂的,每一個生態都有自己的協議,比如蘋果有自己的 Homekit,Google有自己的Weave,亞馬遜有自己的Echo,ZigBee聯盟有自己的Zigbee,這種割裂讓設備商很頭疼,他們需要為不同的生態制造不同的設備,最終用戶也很頭疼,他們需要學習各種生態的智能家居設備的使用方式。為此CSA提出了Matter技術,以打造一個統一的標準,讓一個設備可以在各個生態中工作,并給最終用戶呈現統一的使用界面。
需要說明的是,Matter只是一個應用標準,它的傳輸是建立在支持IPv6的TCP和UDP協議上的,Matter不對傳輸層進行約定,Matter也不對網絡進行約定,但是Matter約定了只能使用Thread/Wi-Fi/Ethernet三種連接協議。Thread協議由Thread Group制定,所以Matter over Thread產品必須通過Thread Group的認證。Wi-Fi則由Wi-Fi聯盟進行規范,所以Matter over Wi-Fi產品必須通過Wi-Fi Alliance認證。
為了讓Matter產品加入Matter網絡,需要一個配網的過程,Matter支持三種類型的配網方式,而低功耗藍牙則是首選配網方式,所以Matter產品一般都會要求支持低功耗藍牙功能。
Matter技術包含了三份規格書及其他要求文檔,大家可以從以下鏈接獲取Matter技術規范:https://csa-iot.org/developer-resource/specifications-download-request/
其中Core specification是它的核心規范,Application cluster specification對Matter組件cluster進行了詳細規定,Device library specification則是對設備層面的一些約束和規定。
不像藍牙和Wi-Fi,即使你不過認證,也照樣可以使用藍牙和Wi-Fi技術。由于Matter采用了PKI技術,而且它又是一個應用規范,你要使用Matter技術,必須通過Matter認證。為此CSA提供了多種資源幫助大家學習了解Matter,大家可以參考如下資源網站:https://csa-iot.org/developer-resource/specifications-download-request/
Matter是一個非常復雜而又現代的標準,但是短短4年時間,Matter就實現了從提出到落地到追捧的成績,不得不說這是一個“Matter奇跡”。下面我們一起來了解一下這個“奇跡”的更多細節。
1.1 Matter架構
如下展示了Matter協議棧在整個系統中的位置,可以看出Matter就是一個應用協議。
Matter協議棧本身又是由application, data model, interaction model, action framing, security, Message Framing and Routing和Transport and IP Framing組成,如下:
Application
Application層定義最終產品的業務邏輯。例如,對于門鎖應用程序,業務邏輯可以根據來自特定語音命令來打開和關閉門鎖。它還可以定義用PIN碼開鎖或者LED反應等。
Data Model
Data Model層用來描述Matter節點支持的遠程操作,這里面主要運用了attributes, commands和events三個Matter概念,我們把相應的attributes,commands和events組合,就成了Matter設備里面的一個基石:cluster。Cluster本身是一個抽象的概念,用來定義一個一個的Matter設備,具體定義可參見之前的:Matter Application Cluster Specification。正因為有了cluster,才能讓用戶快速開發出自己的Matter產品,同時保證互聯互通。
Interaction Model
Data Model層對數據進行了抽象,而Interaction Model層則用來定義節點與節點之間如何交換數據。通俗地講,Interaction model就是用來規定交互命令集的,我們把發起交互的節點叫initiator (一般都是client設備),而接收者稱為target (一般為server設備)。
Action Framing
Action Framing層用來把Interaction Model層的命令轉成serialized格式。
Security
Security層把上面的數據進行加密并添加MAC。
Message Framing and Routing
這層主要把包頭添加到數據中,組成一個真正的包。
Transport and IP Framing
這層把數據傳輸到對端,主要是利用TCP或者UDP協議,同時Matter定義了Message Reliability Protocol (MRP)協議,用來信息確認,重傳和拒絕重復信息。如前所述,在配網(commissioning)過程中,通信是建立在Bluetooth Transport Protocol (BTP)協議之上。
1.2 Matter拓撲結構
Matter可以同時支持Wi-Fi/Thread/Ethernet,也就是說Matter可以讓不同網絡中的設備進行互聯互通通信,這個主要是指Thread board router 可以實現Wi-Fi和Thread通信互轉。不僅如此,Matter還允許接入其他網絡設備,比如ZigBee設備,這主要通過一個Matter bridge設備來實現。在Matter拓撲結構中,還有一個節點非常重要:Matter controller,Matter controller用來完成配網和遠程控制設備,比如蘋果的HomePod mini和Home app就是一個典型的Matter controller節點。如下為一個典型的Matter拓撲結構:
一般來說,一個Matter網絡稱為一個Fabric,共享同一個根操作證書的所有節點可以歸為同一個Fabric,簡單來說,一個生態就是一個Fabric(當然也可以包含多個),比如家里同時有蘋果Google亞馬遜的音箱,那么你可以認為你家里有三個Matter fabric,每個fabric是獨立的,但這里要強調的是,Matter支持一個設備接入多個fabric,也就是可以同時用蘋果Google亞馬遜控制同一個Matter設備,比如門鎖。
1.3 Matter數據模型(Data Model)和設備類型
如下為一個典型的data model表示:
Node
節點(Node)是一個邏輯上獨立的設備,有自己唯一的網絡地址。每個Matter設備由一個或多個Node組成。
Endpoint
一個Node包含多個Endpoint,每個endpoint是一個邏輯上獨立的功能模塊。比如門鎖,它除了可以包含門鎖這個endpoint外,它還可以包含溫度傳感器這個endpoint。
注意:endpoint 0預留為Matter的utility cluster,而且每個Matter設備都必須強制包含它。
Cluster
Endpoint由一個或多個cluster組成,cluster可以認為是一個基本功能集,它包含attributes, commands和events三個組件。比如前面說的門鎖endpoint,它除了可以包含開鎖/關鎖這個cluster外,它還可以包含報警cluster以實現報警功能。
Matter定義了兩種類型的Cluster:
Server –提供Attributes, Commands和Events
Client – 對Server發起交互(interaction)操作
Cluster的詳細規格定義請參見Matter Application Cluster Specification。如何通過cluster組成endpoint,進而組成設備類型,這個則是Matter Device Library Specification規定的內容。
Attribute
Attribute就是一條條表示物理量或者狀態的數據記錄,他們保存在設備的存儲器中。
Command
Command就是下文所說的action,用來觸發server的特定行為,比如關鎖命令用來觸發關鎖操作。
Event
Event其實是一種特殊的attribute,它用來更新設備的狀態,因此你可以把event當成是一種歷史數據記錄。
1.4 Matter交互命令和模型(Interaction Model)
通俗地講,Interaction model就是用來規定交互命令集的,我們把發起交互的節點叫initiator (一般都是client設備),而接收者稱為target (一般為server設備)。
Matter定義了如下interaction類型:
Read
用來讀取attributes或events的值
Write
用來修改attribute的值
Invoke
用來發送commands
Subscribe
用來訂閱target的數據報告,從而不用定時去查詢相關數據,我們可以訂閱attribute,也可以訂閱event。
Interaction本身由transaction組成,而transaction又由action組成,每個action包含1條或者多條信息,如下:
下面我們以門鎖為例子來具體講講interaction模型。
1.4.1 Interaction例子:門鎖
下面例子假設initiator為Matter controller,target為door lock。
Read interaction
如下為讀取DoorLock cluster 中的LockType attribute 的交互圖:

Write interaction
如下為修改DoorLock cluster 中的OperatingMode attribute的交互圖(修改為privacy模式意味著門鎖只能從建筑內打開):

Invoke interaction
如下為調用DoorLock cluster的UnlockDoor command的交互圖,其中Timed request用來定時命令的有效時間,為可選項。

Subscribe interaction
如下為訂閱DoorLock cluster 的LockState attribute狀態值的交互圖,這是一個持續進行的交互,除非一方停止或者返回失敗。
1.5 Matter網絡安全
Matter使用128-bit AES-CCM 算法來加密數據,為了得到AES密鑰,根據兩種不同的應用場景,Matter定義了兩種會話(session)建立方式:Passcode-Authenticated Session Establishment (PASE)和Certificate-Authenticated Session Establishment (CASE)
1.5.1 PASE
PASE僅用于配網(commission)過程中,SPAKE2+算法通過8位passcode來建立一個安全通道,為了減輕設備端計算負擔,可以直接把離線計算好的SPAKE2+ Verifier用來驗證passcode。
1.5.2 CASE
CASE用于正常業務通信過程中,CASE是建立在前面配網成功基礎上的,配網成功后,節點會得到一個節點操作證書(Node Operational Certificate,NOC)。當兩個節點使用CASE進行通信時,他們的NOC必須共用同一個根證書,也就是他們必須屬于同一個Fabric。有了NOC,就可以使用SIGMA算法來得到前述AES密鑰了。
需要注意的是,Matter message包含如下元素:
Message Header – 會話和傳輸有關的信息
Protocol Header – Matter消息的語義規定
Payload – 真正的內容
雖然AES-CCM算法可以保證三個元素的完整性,但是只有Protocol Header和Payload會加密。
1.6 Matter網絡配網
Matter配網(commissioning)就是把一個設備加入Matter Fabric(也叫Matter操作網絡)的過程,此過程包含兩個角色:
Commissioner device,一般放在Matter controller中,用于發起配網過程。
Commissionee device,就是還未添加到Matter網絡中的設備。
為了完成配網,commissionee必須提供如下onboarding信息:
16-bit Vendor ID and 16-bit Product ID
12-bit device discriminator
27-bit setup passcode
8-bit Discovery Capabilities Bitmask
上面這些信息可以以下面三種方式提供:
手動配對碼(Manual Pairing Code)
二維碼(QR Code)
QR Code Payload
雙方必須支持Manual Pairing Code,但推薦使用二維碼,當然各個生態系統也可以定義自己的discriminator和setup passcode。 配網流程如下圖所示:
如果上述配網流程成功,那么設備將得到如下信息:
由fabric ID和node ID組成的實例名
Node Operational Certificate(NOC)
NOC對應的私鑰
Access Control List
操作網絡的其他信息
1.7 Matter重要概念介紹
1.7.1 Matter Node(節點)
Matter node就是一個Matter設備的實例,一個Matter設備有可能包含一個或多個node,每個node通過64bit的node id來標識。我們也可以把不同的node組成一個group,并用16bit的group id來標識。
1.7.2 Matter controller(控制器)
Matter controller也是Matter網絡的一個節點,它可以遠程配置和控制附件設備,如下為兩種典型的controller。
PC機中我們常見的controller就是CHIP Tool,當然Android或者iOS也支持CHIP Tool,開發者在調試Matter設備的時候,用得最多的就是CHIP Tool,如何在各大平臺中配置和使用CHIP Tool,大家可以參考:
https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/protocols/matter/getting_started/testing/index.html#ug-matter-gs-testing
對于商用Matter生態系統,controller是一個組合體,比如蘋果Matter生態,它的controller應該是iOS里面的Home app和HomePod音箱的組合體。
1.7.3 Matter Fabric(網絡)
一個Matter Fabric就是一個Matter網絡,一個Matter Fabric中的所有節點共享同一個根證書,所以他們可以相互通信,每個Matter Fabric會分配一個64bit的ID進行標識。一般來說,一個Matter生態就是一個Matter fabric,比如蘋果的Home就是一個fabric,谷歌的home又是另一個fabric。
1.7.4 Multi-fabric/multi-admin接入多生態
一個Matter node(節點)可以接入一個Matter fabric,也可以同時接入多個Matter fabric,比如同時被蘋果/谷歌/亞馬遜的音箱控制,這個特性就稱為multi-fabric或者multi-admin。Multi-fabric將保證不同的生態可以相互兼容,提高Matter應用的互聯互通性能。
1.7.5 Matter bridge
智能家居是一個非常碎片化的市場,除了Matter技術外,還有很多其他技術運用在智能家居市場中,比如藍牙和ZigBee。為了將這些現有的智能家居產品一攬子接入Matter生態,Matter規范里面提出了Matter Bridge這個設備類型,通過Matter bridge,我們可以把非Matter設備快速接入Matter生態。如下網絡拓撲結構演示了如何將一個藍牙燈泡接入Matter網絡,然后Matter controller像控制正常Matter設備一樣去控制它。
1.7.6 Matter標準OTA
Matter規范要求設備必須支持設備升級功能,雖然Matter定義了一整套設備升級標準,但Matter沒有強制規定設備必須采用這套標準的OTA升級方式,也就是說設備也可以采用其他方式來升級,比如使用基于藍牙或者Wi-Fi的SMP方式進行升級。
Matter標準OTA定義了兩個角色:OTA Provider和OTA Requestor,OTA Provider和OTA Requestor都是cluster,因此他們都有client和server角色之分,要升級固件的設備叫OTA requestor,而提供固件的設備(比如controller)叫OTA provider。
1.7.7 Distributed Compliance Ledger(DCL)
通俗地說,DCL是CSA運營的一個分布式數據庫服務器,既然DCL是一個記賬簿,它不會不斷地更新和發展的。每當成員公司有新品發布,他們就會把這個新品的認證信息寫到DCL中。如果頒發了新的PAA證書,這個信息也會寫入DCL中。前面提及的Matter標準OTA,新image的URL信息也可以寫入到DCL中。CSA也可以撤銷或者作廢DCL中的一些證書或者認證信息。總之,DCL就是一個分布式數據庫服務器,保證了PKI系統的正常運行,同時也保證了Matter各個生態的互聯互通。
1.7.8 Certificate Declaration(CD)
每當一個產品通過了Matter認證,CSA就會頒發一個CD證書給它,CD證書包括Vendor ID,Certificate ID,certification type等,由于一個產品類別下所有設備共用同一個CD,因此CD都是hard code在應用中的。
2. 支持Matter的nRF設備介紹
2.1 Matter over Thread nRF設備
Nordic支持Matter over thread應用的SoC主要包括nRF5340和nRF52840兩款。
2.1.1 nRF5340主要特性
帶1 MB 閃存和 512 KB 內存的128/64 MHz Arm Cortex-M33 應用處理器
帶256 KB 閃存和 64 KB 內存的64 MHz Arm Cortex-M33 網絡處理器
低功耗藍牙
藍牙測向
Matter
Bluetooth mesh, Thread, Zigbee
ANT
高級安全性
USB, QSPI, HS-SPI
105 °C 擴展工作溫度
1.7-5.5 V 電源電壓范圍
開發nRF5340應用時,在nRF Connect SDK中選擇的開發板類型為:
nrf5340dk_nrf5340_cpuapp。
2.1.2 nRF52840主要特性
64 MHz Arm Cortex-M4 帶FPU
1 MB閃存 + 256 KB RAM
低功耗藍牙,藍牙mesh
2Mbps
2.4 GHz 收發器
ANT, 802.15.4, Thread, Zigbee
長距離
+8 dBm 發射功率
-95 dBm 靈敏度
支持IEEE 802.15.4無線電
Matter
Thread
Zigbee
1.7V至5.5V供電電壓范圍
全速12 Mbps USB
NFC-A tag
PWM
UART, SPI, TWI, PDM, I2S, QSP
高速 32 MHz SPI
Quad SPI 接口32 MHz
12位/200 ksps ADC
128位 AES CCM, ARM CryptoCell
USB 2.0
開發nRF52840應用時,在nRF Connect SDK中選擇的開發板類型為:
nrf52840dk_nrf52840
2.2 Matter over Wi-Fi nRF設備
要實現Matter over Wi-Fi應用,需要同時使用nRF5340和nRF7002/nRF7001兩款芯片,nRF7002/nRF7001是Wi-Fi 6協同IC,他們只運行Wi-Fi有關的MAC層,Matter的其他部分還是跑在nRF5340上。
2.2.1 nRF7002主要特性
Wi-Fi 6站點(STA)
2.4 GHz和5 GHz雙頻段
符合802.11a/b/g/n/ac/ax標準
用于物聯網的低功耗安全Wi-Fi
與低功耗藍牙的理想共存
目標喚醒時間(TWT)
SPI / QSPI
1個空間流(SS)
20MHz通道帶寬
64 QAM (MCS7),86 Mbps PHY
OFDMA(下行鏈路和上行鏈路)
BSS著色
共存接口
nRF Connect SDK提供支持
開發nRF5340+nRF7002應用時,在nRF Connect SDK中選擇的開發板類型為:
nrf7002dk_nrf5340_cpuapp。
2.2.2 nRF7001主要特性
nRF7001跟nRF7002功能差不多
但它只支持2.4G頻段
不支持5G頻段。
3. nRF Connect SDK和Matter SDK
開發Matter應用,你可以選擇Nordic自己的SDK:nRF Connect SDK來開發,也可以選擇Matter官方SDK:Matter SDK來開發。其實兩套SDK基本上差不多,并且是相互包含的關系,也就是說,nRF Connect SDK里面已經包含了Matter SDK,站在nRF Connect SDK角度來看,Matter SDK就是它的一個模塊。
同樣,Matter SDK里面也包含了nRF Connect SDK,站在Matter SDK角度來看,nRF Connect SDK就是它的一個模塊。由于兩者的互包含關系,導致兩者的版本無法同步,也就是說,當nRF Connect SDK開始下一個版本開發的時候,它會鎖定Matter SDK一個版本,比如nRF Connect SDK v2.5.0開發的時候,由于Matter SDK v1.2.0.0還沒有發布,因此它鎖定的版本就是Matter SDK v1.1.0.1;同樣當Matter SDK v1.2.0.0開始開發的時候,由于nRF Connect SDK v2.5.0還沒有發布,因此它鎖定的版本就是nRF Connect SDK v2.4.0。
這就導致一個現象,Matter SDK鎖定的nRF Connect SDK版本總是落后于Nordic最新版本,nRF Connect SDK鎖定的Matter SDK版本也總是落后于Matter官方最新版本。
如果你是做一個商業產品開發,強烈建議你使用nRF Connect SDK來進行開發,因為每個nRF Connect SDK版本的發布都會對Matter所有例子進行考核和測試,以保證他們的質量和穩定性,這也是為什么nRF Connect SDK會對Matter SDK打很多補丁以保證其質量。
而且nRF Connect SDK同時支持Windows/MacOS/Linux平臺,讓你不再局限于Linux開發平臺(經過一定修改后,我們也可以讓Matter SDK跑在Windows平臺,下文會對此進行介紹)。
如果你想測試Matter最新的特性,而這個特性nRF Connect SDK暫時又沒有,那么可以使用Matter SDK來進行開發和調試,待下版本nRF Connect SDK包含了該特性,你就可以直接移植過去,快速發布你的產品。
欲查看Matter SDK鎖定的nRF Connect SDK版本,大家可以打開這個文件:config/nrfconnect/.nrfconnect-recommended-revision,如下:
由于nRF Connect SDK會對它鎖定的Matter SDK版本進行修改,我們沒辦法一眼看出它鎖定的版本,但是大家可以從如下網站找到每個版本的nRF Connect SDK鎖定的Matter SDK版本以及它遵守的Matter規范版本。
https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/protocols/matter/index.html
| nRF Connect SDK version | Matter specification version | Matter SDK version |
|---|---|---|
| v2.5.99 (latest) | 1.2.0 | 1.2.0.1 |
| v2.5.2 | 1.1.0 | 1.1.0.1 |
| v2.5.1 | 1.1.0 | 1.1.0.1 |
| v2.5.0 | 1.1.0 | 1.1.0.1 |
| v2.4.3 | 1.1.0 | 1.1.0.1 |
| v2.4.2 | 1.1.0 | 1.1.0.1 |
| v2.4.1 | 1.1.0 | 1.1.0.1 |
| v2.4.0 | 1.1.0 | 1.1.0.1 |
| v2.3.0 | 1.0.0 | 1.0.0.2 |
| v2.2.0 | 1.0.0 | 1.0.0.0 |
| v2.1.4 | 1.0.0 | 1.0.0.0 |
| v2.1.3 | 1.0.0 | 1.0.0.0 |
| v2.1.2 | 1.0.0 | 1.0.0.0 |
雖然nRF Connect SDK和Matter SDK相互包含,但他們使用同一套工具鏈,而且這套工具鏈是伴隨nRF Connect SDK一起下載和安裝的,另外,不管你使用Matter SDK來開發Matter應用還是使用nRF Connect SDK來開發Matter應用,nRF Connect SDK都必須下載和安裝,下面我們會以nRF Connect SDK為主來講解Matter應用開發流程,然后在此基礎上再講解Matter SDK開發Matter應用的流程。
實際上,你只要熟悉了nRF Connect SDK開發流程,也就熟悉了Matter SDK開發流程,因為兩者幾乎一模一樣。
4. nRF Connect SDK開發環境搭建
關于nRF Connect SDK搭建和介紹,這里有一篇博文:
開發你的第一個nRF Connect SDK/Zephyr應用程序l,
推薦大家去看一下。下面我們會對博文內容進行濃縮,簡要介紹nRF Connect SDK。
4.1 前置安裝
在我們開始正式的開發環境配置之前,我們先需要下載如下三個工具:
Visual Studio Code:https://code.visualstudio.com/,這個就是我們的跨Windows/Linux/MacOS平臺的IDE工具。
nRF command line tools:https://www.nordicsemi.com/Software-and-Tools/Development-Tools/nRF-Command-Line-Tools/Download#infotabs,這個就是j-link驅動以及nrfjprog等Nordic提供的一些有用的命令行工具。
west,git和Python,這三個工具是可選的,不過大家手動安裝他們一下,某些場合還是蠻有用處的。請注意,即使大家沒有手動安裝這3個工具,Nordic工具鏈也會自動包含這三個工具,只不過大家使用工具鏈里面自帶的工具,會有一點麻煩,所以這里建議大家可以先手動安裝他們。
4.2 VS Code開發環境搭建
Microsoft Visual Studio Code(VS Code)是Nordic推薦的開發nRF Connect SDK應用的跨平臺IDE工具,所以nRF Connect SDK開發環境搭建都是在VS Code中進行的。
4.2.1 插件安裝
首先下載相應的插件。打開VS Code,進入Marketplace,搜索“nrf”,然后選擇“nRF Connect for VS Code Extension Pack”進行安裝,一旦nRF Connect for VS Code Extension Pack安裝成功,所有nRF插件都自動安裝成功。目前Nordic開發了如下nRF插件:
4.2.2 nRF Connect SDK安裝
由于nRF Connect SDK放在GitHub服務器上,下載和安裝nRF Connect SDK的時候請一定要使用VPN,否則很有可能就會下載不完整或者失敗。
上面的nRF Connect for VS code插件安裝成功后,點擊左邊的插件圖標,進入WELCOME面板,選擇Manage SDKs,
然后在右邊列表框中選擇Install SDK,
然后選擇相應版本的nRF Connect SDK,
請注意,如果你是一個新用戶,強烈建議你選擇最新版本,即列表里面版本最高的版本,上面是v2.5.0(截止本文第一次發表時),但是當你讀到這時,最高版本有可能已經到v2.6.0,v2.7.0,甚至更高,請選擇此時最高版本。(注意:*.*.99之類的版本是開發專用版本,不能用于量產)
選擇好版本后,然后選擇SDK安裝根目錄,一般使用默認推薦的目錄即可,如下。
大家千萬不要使用很長的目錄作為安裝根目錄,否則在Windows上編譯例子的時候,經常會碰到目錄名太長的編譯報錯。
然后VS code開始下載nRF Connect SDK,
下載完成之后,你就可以打開SDK所在的根目錄,
SDK在下載過程中,經常碰到下載不完整的情況,而且這種情況又不會報錯,為此我們可以通過下面的方式去檢驗nRF Connect SDK是否下載完整和正確,選擇Manage west workspace,然后選擇West Update,
如果nRF Connect SDK還缺少一些組件沒有下載完整,此時在OUTPUT窗口,你將會看到類似下面這樣的報錯信息:
如果nRF Connect SDK已經完整下載并正確,此時在OUTPUT窗口,你將會看到下面的信息輸出:
除了上述的VS code安裝成功確認方式,我們也可以通過目錄和命令行的方式來確認nRF Connect SDK是否完整安裝正確。
nRF Connect SDK和工具鏈安裝成功后,都放在Windows如下目錄里面:
打開CMD,進入相應SDK根目錄,然后輸入命令:git show,以確認安裝版本是否正確:
然后,我們可以手動輸入命令:west update,以同步nRF Connect SDK所有倉庫,從而確認SDK是否下載完整和正確,
如果最后沒有出現報錯信息,說明所有關聯倉庫都已經下載并同步成功,nRF Connect SDK已經下載完整和正確。
4.2.3 Toolchain安裝
nRF Connect SDK開發使用的Toolchain也可以通過VS Code直接安裝,上面的nRF Connect for VS code插件安裝成功后,點擊左邊的插件圖標,進入WELCOME面板,然后選擇Manage toolchains,在右邊的列表框中選擇Install Toolchain,如下:
根據你選擇的nRF Connect SDK版本選擇對應版本的Toolchain,比如nRF Connect SDK v2.5.0對應的Toolchain安裝如下所示:
然后開始下載Toolchain,
下載成功后,自動解壓和安裝,
如下為安裝成功的提示:
這里需要注意的是,Toolchain安裝可以不用VPN,但使用VPN可以讓安裝更穩定更可靠。
如果你PC里面有多個版本的Toolchain,你可以選擇任一版本作為當前版本,
4.2.4 安裝必須的Python腳本
nRF Connect SDK雖然已經預裝了大部分的Python腳本,但是Matter模塊里面有些Python腳本還沒有安裝。很多人電腦里裝了多個Python環境,怎么保證我們現在使用的Python環境是nRF Connect SDK v2.5.0 Toolchain自帶的?為了確保執行的是nRF Connect SDK Toolchain里面的Python,而不是操作系統環境變量中的Python,推薦大家使用VS code的終端來執行命令,即打開如下nRF Connect終端:

這樣就保證了該命令行的環境是nRF Connect SDK Toolchain設置的環境,在該終端中執行的任何命令都是針對nRF Connect SDK Toolchain環境來說的。
我們輸入如下命令:
pip3 install -r C:/ncs/v2.5.0/modules/lib/matter/scripts/setup/requirements.nrfconnect.txt
這樣系統就會自動補全nRF Connect SDK Toolchain缺少的Python包,如下所示:
4.2.5 zap工具安裝
nRF Connect SDK安裝成功后,我們就需要開始安裝zap工具,zap工具是用來添加/編輯/刪除前文所述的node/endpoint/cluster,因此它是一個必須安裝的工具。對nRF Connect SDK來說,zap工具的安裝是比較簡單的,Nordic特意提供了如下Python命令幫助大家安裝:
首先進入matter倉庫主目錄:
cd C:ncsv2.5.0moduleslibmatter
然后執行如下命令,其中“C:NordicToolszap-win-x64”是zap工具安裝的根目錄,大家也可以選擇其他目錄。
python scripts/setup/nrfconnect/get_zap.py -l C:NordicToolszap-win-x64 -o
zap工具安裝成功后,記得把C:NordicToolszap-win-x64這個目錄添加到操作系統的環境變量中。
至此,nRF Connect SDK開發環境已經搭好,下面我們來編譯一個例子來驗證一下開發環境是否真得搭成功了。
4.3 使用nRF Connect SDK編譯Matter例程
nRF Connect SDK使用CMakeLists.txt文件來表示項目,并通過CMake命令來取代傳統的通過GUI來添加源文件和目錄,使用Kconfig來配置項目以取代傳統的頭文件配置方式,使用DeviceTree來配置底層驅動文件以取代傳統的頭文件配置方式,如果大家對CMake/Kconfig/DeviceTree不熟的話,建議閱讀:開發你的第一個nRF Connect SDK/Zephyr應用程序l,以加深對nRF Connect SDK的理解。
Matter項目很大,編譯起來特別費時間,有時為了快速驗證你的開發環境是否搭好,大家可以跑一個簡單的例子,比如zephyr/samples/basic/blinky,以測試你的開發環境是否搭好。這里我們就不跑了,大家自己可以先測一下。下面我們為大家直接演示Matter例子是如何編譯和運行的。
我們以nrf/samples/matter/lock為例,詳細闡述如何使用nRF Connect SDK來編譯和運行Matter例子。nrf/samples/matter/lock是一個門鎖例子,同時支持Matter over Thread和Matter over Wi-Fi,如果你選擇nrf5340dk_nrf5340_cpuapp或者nrf52840dk_nrf52840,那么這個例子自動編譯成Matter over Thread應用;如果你選擇nrf7002dk_nrf5340_cpuapp,那么這個例子自動編譯成Matter over Wi-Fi應用。
下面我們以nrf52840dk_nrf52840為例(nrf5340dk_nrf5340_cpuapp和nrf7002dk_nrf5340_cpuapp跟它一模一樣,只需更換板子即可),來編譯和運行這個門鎖例子。
選擇APPLICATIONS標簽頁,選擇Open Existing Application,
選擇目錄:nrf/samples/matter/lock,
打開上述項目后,將自動跳出Add Build Configuration頁面,在Board列表框中,選擇開發板:nrf52840dk_nrf52840,
然后選擇Configuration選項,如果留空,默認選擇prj.conf,大家也可以選擇其他配置項。
其他一些配置項的說明如下所示:
選擇Build Configuration,開始編譯,視你的PC配置情況,編譯有可能耗時達10分鐘之久,編譯成功后,你將看到如下輸出:
整個VS code一覽圖如下所示:
至此,項目編譯成功,大家可以點擊“Flash”將代碼下載到板子里面,然后Matter應用就自動跑起來了,打開PC串口助手,你將看到如下輸出日志,說明Matter應用已經在正常運行了。
5. Matter SDK開發環境搭建
如前所述,搭建Matter SDK開發環境之前,必須先搭建好nRF Connect SDK開發環境,請大家先按照第4章的要求,搭建好nRF Connect SDK開發環境,然后再來讀這一章。
5.1 Matter SDK下載和安裝
5.1.1 Matter SDK下載
Matter SDK是放在GitHub上的,因此必須使用VPN來下載Matter SDK。
首先,打開CMD,進入c:/ncs目錄,然后輸入如下命令:
git clone https://github.com/project-chip/connectedhomeip.git
上面命令將把Matter SDK公共的倉庫都下載下來,而且自動切換到Matter SDK的master分支,如果你要切換到一個特定的tag,比如v1.2.0.1,請執行:
git checkout v1.2.0.1
由于Matter SDK支持眾多平臺和廠商,我們還需要下載這些第三方的倉庫,為此,我們再輸入如下命令:
cd C:/ncs/connectedhomeip/scripts python checkout_submodules.py --platform nrfconnect
上面的platform參數來指明下載哪個平臺或廠商的倉庫,如果沒有指明,說明下載所有平臺或廠商的倉庫,這個工作量是巨大的(目前是19GB左右),下載的時間也是很長的。上面的例子我們指明了nrfconnect平臺,這就意味著它只會下載Nordic Matter開發相關的倉庫,這個就小多了,大概1.5GB不到。
如果你之前已經安裝過Matter SDK,現在只是想更新到最新版本,那么使用下面命令即可:
git pull git submodule update --init
5.1.2 安裝缺少的Python模塊
然后我們還需要安裝缺少的Python模塊,這個是針對于nRF Connect SDK Toolchain來說的。nRF Connect SDK Toolchain是直接為nRF Connect SDK準備的,因此它不用做任何修改,就可以直接編譯nRF Connect SDK例子,但對Matter SDK例子,它有一些額外的Python模塊需求,因此我們需要將其補充完整。為了確保執行的是nRF Connect SDK Toolchain里面的Python,而不是操作系統環境變量中的Python,推薦大家使用VS code的終端來執行命令,即打開如下nRF Connect終端:

這樣就保證了該命令行的環境是nRF Connect SDK Toolchain設置的環境,在該終端中執行的任何命令都是針對nRF Connect SDK Toolchain環境來說的。
我們輸入如下命令:
pip3 install -r C:/ncs/connectedhomeip/scripts/setup/requirements.build.txt
這樣系統就會自動補全nRF Connect SDK Toolchain缺少的Python包,如下所示:
5.1.3 安裝合適的zap工具
雖然前面nRF Connect SDK開發環境搭建過程中,已經安裝好了zap工具,但是這個zap工具的版本有可能跟Matter SDK要求的zap工具版本不一樣,為此我們還需要再安裝一次期望版本的zap工具。
首先我們需要先確認zap工具的版本對不對,大家可以通過scripts/setup/zap.version這個文件確認:

這就意味著對Matter SDK v1.2.0.1來說,它需要的zap工具版本是v2023.10.24-nightly,然后大家可以到如下鏈接下載相應版本:https://github.com/project-chip/zap/releases,找到版本“v2023.10.24-nightly”,然后下載自己平臺的安裝包。

比如Windows,就下載zap-win-x64.zip這個壓縮包,下載成功后,解壓縮,將其放在某個目錄下,然后把該目錄添加到Path變量中,如下為我電腦上的解壓縮路徑和Path變量值:


如果你的PC安裝有老的zap工具,那么請記得把上面的環境變量一定要指向你剛剛解壓縮的目錄,而不是原來的值。另外原來的zap工具會在如下目錄生成一個緩沖文件:
為了更好的兼容性,大家可以把這個文件直接刪掉。
至此,Matter SDK已經下載和安裝完畢,下面我們就可以開始用它來編譯和運行Matter應用了。
5.2 編譯Matter SDK例子
5.2.1 Linux/MacOS平臺
原生的Matter SDK就支持Linux和MacOS平臺,因此你不要做任何修改,你就可以在Linux和MacOS上編譯Matter SDK例子,大家可以參考4.3節介紹的步驟,去編譯Matter SDK里面的例子,比如exampleslock-appnrfconnect,這個是Matter SDK里面自帶的門鎖例子。
5.2.2 Windows平臺
由于前面已經把nRF Connect SDK開發環境搭建好,我們可以直接使用nRF Connect SDK開發環境來編譯和運行Matter SDK例子,整個步驟跟前述的編譯運行nRF Connect SDK例子一模一樣。
5.2.2.1 修改Matter SDK以適配Windows平臺
由于原生的Matter SDK只能在Linux和MacOS上進行編譯,我們需要對原生的Matter SDK進行幾處修改才能直接在Windows上進行編譯,修改的地方如下所示:
在connectedhomeip/build_overrides目錄下,新建一個空文件,文件名為:pigweed_environment.gni。這個文件創建一次就可以,然后可以適用所有Matter工程。
修改一些編譯腳本。請大家將
https://patch-diff.githubusercontent.com/raw/project-chip/connectedhomeip/pull/30982.diff
對應的文件下載下來,命名為30982.diff,放在c:/ncs目錄下,然后執行
git apply c:/ncs/30982.diff
就可以自動修改相應腳本以支持Windows,如下:
注意:這個補丁是針對Matter SDK版本v1.2.0.1的,Matter SDK未來版本有可能會把這個PR合并進去,這樣這個補丁就沒有必要再打了。
修改每個項目的CMakelists.txt文件,只改一個地方:
把本項目目錄下的third_partyconnectedhomeip這個文件包含的內容直接取代CMakelists.txt中的變量connectedhomeip,即把../../../..取代connectedhomeip,使
get_filename_component(CHIP_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/third_party/connectedhomeip REALPATH)
這句話變成
get_filename_component(CHIP_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/third_party/../../../.. REALPATH)
5.2.2.2使用Matter SDK編譯Matter例程
如果你前面沒有選擇Matter SDK的版本,那么你首先要checkout一個你期望的版本,一般選擇一個tag來開發和測試,而且一般都是選擇最新的tag來開發和測試,如下圖所見,截止本文發表時,Matter SDK最新的tag是v1.2.0.1。

為此我們選擇v1.2.0.1這個tag來演示我們下面例子的編譯和測試。我們在CMD中輸入如下命令:
git checkout v1.2.0.1 git submodule update
我們還是以Matter SDK原生的lock例子為例:connectedhomeipexampleslock-appnrfconnect,來闡述整個編譯過程。
首先修改CMakelists.txt文件(前面說得pigweed_environment.gni這個空文件記得要先創建),得到:
然后像編譯nRF Connect SDK例子一樣去編譯這個lock例子。由于Matter SDK使用了nRF Connect SDK的工具鏈,因此我們必須要知道當前Matter SDK鎖定的nRF Connect SDK的版本是多少。查看Matter SDK要求的nRF Connect SDK版本,大家可以打開這個文件:C:ncsconnectedhomeipconfignrfconnect.nrfconnect-recommended-revision,如下:
說明它要求的nRF Connect SDK版本是v2.4.0,接下來我們就要在WELCOME標簽頁中選擇nRF Connect SDK v2.4.0以及對應的Toolchain,如下:

然后選擇Open Existing Application,找到目錄:connectedhomeipexampleslock-appnrfconnect,如下:
然后選擇開發板:nrf52840dk_nrf52840
然后選擇“Build Configuration”開始編譯,編譯成功后,將有如下輸出日志:
點擊Flash,將程序下載到開發板:
程序運行起來后,將有如下日志輸出:
按下Button4,設備就會開始藍牙廣播,表示已經做好配網準備,可以接入Matter生態了:
下面我們就會講解如何使用HomePod mini來測試Matter設備。
6. 使用蘋果HomePod mini測試你的Matter設備
不管是用nRF Connect SDK編譯的lock例程(4.3節),還是用Matter SDK編譯的lock例程(5.2.2.2節),編譯成功并運行后,他們的測試流程都是一樣的。
首先確保設備藍牙廣播已經開啟,日志有“advertising started”字樣,如果沒有開啟,請按開發板最后一個按鍵以激活藍牙廣播。
然后我們從日志中可以看到一個網址,如下:
https://project-chip.github.io/connectedhomeip/qrcode.html?data=MT%3A8IXS142C00KA0648G00
將上面網址拷到瀏覽器中,即可以得到配網用的二維碼,
目前Nordic所有例子默認都使用上面二維碼來配網,大家只要掃描上面二維碼就可以完成配網。
在開始下面的測試步驟之前,請確保你的HomePod mini和iPhone或者iPad連接同一個路由器,而且HomePod mini已經跟該iPhone或者iPad的Home app綁定好。
打開iOS設備上的Home app,點擊右上角的“+”,選擇Add or Scan Accessory,如下:

跳出下面的掃描窗口,將掃描窗口對準上面的二維碼,掃描成功后,配網真正開始。

大家也可以從日志看出,配網流程正在進行中,下面就是截取配網流程的一個小片段的日志:
過一會,iOS設備就會彈出如下對話框,這個是因為我們使用的是測試DAC證書和測試用PID等,請大家參考第8章如何獲取生產用的證書和ID等信息,這里我們選擇“Add Anyway”。

設備配網成功后,iOS設備會連續出現如下界面:
選擇這個設備所在的位置:

給這個設備取一個好記的名字:

如果是鎖設備類型,還需要設置它的訪問密碼:

設置一些自動化的場景:

最后顯示設備添加成功的界面,如下:

同時大家也可以從Home app的主界面看到這個添加成功的設備,如下:

除了從iOS設備上觀察設備是否添加成功,你也可以從日志輸出來佐證設備是否添加成功,設備添加成功后,你一般會看到如下紅色標注的日志:
設備添加成功后,我們就可以對設備進行各種操作,比如我們去開鎖,開鎖可以通過Home app直接操作,也可以通過語音Siri來操作,不過二者有點不一樣。通過Home app操作的話,你直接點擊如下圖標即可:

通過Siri可以發出開鎖命令,但是它無法開鎖,必須通過Home app確認才能開鎖(這個是出于安全考慮),即Siri發出開鎖命令后,Home app會收到如下確認信息,確認后才能開鎖:


關鎖操作相對安全一些,因此Home app和Siri都可以直接執行關鎖操作,Home app直接就關鎖成功,而Siri關鎖成功的同時會給Home app發一條消息,告知鎖已關閉,如下:

大家除了可以從iOS設備看到開鎖或者關鎖成功的界面,也可以從輸出的串口日志看到開鎖或者關鎖成功的標志,如下:
7. 開始你的Matter定制開發之旅
Matter開發主要包括兩方面的工作:一是Matter應用本身的開發,二是非Matter應用開發。Matter應用開發本質上就是cluster/endpoint/node的添加、編輯、刪除以及相關回調事件處理等,如前所述,這個需要通過zcl編輯工具zap來生成ember層的代碼,以及手動添加或者修改其他c++文件來實現,下面一一對此進行介紹。
下面例子我們是基于nRF Connect SDK v2.5.0例子:
nrfsamplesmattertemplate
來闡述的(v2.5.0是截止本文發表時的最高版本,對于讀者你來說,請選擇當下最新版本)。
如果你第一次接觸nRF Connect SDK,建議你先讀完這篇文章:
開發你的第一個nRF Connect SDK/Zephyr應用程序l,然后再往下看。
首先在VS Code的nRF Connect插件中重新選擇nRF Connect SDK v2.5.0和nRF Connect SDK Toolchain v2.5.0,如下:

然后選擇Create New Application,并選擇Copy a sample,
選擇例程放置在哪里,
選擇Add to Workspace:
然后就可以按照4.3節的做法來編譯這個例子,選擇開發板:nrf52840dk_nrf52840,
然后選擇Build Configuration,開始編譯,視你的PC配置情況,編譯有可能耗時達10分鐘之久,編譯成功后,你將看到如下輸出:
下面我們將在此例程基礎上,對其進行定制開發,開發的內容主要包括兩部分:一是添加Matter on/off light設備,二是添加藍牙LBS(LED和Button服務)服務,具體請見下文。
7.1 添加Matter On/Off Light設備
7.1.1 添加cluster
如前所述,我們可以使用ZAP來添加endpoint和cluster。首先我們確認zap版本是否正確(前面我們來回切換nRF Connect SDK和Matter SDK,有可能會導致zap版本混亂,這里有必要再次確認一下),輸入如下兩條命令進行確認:
cd C:\ncs\v2.5.0\modules\lib\matter python scripts/setup/nrfconnect/get_zap.py -l C:\Nordic\Tools\zap-win-x64 -o
ZAP工具安裝成功后,我們就可以用它來編輯zap文件,在我們這個項目里面,zap文件就是
C:/ncs/bulb/src/template.zap
template.zap是一個JSON文件,包含了應用所有的cluster,command和attribute。我們可以使用如下命令打開這個zap文件:
zap C:/ncs/bulb/src/template.zap --zcl C:/ncs/v2.5.0/modules/lib/matter/src/app/zap-templates/zcl/zcl.json --gen C:/ncs/v2.5.0/modules/lib/matter/src/app/zap-templates/app-templates.json
cmd窗口如下所示:
同時彈出ZCL窗口:
可以看出,例子目前只有Endpoint 0,選擇Endpoint 0,并選擇“Enabled Clusters”,我們可以看到這個Endpoint使能了哪些cluster,比如Descriptor cluster。
下面我們添加一個Endpoint以支持Matter On/Off Light設備,選擇“ADD ENDPOINT”,在彈出的對話框中,選擇“Matter On/Off Light”,如下:

請確認on/off cluster已使能,然后點擊配置圖標。
在彈出的對話框中,確認On/Off Attribute已經使能。
同時確認Off和On命令已使能:
至此,我們的endpoint和cluster就添加成功了。
但上面的添加操作只是修改了zap文件,對我們SDK沒有做任何修改。接下來,我們就要使用一個Python腳本將這個zap文件轉成相應的c++文件和頭文件,以讓這個修改操作可以編譯到我們的代碼中去。(大家也可以直接去創建相應的c++文件和頭文件,但這個過程比較枯燥和繁瑣,所以我們才引入了zap工具和相應的代碼轉換Python腳本)。
打開CMD,輸入如下命令:
cd C:ncsv2.5.0moduleslibmatter python ./scripts/tools/zap/generate.py C:/ncs/bulb/src/template.zap -t src/app/zap-templates/app-templates.json -o C:/ncs/bulb/src/zap-generated
至此,cluster已經添加到我們的應用中了。
7.1.2 修改項目代碼
添加完cluster后,我們還需要修改項目代碼,以讓新添加的設備真正可以工作起來。這個工作主要包括兩部分:
添加Matter stack回調函數,以處理controller發送過來的命令,比如開燈。這個主要通過覆蓋MatterPostAttributeChangeCallback()來實現
更新attribute數值,以讓Matter stack可以將最新的狀態或者event同步給controller。這個主要通過Clusters::OnOff::Attributes::OnOff::Set()之類的函數實現。
首先我們先實現MatterPostAttributeChangeCallback(),新建一個文件:src/zcl_callbacks.cpp,然后將如下代碼拷入:
#include "app_task.h"
#include
#include
#include
using namespace ::chip;
using namespace ::chip::app::Clusters;
void MatterPostAttributeChangeCallback(const chip::app::ConcreteAttributePath & attributePath, uint8_t type,
uint16_t size, uint8_t * value)
{
if (attributePath.mClusterId != OnOff::Id || attributePath.mAttributeId != OnOff::Attributes::OnOff::Id)
return;
AppEvent event;
if (*value) {
event.Type = AppEventType::TurnOnLED;
event.Handler = AppTask::TurnOnLEDHandler;
}
else {
event.Type = AppEventType::TurnOffLED;
event.Handler = AppTask::TurnOffLEDHandler;
}
AppTask::Instance().PostEvent(event);
}
本來代碼邏輯可以更簡單,當收到On命令時,調用sBulbLED.Set(true)開燈;收到Off命令時,調用sBulbLED.Set(false)關燈。但這種做法會影響Matter協議棧的行為,因此我們把sBulbLED.Set()操作扔到一個event queue中去執行,而AppTask正好有一個現成的sAppEventQueue,我們正好可以加以利用,這樣當收到On命令時,我們把TurnOnLED事件扔到Event queue,然后在AppTask主循環中取出該事件,并調用該事件的handler:TurnOnLEDHandler。Off命令的處理情況也類似。我們在app_task.cpp加入如下代碼:
void AppTask::TurnOnLEDHandler(const AppEvent &)
{
LOG_INF("TurnOnLEDHandler");
sBulbLED.Set(true);
}
void AppTask::TurnOffLEDHandler(const AppEvent &)
{
LOG_INF("TurnOffLEDHandler");
sBulbLED.Set(false);
}
其中sBulbLED定義如下:
LEDWidget sBulbLED;
我們同時在AppTask::Init()中對其做如下初始化:
sBulbLED.Init(DK_LED2); sBulbLED.Set(false);
然后不要忘了在app_task.h中聲明TurnOnLEDHandler和TurnOffLEDHandler,如下:
static void TurnOnLEDHandler(const AppEvent &); static void TurnOffLEDHandler(const AppEvent &);
為了讓AppTask可以處理上面的TurnOnLED和TurnOffLED事件,我們需要在app_event.h修改如下定義:
enum class AppEventType : uint8_t { None = 0, Button, ButtonPushed, ButtonReleased, Timer, UpdateLedState, TurnOnLED, TurnOffLED};
為了讓app_task.cpp訪問cluster attribute,比如Clusters::OnOff::Attributes::OnOff::Set(),需要加入如下頭文件:(注:本文我們并沒有調用Clusters::OnOff::Attributes::OnOff::Set(),但實際應用肯定會調用它的)
#include
最后我們把src/zcl_callbacks.cpp文件添加到CMakeLists.txt,如下:

然后我們就可以編譯了,成功后會有如下顯示信息:
7.1.3 測試
我們可以按照第6章的方式,測試這個新的Matter設備,這里就不再贅述了。設備配網成功后,iOS Home app將會看到如下設備:

操作燈泡的界面如下所示:

7.2 添加藍牙LBS服務(LED和Button服務)
在nRF Connect SDK中,Matter相關代碼都是用C++撰寫的,除此之外,其他代碼都是使用C代碼編寫的。兩者渾然一體,各自運行良好。
因此,我們只要參考nrfsamplesbluetoothperipheral_lbs這個例子,就可以把LBS服務加入到例子中。
首先我們把nrfsamplesbluetoothperipheral_lbssrcmain.c,改名為lbs.c,并拷貝到項目的src目錄下,即C:ncsbulbsrc。然后在CMakeLists.txt文件中添加此文件:

然后我們需要對lbs.c文件作幾處修改。首先main()函數已經被C++占用了,
我們需要把lbs.c里面的main()函數換成一個普通線程,為此,我們先定義一個靜態線程:
K_THREAD_DEFINE(ble_lbs_thread_id, 1024, ble_lbs_thread, NULL, NULL, NULL, 7, 0, 0);
然后把int main(void)改成:
int ble_lbs_thread(void)
由于在Matter應用部分我們已經調用了bt_enable(),dk_leds_init(),init_button(),bt_le_adv_start(),settings_load()等,因此我們把lbs.c中相關調用刪掉。實際上我們只需要bt_lbs_init()這一個初始化函數。
由于Matter應用和lbs.c中都使用了LED模塊,為了有一個更好的直觀效果,我們把lbs.c中的
#define RUN_STATUS_LED DK_LED1 #define CON_STATUS_LED DK_LED2
改成
#define RUN_STATUS_LED DK_LED4 #define CON_STATUS_LED DK_LED4
最后我們合并兩個項目的prj.conf文件,即把
CONFIG_BT_LBS=y CONFIG_BT_LBS_POLL_BUTTON=y
添加到項目的prj.conf文件中。
至此項目代碼修改完畢,我們可以編譯了,編譯成功后,下載代碼到板子中,打開手機app:nRF Connect,將看到如下廣播:

點擊“CONNECT”,連接成功后,我們將看到LBS服務,如下:

然后我們可以對LED這個特征進行操作:ON或者OFF,板子上的LED3將跟隨命令而變化。

7.3 C代碼與C++代碼混合編程
7.3.1概述
從上面例子大家可以看出,添加Matter設備的時候,我們使用的是C++代碼;添加藍牙LBS服務的時候,我們使用的是C代碼。一個工程中同時存在C和C++代碼,這是Matter應用一個非常突出的特性,這就要求我們既需要理解C語言代碼,也需要了解一定的C++代碼,所以Matter開發是一個比較復雜而富有挑戰的工作。
在Matter開發中,大家碰到一個很常見的問題是:如何讓C代碼調用外部C++代碼編寫的API,或者如何讓C++代碼調用外部C代碼編寫的API。
關于C++代碼調用外部C代碼API,前面其實已經出現過多次,這個跟C代碼調用C代碼API一模一樣,比如在app_task.cpp中,調用了如下外部C語言API:dk_buttons_init,k_msgq_get,k_timer_start等,可以看出跟普通調用幾乎沒有區別。
關于C代碼調用外部C++代碼API,這個處理起來就稍微復雜一些。如果C代碼只是調用一個全局的C++函數,那么我們需要把該函數申明為extern "C",然后就可以被C代碼調用了;但是C編譯器又不識別extern "C",因此我們一般在頭文件中使用如下申明:

其中start_lbs_adv()就是一個可以被C調用的C++函數。
還有一種情況,就是C要調用C++類里面的函數,這個時候我們就需要先獲得類對應的實例,然后通過實例去引用本實例自身的函數。如何獲得實例的引用是整個調用最關鍵的部分,好在Matter應用中,我們使用了Singleton(單例)模式,也就是說每個類只會創建一個靜態的全局實例,這也就意味著類函數調用跟全局函數調用差不多,通過這個靜態全局實例,我們就可以調用類里面任何公共(public)函數,比如類AppTask,它的靜態全局實例可以通過AppTask::Instance()獲得,得到這個實例后,我們就可以調用AppTask里面任何公共函數了,比如StartApp(),這樣完整調用例子就變成:AppTask::Instance().StartApp()。
由于我們不會去更改SDK任何原始代碼,我們需要建一個CPP文件作為橋梁去調用其他CPP文件里面的API,這樣就可以保證SDK原始的CPP文件不會動,我們只需要修改該新建的CPP文件就可以完成我們的目標。
下面我們結合實際應用場景來看看C和C++是如何相互交互的。還是以上面的工程為例,我們要添加兩項工作:一是增加LBS原始的廣播,二是當Button狀態變化時,通知到手機app。
7.3.2 C調用外部C++函數示例
本來啟動廣播直接調用bt_le_adv_start()即可,為了演示C調用外部C++ API,這次我們通過調用BLEAdvertisingArbiter::InsertRequest來實現。
首先我們新建兩個文件:lbs_adv.cpp和lbs_adv.h,在lbs_adv.h我們定義如下可以被C調用的C++ API:
#pragma once
#ifdef __cplusplus
extern "C"
{
#endif
void start_lbs_adv();
#ifdef __cplusplus
}
#endif
然后我們在lbs_adv.cpp中實現start_lbs_adv(),實現代碼如下所示:
/* * Copyright (c) 2021 Nordic Semiconductor ASA * * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause */ #include "lbs_adv.h" #include #include #include #include #include #include #include #include #include #include #include using namespace ::chip; constexpr uint8_t kAdvertisingFlags = BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR; constexpr uint8_t serviceData[] = {BT_UUID_LBS_VAL}; constexpr uint8_t name[] = "LBS_ADV"; void lbs_adv_started(int rc) { printk("LBS advertising started:%dn", rc); } void lbs_adv_stopped() { printk("LBS advertising stoppedn"); } void start_lbs_adv() { static std::array advertisingData; static std::array scanResponseData; static chip::DeviceLayer::BLEAdvertisingArbiter::Request lbsAdvRequest = {}; advertisingData[0] = BT_DATA(BT_DATA_FLAGS, &kAdvertisingFlags, sizeof(kAdvertisingFlags)); advertisingData[1] = BT_DATA(BT_DATA_NAME_COMPLETE, name, sizeof(name)); scanResponseData[0] = BT_DATA(BT_DATA_UUID128_ALL, serviceData, sizeof(serviceData)); lbsAdvRequest.priority = 2; lbsAdvRequest.options = BT_LE_ADV_OPT_CONNECTABLE; lbsAdvRequest.minInterval = 360; lbsAdvRequest.maxInterval = 500; lbsAdvRequest.advertisingData = Span(advertisingData); lbsAdvRequest.scanResponseData = Span(scanResponseData); lbsAdvRequest.onStarted = lbs_adv_started; lbsAdvRequest.onStopped = lbs_adv_stopped; chip::DeviceLayer::BLEAdvertisingArbiter::InsertRequest(lbsAdvRequest); }
可以看出start_lbs_adv()最終調用了Matter C++庫函數: BLEAdvertisingArbiter::InsertRequest()。
最后我們在lbs.c文件中調用start_lbs_adv(),這樣當Matter配網廣播超時之后,我們的LBS廣播就會自動啟動。為了更快地觀察到效果,大家可以把moduleslibmattersrcincludeplatformCHIPDeviceConfig.h中的CHIP_DEVICE_CONFIG_DISCOVERY_TIMEOUT_SECS定義做如下修改:
#define CHIP_DEVICE_CONFIG_DISCOVERY_TIMEOUT_SECS (3 * 60)
將編譯成功的代碼燒錄到板子,3分鐘超時過后,大家可以看到如下廣播:

同時串口日志會有如下顯示:

這個時候我們點擊“CONNECT”,連接這個設備,會發現設備只包含LBS服務,之前的CHIPoBLE配網服務由于超時已經被解除注冊了,如下:

7.3.3 C++調用外部C函數示例
現在我們完成第二個工作:當Button狀態變化時,通知到手機app。
這個工作在原始的peripheral_lbs例程中,是通過在button_changed回調函數中調用bt_lbs_send_button_state()實現,由于在app_task.cpp中我們已經實現了按鍵的回調函數:AppTask::ButtonEventHandler,我們將在AppTask::ButtonEventHandler中調用bt_lbs_send_button_state()來實現我們的目的。
首先在app_task.cpp中包含如下文件:
#include
然后直接在AppTask::ButtonEventHandler中調用bt_lbs_send_button_state(),如下:
至此,代碼已全部更改完畢。可以看出C++調用外部C函數的確比較簡單,沒有任何多余的操作。
再次編譯代碼,并將新程序燒錄到板子中。跟前面操作一樣,通過手機app:nRF Connect連上板子后,并使能Button特征對應的CCCD,然后我們按下或者松開板子上的按鍵1,手機app的Button特征值會跟隨一起變化,如下:

項目最終代碼大家可以從這里下載:
matter_bulb.zip
8. Matter產品量產注意事項
nRF Connect SDK或者Matter SDK例子默認配置都是開發者模式,這種模式是不能量產的。因此,在產品量產之前,我們還需要做一些額外的配置。
8.1 Matter認證(Certification)
純藍牙或者Wi-Fi產品,即使不通過認證,也是可以量產的,因為藍牙和Wi-Fi更強調他們的連接標準性。跟純藍牙或Wi-Fi標準不一樣,Matter是一個應用級別的標準,而且Matter使用了PKI技術進行鑒定(authenticate),這就意味著Matter產品必須經過認證(certification),才能確保產品的互聯互通性。
對于藍牙和Wi-Fi新產品認證,如果它完全繼承芯片原廠或者模塊商的認證,那么它是可以免除ATL實驗室的測試。對于Matter新產品,它必須經過ATL實驗室的測試,然后才能獲得認證證書。當然Matter也有快速認證,前提是你必須有一款產品已經獲得過認證,新產品是在已認證產品的基礎上做微小改動情況下,才能免除ATL實驗室的測試。
前面也提及過,過Matter認證之前,你必須先確保你的產品已經通過藍牙和Thread或Wi-Fi認證。而且要獲得產品認證資格,你還必須加入相關聯盟,這也會產生一定費用。
關于Matter認證的詳細說明,請參考:
https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/protocols/matter/end_product/certification.html。
Matter認證過程中,有一份PICS文件非常重要,這個需要你提交給ATL和CSA。關于如何生成自己產品對應的PICS文件,還是請參考上面鏈接。
8.2 生態系統的認證
獲得了Matter認證,就意味著你的產品跟所有Matter生態都是互聯互通的。由于種種原因,每個生態還有自己的認證,比如Google有Works with Google Home認證,Amazon有Frustration-Free Setup(FFS)認證。這些認證其實不是必須的,看大家的意愿去選擇要不要過這些認證。具體請見:
https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/protocols/matter/end_product/ecosystems_certification.html。
8.3 Certification Declaration(CD)固化
當你通過了CSA的Matter認證后,CSA會頒發一個CD證書給你。按照Matter規定,你每升級一次固件,都需要重做一次認證(這個認證是免費的哦),每重做一次認證,CSA都會頒發一個新的CD證書給你,然后你通過OTA把這個新CD取代老CD。
CD一個最重要的作用,就是在設備配網過程中,充當設備自證(Device Attestation)申明。因此我們需要把CD和固件一起燒入到設備中。最簡單的方法,就是定義一個宏,固化到固件中,但這種方法無法更新CD。
還有一種方法,就是把CD放在一個特殊Flash區域,比如Settings或者NVS區域,這樣我們就可以通過Settings或者NVS API更新它。更多細節請見:
https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/protocols/matter/end_product/configuring_cd.html。
8.4 如何獲取PAI和DAC證書/私鑰
DAC,全稱Device Attestation Certificate,即設備自證證書,DAC證書和DAC私鑰對每個設備來說都是唯一的,也就是大家常說的“一機一密”。PAI,全稱Product Attestation Intermediate,一般一個產品類別對應一個唯一PAI,每個產品下面有許許多多的設備,所以PAI是用來簽署前面的DAC證書的。
對于量產產品來說,你只能使用CSA認證過的CA機構簽發的PAI以及DAC公私鑰對,大家可以聯系CSA授權的CA機構去購買相應證書和密鑰。
在產品開發過程中,如果你不想使用SDK默認的測試證書,那么也可以通過chip-cert來生成自己的測試證書,具體請參見8.3節和8.5節的兩個鏈接里面的介紹。
8.5 Factory data燒寫
Matter產品量產的時候,有很多信息需要燒入到設備中,并且整個產品生命周期不再會改變,這些信息就稱為出廠數據(factory data)。對于Matter設備來說,前面所述的DAC證書,PAI證書,供應商ID,產品ID,序列號,配網信息等,都屬于出廠信息。
為了保證大家可以生成自己需要的factory data,以及把這些factory data正確燒入到設備中,nRF Connect SDK準備了兩個Python腳本:generate_nrfconnect_chip_factory_data.py用來生成JSON格式的出廠數據/配對碼/配對二維碼等,以及nrfconnect_generate_partition.py用來把前面的JSON文件轉成hex文件,這樣就可以通過nrfjprog等J-link工具把hex文件燒入到設備中。
具體來說,我們可以按照下面步驟來完成出廠數據燒寫工作:
在prj.conf中加入:
CONFIG_CHIP_FACTORY_DATA=y
然后重新編譯項目,待編譯成功后,將代碼燒錄板子中。
打開VS Code的nRF Connect終端,然后輸入如下命令:
cd C:ncsv2.5.0moduleslibmatter python scripts/tools/nrfconnect/generate_nrfconnect_chip_factory_data.py --sn "99887766554433221100" --vendor_id 65521 --product_id 32774 --vendor_name "Nordic" --product_name "MyLock" --date "2024-02-05" --hw_ver 1 --hw_ver_str "release" --dac_cert "credentials/development/attestation/Matter-Development-DAC-FFF1-8006-Cert.der" --dac_key "credentials/development/attestation/Matter-Development-DAC-FFF1-8006-Key.der" --pai_cert "credentials/development/attestation/Matter-Development-PAI-FFF1-noPID-Cert.der" --spake2_it 1000 --spake2_salt "U1BBS0UyUCBLZXkgU2FsdA==" --discriminator 0x666 --generate_rd_uid --rd_uid e2eb609c5a793e5e9de536c211246a2e --include_passcode --passcode 666888 --product_finish "matte" --product_color "black" --out "c:/ncs/bulb/factory_data.json" --schema "scripts/tools/nrfconnect/nrfconnect_factory_data.schema" --overwrite
注意:上面的DAC和PAI還是測試用證書,記得換成自己購買的證書。sn/vendor_id/product_id/vendor_name/discriminator/passcode/spake2_it/spake2_salt等等其他參數也需要按照你們的需求做相應調整。
日志如下所示:
確認configurationnrf52840dk_nrf52840(或者其他板子對應目錄)對應的pm_static.yml包含factory_data分區,并記下分區的起始地址,下面需要用到這個地址值。

然后在VS Code nRF Connect終端中執行如下命令:
python scripts/tools/nrfconnect/nrfconnect_generate_partition.py -i c:/ncs/bulb/factory_data.json -o c:/ncs/bulb/factory_data --offset 0xf7000 --size 0x1000
offset和size就是前面pm_static.yml文件中的address和size
執行結果如下所示:
把上述生成的出廠數據燒錄到設備中,這可以通過如下命令實現:
nrfjprog -f nrf52 --program c:/ncs/bulb/factory_data.hex --sectorerase --verify --reset
執行結果如下所示:
這時,觀察串口日志,我們發現設備的配網信息已發生改變,如下:

審核編輯 黃宇
-
Matter
+關注
關注
1文章
334瀏覽量
7147
發布評論請先 登錄
Matter 1.5 正式發布
打破智能家居生態壁壘,樂鑫一站式Matter解決方案實現無縫互聯
利用“Matter”實現智慧家居互聯的標準化
芯科科技2025年Works With開發者大會深圳站Matter技術專場前瞻
芯科科技探索Matter全方面應用解決方案
如何快速開發符合Matter標準的智能家居設備?
Matter相關術語的定義
芯科科技亮相2025 Matter開放日和開發者大會
Matter采用基于標準的無線技術
Matter 智能家居的通用語言
下一代物聯網:芯科科技和Arduino借助邊緣AI和ML簡化Matter設計和應用
2025 Matter如何變更好?
Nordic的matter是如何做的
通用Matter over thread 模組
恩智浦Matter部署中雙PAN IEEE802.15.4方案開發完整攻略
Matter開發,看這一篇就夠了
評論