Matter开发手册
概述
目前,泰凌已有多个芯片支持Matter协议。本文档以TLSR9528A为例,提供Telink Matter解决方案的完整指导,包括环境搭建、Matter设备固件构建和烧录、边界路由器设置(包括RCP构建和烧录)、chip-tool 的构建和使用等,帮助用户了解Telink Matter相关事宜,更好的体验Telink Matter应用的功能。
Matter概述
Matter的出现
-
困境
物联网(IoT)产品“碎片化”的问题不仅让消费者和开发者们头疼不已,也阻碍了家庭智能硬件产品的进一步发展。目前,主导物联网产品发展的科技巨头们,都有各自独立的智能家居生态系统,如Amazon Alexa、Apple HomeKit和Google Home等。
-
对于消费者
消费者在挑选智能产品的过程中,不仅需要关注产品的功能、特性和价格,还需要去考虑是否兼容家中已有的生态系统,这造成了选择上的困难以及使用中的不便。
-
对于商家
第三方开发者们在开发一款智能产品之前,也必须考虑该产品需要支持哪一种生态系统,以便于满足该产品目标用户的需求。如果开发者们不满足于将自己的产品限制于某一种生态系统中,想要满足不同的消费者的多样化的需求并拓展自己的市场占有率,他们可能需要改造已有的设备来支持更多的生态系统,或者重新开发支持更多智能生态系统的设备,而这两种选项都可能会让他们面临极大的困境。一方面,不得不花费更多的时间和精力去完成产品的软件层和不同智能生态系统的适配工作;另一方面,甚至需要为了满足某些生态系统的要求,去改动底层硬件或者外观的设计。
因此,各方都希望能形成一套共同接受并遵循的“标准”去解决以上的“碎片化”的问题,便于智能家居品牌和制造商的开发,同时也便于消费者的选择。为了满足这一共同需求,包括Amazon、Apple、Google等许多物联网生态系统构建者们,与Zigbee联盟走到了一起,在2019年12月宣布成立了Connected Home over IP(CHIP)项目工作组,致力于打造一个基于开源生态的全新智能家居协议。2021年5月,随着Zigbee联盟更名为连接标准联盟(Connectivity Standards Alliance),项目工作组协商制定出这个局域网内的应用层标准协议的初稿,并将CHIP改名为Matter。
Matter总览
Matter设备将工作在统一的应用层中,且仅仅依赖传输层中的IPv6标准所构成的TCP/IP和UDP协议,从而兼容不同的物理介质和数据链路标准。因为IP网络是一个Mesh结构,所以Matter也将呈现为Mesh拓扑结构(由不同通信技术的子网络组成)。
在计划于今年秋季正式发布的第一版Matter协议中,它将首先支持以Ethernet、Wi-Fi和Thread网络进行设备间通信;并利用蓝牙低功耗(BLE)技术作为Matter设备入网的通道,以简化Matter设备的配置步骤。其中,Thread协议基于IEEE 802.15.4技术,其网络中的设备无法直接与Wi-Fi或以太网设备通信,因此在Matter拓扑结构中需要增加Thread边界路由器,使Thread网络中的Matter设备与其他网络中的设备可以互联。比如,一个仅支持Thread网络的Matter设备,可以通过Border Router(如HomePod Mini),来和其他的仅支持Wi-Fi网络的设备(如iPhone)进行通信。
在Matter网络中,将拥有统一的数据模型和交互模型。Matter协议把网络当作共享资源处理,没有制定排他性的网络所有权和访问权,这就使得多个不同协议的网络可以共存于同一组IP网络中。在以往,两个智能设备需要处于同一个物理网络中的才可以实现互相通讯,而Matter协议将构建起多个虚拟网络,允许不同物理网络中的智能设备实现互相通讯。这里的一个虚拟网络是一群Matter设备的集合,被称作一个Fabric。在实现中,一个Fabric往往对应一个智能生态系统所构成的网络。
一个物理设备被叫做Node(相当于HomeKit中的Accessory),一个Node可以被加入到一个或多个Fabrics之中。Node下面用逻辑功能单元Endpoint来表示不同功能模块,比如下图中Endpoint 1和Endpoint 2表示一个空调的不同功能模块;Endpoint 0是必须保留的根端点,用来描述设备特性。Endpoint中用若干个Cluster(继承于Zigbee Cluster Library,ZCL)来表述具体功能,如开关、风力、温度测量和温度控制。而Matter设备之间的交互(Interaction),则是由一个设备的某个Endpoint和另一个设备的某个Endpoint之间的通讯来完成的。
除此之外,Matter协议所构建的网络还具有以下特性:
-
Multi-Admin,支持把Matter设备同时加入到不同生态系统中的能力,被不同Fabrics中的管理员(Administrator)所管理,从而实现广泛的兼容性。
-
通过分布式合规设备总账(Distributed Compliance Ledger, DCL)来共享Matter厂商及设备的信息。每个生态系统都可以向DCL查询Matter配网、OTA等过程中所需要的信息。
-
允许使用者在无需连接到云端的情况下,进行本地设备的控制。
-
已经大量存在的非Matter的智能设备,也有机会通过Matter Bridge设备被添加到Matter Fabric之中。这个Matter Bridge设备负责和非Matter设备通信,它会将非Matter设备虚拟成对应的Endpoint,就像一个Node里面有多个不同功能的Endpoints,从而让Matter网络中的Matter设备可以和非Matter设备实现通信。
Matter功能
Matter协议主要是面向智能家居市场,其主要支持的设备类型有:
-
照明、开关等照明设备
-
加热、制冷等空气处理设备
-
探测器、报警器等安全设备
-
门禁、门锁等进入控制设备
-
音箱、电视等影音娱乐设备
-
窗户、窗帘等采光通风设备
-
热点、网桥等网络中继设备
随着Matter协议的发展和演化,在未来还会支持更多的智能设备。
Matter的未来
Matter项目获得如此高的关注,并不仅仅是因为它概念和标准上的先进,而是源于三位智能家居巨头的承诺。在Matter项目立项之初,Amazon、Apple和Google就承诺使用该协议的设备将可以兼容他们的生态。在Matter协议推出之后,IoT产品的开发者们将能够做到一次开发同时支持多个生态系统(Amazon Alexa、Apple HomeKit和Google Home等)的接入协议,这将大大简化开发者的工作,使得智能设备能无缝地连接到任何Matter兼容的智能生态系统中。消费者也可以更容易地选购产品,而不用特别担心买到的设备和已有的生态系统的适配问题。
Telink Matter概述
泰凌微电子积极参与了Matter协议中的Matter设备的功能开发,Matter设备的测试与认证,以及Matter标准中文解读等方面的工作。作为致力于低功耗高性能无线连接SoC芯片解决方案的提供商,我们推出了基于TLSR9系列芯片的Matter Over Thread解决方案,可以用于开发Matter Thread终端设备。
Telink Matter目前支持的应用
⽬前Telink Matter⽀持的例程如下:
(1) connectedhomeip/example/lighting-app/telink
lighting-app灯泡应用
(2) connectedhomeip/example/ligth-switch-app/telink
light-switch-app开关应用
为了便于客户体验上述应用,我们提供了预制的lighting-app固件,light-switch-app固件和对应的chip-tool⼯具,可以在下⾯的微盘地址中找到:
https://drive.weixin.qq.com/s?k=AKwA0AfNAA8vmdyx0L
所使用到的仓库和分支
最新的Docker Image仍然在更新中,其中包含编译Matter应用所需要使用的Zephyr环境。如果您想要了解,可以查看:
https://hub.docker.com/r/connectedhomeip/chip-build-telink
Matter的custom branch分⽀telink_matter已经合并进了官⽅的master分⽀,因此可以使⽤以下仓库:
https://github.com/project-chip/connectedhomeip
硬件和工具准备
所需硬件和工具
(1) Telink评估板 作为Matter设备;
(2) Telink评估板 作为RCP;
(3) Raspberry Pi 4 作为边界路由的一部分,推荐使用4GB RAM版本;
(4) SD卡 给Raspberry Pi 4使用,至少需要16GB;
(5) 主机 PC 需要系统为Ubuntu v20.04 LTS,作为一个构建机器和Matter设备的主机;
(6) Telink烧录器 用于烧录Matter设备和RCP固件;
(7) Wi-Fi路由器 充当Wi-Fi接入点。
TLSR9528评估板介绍
按键功能
TLSR9528评估板上的四个机械按键布局和功能如下:
按钮序号 | 对应PIN脚 | 功能 | 描述 |
---|---|---|---|
SW2 | PD2 | 恢复出厂设置 | 按三下一号键,清除当前配网的Thread网络并返回未配网状态 |
SW3 | PD6 | 触发BLE广播 | 进入配网状态,设备开始BLE广播,进入可被发现的状态 |
SW4 | PD7 | 灯光控制 | 对于灯泡,可以手动控制开关灯。对于开关,可以控制连接灯泡的开关灯 |
SW5 | PF6 | 组建Thread网络 | 设备以默认配置加入Thread网络,仅用于测试目的 |
LED灯状态
白灯指示设备当前的网络状态:
状态 | 描述 |
---|---|
白灯短亮并闪烁 | 设备未配网于Thread网络,Thread未使能 |
白灯频繁闪烁 | 设备已配网,Thread使能,设备正在尝试加入Thread网络 |
白灯长亮并闪烁 | 设备已配网且已作为child加入Thread网络 |
红灯、绿灯表示灯的状态:
-
开
亮度0 - 255(最大值)
-
关
连接UART模块串口输出
UART模块可以帮助我们获得Matter设备的串口调试信息,我们可以按照以下管脚位置进⾏接线:
UART模块 | TLSR9528评估板 |
---|---|
TXD | PB3 (pin 1 of J3) |
RXD | PB2 (pin 22 of J3) |
GND | GND (e.g.pin 3 of J15 or pin 23 of J17) |
波特率:115200 Bits/second;
数据位:8;
校验位:None;
停止位:1。
供电方式
(1) 使用USB供电
- 插上图中红色框标注的跳线帽。
(2) 使用自带VBAT PIN脚进行供电
在没有USB线的情况下,TLSR9528评估板可以用自带PIN脚进行供电。
-
移除图中红色框标注的跳线帽。
-
J17的VBAT脚接入3.3V电源。
-
J17的GND脚接地。
体验Matter的实现和功能
环境搭建(手动)
安装 Zephyr 工程环境
在进行接下去的操作前,先执行 APT 更新和升级:
sudo apt update
sudo apt upgrade
(1) 安装依赖项
wget https://apt.kitware.com/kitware-archive.sh
sudo bash kitware-archive.sh
sudo apt install --no-install-recommends git cmake ninja-build gperf \
ccache dfu-util device-tree-compiler \
python3-dev python3-pip python3-setuptools python3-tk python3-wheel xz-utils file \
make gcc gcc-multilib g++-multilib libsdl2-dev
Zephyr目前要求的主要依赖项的最低版本为:CMake (3.20.0), Python3 (3.6), Devicetree compiler (1.4.6).
cmake --version
python3 --version
dtc --version
在进行下一步之前,请验证系统上安装的版本,否则请将APT镜像切换到稳定且最新的镜像,或手动更新这些依赖项。
(2) 安装west
pip3 install --user -U west
echo 'export PATH=~/.local/bin:"$PATH"' >> ~/.bashrc
source ~/.bashrc
确认~/.local/bin在 $PATH
环境变量上。
(3) 获取Zephyr源码
west init ~/zephyrproject
cd ~/zephyrproject
west update
west blobs fetch hal_telink
west zephyr-export
在中国大陆运行 west init 和 west update 来获取Zephyr源码通常会耗费额外的时间,此外,某些项目可能无法从外部服务器更新。
请寻找其他方法来下载最新的源码。
(4) 安装Zephyr所需额外的Python依赖
pip3 install --user -r ~/zephyrproject/zephyr/scripts/requirements.txt
(5) 安装toolchain
下载Zephyr toolchain(约1~2GB)到本地目录,在中国大陆可能会耗费额外时间。
执行以下命令下载Zephyr SDK v0.16.1:
wget https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.16.1/zephyr-sdk-0.16.1_linux-x86_64_minimal.tar.gz
验证下载的工具链的压缩包。
wget -O - https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.16.1/sha256.sum | shasum --check --ignore-missing
添加执行权限。
chmod +x zephyr-sdk-0.16.1_linux-x86_64.tar.gz
解压压缩包到指定路径。
tar xvf zephyr-sdk-0.16.1_linux-x86_64_minimal.tar.xz
可以在下列推荐的路径下载并安装Zephyr SDK:
$HOME/zephyr-sdk[-x.y.z]
$HOME/.local/zephyr-sdk[-x.y.z]
$HOME/.local/opt/zephyr-sdk[-x.y.z]
$HOME/bin/zephyr-sdk[-x.y.z]
/opt/zephyr-sdk[-x.y.z]
/usr/zephyr-sdk[-x.y.z]
/usr/local/zephyr-sdk[-x.y.z]
[-x.y.z]是您下载的SDK版本,例如:-0.16.1。
注意:在您安装好以后不能移动SDK文件夹。
仅安装riscv64的工具链。
cd ~/zephyr-sdk-0.16.1
./setup.sh -t riscv64-zephyr-elf -h -c
(6) 验证安装完成
在继续安装Matter工程环境之前,请先构建Hello World示例来验证Zephyr工程环境安装无误。
cd ~/zephyrproject/zephyr
west build -p auto -b <build_target> zephyr/samples/hello_world -d build_helloWorld
注意:build_target为您准备使用的开发板名称,例如:
tlsr9518adk80d
、tlsr9528a
。
在Zephyr根目录文件夹中用west build
命令构建 hello_world 示例,构建完成后可以在 build_helloWorld/zephyr 文件夹下找到名为 zephyr.bin 的文件。
(7) 将Zephyr的环境脚本加入Shell之中
注意:请将 zephyr 环境配置脚本追加到~/.bashrc中,否则你可能会在之后的构建中遇到
west build
错误。
echo "source ~/zephyrproject/zephyr/zephyr-env.sh" >> ~/.bashrc
然后执行以下命令让shell环境立刻更新:
source ~/.bashrc
(8) 添加Telink Zephyr远程仓库并拉取指定提交的源码。
cd ~/zephyrproject/zephyr
git remote add telink https://github.com/telink-semi/zephyr
git fetch telink develop
git checkout ef7bfc2214602ecf237332b71e6a2bdd69205fbd
cd ..
west update
west blobs fetch hal_telink
(9) (可选)如果您在已经完成了以上所有步骤后,想要切换到其它分支或commit,只需要执行以下命令:
git fetch telink
git checkout <your_target_branch_or_commitid>
cd ..
west update
west blobs fetch hal_telink
获取Matter源码
在此节中介绍的是获取Matter master分支上指定commit的步骤,与上一节中拉取的Zephyr代码相匹配。
(1) 安装依赖项:
sudo apt-get install git gcc g++ pkg-config libssl-dev libdbus-1-dev \
libglib2.0-dev libavahi-client-dev ninja-build python3-venv python3-dev \
python3-pip unzip libgirepository1.0-dev libcairo2-dev libreadline-dev
(2) 克隆Matter项目:
将Matter项目克隆到本地目录,例如/home/${YOUR_USERNAME}/workspace/matter。
git clone https://github.com/project-chip/connectedhomeip
其中 ${YOUR_USERNAME} 是您的用户名文件夹
(3) 切换到master分支上的指定commit,并更新子模块。
cd ./connectedhomeip
git checkout 48be002741f2b87fe8554ec9961cbfc0d248b523
git submodule update --init --recursive
(4) 运行引导程序
执行bootstrap,准备Matter的环境,第一次运行通常需要很长时间。
source scripts/bootstrap.sh
注意:每次切换 commit、改变环境,都可能要重新运行引导程序。
此步骤将生成一个在Matter根目录 connectedhomeip 下的叫做 .environment的隐藏文件夹。在中国大陆它可能会花费额外的时间或遭遇失败。
提示:如果 Matter 构建环境有任何问题,您可以尝试:
1) 移除环境(在 Matter 项目的根目录中):
rm -rf .environment
2) 再次重做引导程序:
source scripts/bootstrap.sh
(5) (可选)如果您需要切换到其它分支或commit,需要执行以下命令
git fetch origin
git checkout <your_target_branch_or_commitid>
git submodule update --init --recursive
rm -rf .environment
source scripts/bootstrap.sh
您可以在这里找到更多信息:https://github.com/project-chip/connectedhomeip/blob/master/docs/guides/BUILDING.md
编译固件
闪存布局
对于TLSR9528A使用2MB flash的固件,flash分区如下(其余flash分区文件也在相同目录下): 2m_flash.overlay:
...
&flash {
reg = <0x20000000 0x200000>;
/delete-node/ partitions;
partitions {
compatible = "fixed-partitions";
#address-cells = <1>;
#size-cells = <1>;
boot_partition: partition@0 {
label = "mcuboot";
reg = <0x00000000 0x13000>;
};
slot0_partition: partition@13000 {
label = "image-0";
reg = <0x13000 0xec000>;
};
factory_partition: partition@ff000 {
label = "factory-data";
reg = <0xff000 0x1000>;
};
dac_keypair_partition: partition@100000 {
label = "dac-keypair";
reg = <0x100000 0x1000>; //store dac and key pair.
};
descriptor_partition: partition@101000 {
label = "sboot-descriptor";
reg = <0x101000 0x2000>;
};
storage_partition: partition@103000 {
label = "storage";
reg = <0x103000 0xf000>;
};
slot1_partition: partition@112000 {
label = "image-1";
reg = <0x112000 0xec000>;
};
vendor_partition: partition@1fe000 {
label = "vendor-data";
reg = <0x1fe000 0x2000>;
};
};
};
...
注意:表格内的信息仅具有参考价值,最准确的内存占用情况请下载最新的 Matter 代码进行确认。
设备的配置
如果一个或多个设备被配置为FTD (Full Thread Device),例如灯泡,则设备到设备之间的通信可以不需要边界路由器。
注意:默认情况下,所有设备都配置为 MTD(Minimal Thread Device)。
应用程序的配置文件位于:
examples/app/telink/prj.conf
MTD配置示例:
# OpenThread configs
CONFIG_OPENTHREAD_MTD=y
CONFIG_OPENTHREAD_FTD=n
FTD配置示例:
# OpenThread configs
CONFIG_OPENTHREAD_MTD=n
CONFIG_OPENTHREAD_FTD=y
编译
在Matter根目录执行以下操作,如果使用Docker镜像的话则在/root/chip中进行操作:
(1) 启动Matter环境:
source scripts/activate.sh
(2) 转到示例所在目录:
cd examples/*app*/telink
app:lighting-app或light-switch-app
(3) 若已经存在构建,则删除原有构建时产生的目录:
rm -rf build/
(4) 构建示例:
west build -b <build_target>
build_target为您准备使用的开发板名称,例如,tlsr9518adk80d
、tlsr9528a
。
并且,在编译命令中需要根据您使用开发板的flash大小来指定 -DFLASH_SIZE
,例如您使用的是2MB flash的B92开发板,则编译命令为:
west build -b tlsr9528a -- -DFLASH_SIZE=2m
您可以在 build/zephyr 目录下找到名为 zephyr.bin 的目标构建文件。
注意:请确保您的PC中已经安装并配置了
gn
构建工具,否则可能出现构建错误。另外,请记得执行zephyr工程路径下的zephyr-env.sh
,否则,可能出现west build
不存在的报错。
编译chip-tool
(1) 启动Matter环境:
source scripts/activate.sh
(2) 转到示例所在目录:
cd examples/chip-tool
(3) 若已经存在构建,则删除原有构建时产生的目录:
rm -rf out/
(4) 构建chip-tool
gn gen out
ninja -C out
构建完成的文件可以在 {MATTER_CHIP_TOOL_EXAMPLE_FOLDER}/out/chip-tool 找到。
如果想了解更多和chip-tool相关的内容,可以点击以下链接进行查看:https://github.com/project-chip/connectedhomeip/blob/master/examples/chip-tool/README.md
固件烧录
本烧录说明的实现适用于Windows和Ubuntu平台,以B92 EVB为例, 烧录一块B92 EVB所需要准备的硬件,至少需要有:
(1) 一块B92 EVB评估板;
(2) 一块Burning Evk烧录器;
(3) 两根Mini-USB线;
如需同时烧录多块B92 EVB评估板,请准备多套以上的硬件。另外,可能需要足够接口的USB Hub。
BDT和LinuxBDT下载
BDT是烧录调试工具,可以通过下面链接获取到最新的烧录工具:
Windows 10: http://wiki.telink-semi.cn/tools_and_sdk/Tools/BDT/BDT.zip
Ubuntu 20.04: http://wiki.telink-semi.cn/tools_and_sdk/Tools/BDT/LinuxBDT.tar.bz2
BDT的连接方式
请按照下面的图示进行硬件连接,如图是完成硬件连接后状态:
注意:务必采用默认的跳帽配置。
BDT在Windows平台上的使用步骤
(1) ⽤USB线连接烧录器到电脑的USB⼝。
(2) 下载BDT烧录软件,解压到本地⽂件夹,双击可执⾏⽂件"Telink BDT.exe"。如果⼀切正常,可以看到如下的窗⼝显⽰,在系统标题栏中可以看到已被连接的烧录器的设备信息(⻅图中红⾊框)。
(3) 选择相应的芯片。
- 如果使用的是
TLSR9528
芯片,则选择B92_3V3
。
(4) 点击工具栏中的"SWS"按钮,如果看到下图中的信息,则表明所有的硬件连接都没有问题。
(5) 设置Flash擦除的区域大小。点击工具栏中的"Setting"按钮,在弹出的"Setting"窗口中可以看到默认的Flash擦除的区域大小是512kB。
将Flash擦除的区域大小设置为"2040",如下图所示:
注意:对于外挂2MB Flash的TLSR9528开发板,Flash最后的8kB空间预留用于保存重要的SoC信息,因此最多可以擦除2040 KB的Flash区域。
(6) 点击工具栏中的"Erase"按钮,等待Flash擦除操作完成。
(7) 选择需要烧录的BIN文件。点击"File"菜单里的"Open"子菜单,在弹出的文件选择对话框中选中需要烧录的BIN文件。选中后的BIN文件将显示在底部的状态栏中。
(8) 点击工具栏中的"Download"按钮,等待Flash烧录完成。
对于更多命令的详细说明,请参考 BDT\doc
文件夹下的文档。
BDT在Windows平台上的常见问题
(1) 烧录器插入电脑后,可以被Windows设备管理器正确识别,但是烧录工具软件没有识别到,即在系统标题栏中看不到烧录器的设备信息(见图3.2)。请检查电脑是否用了AMD平台的处理器,换一台Intel平台处理器的电脑重新尝试。
(2) 最常见的问题是,在点击工具栏中的"SWS"按钮后,出现下图中的错误信息:
主要有两种原因:
-
硬件连接不正确。请参照前面的说明仔细核对所有的硬件连接,确认没有遗漏或错误的连接。
-
烧录器的固件版本太低。请按照以下步骤查看烧录器固件的版本:
1) 点击Help菜单下的Upgrade子菜单。
2) 在弹出的Upgrade Evk窗口中,点击"Read FW version"按钮。在旁边的"Firmware Version"区域将会显示烧录器的固件版本号,例如下图所示。如果固件版本号过低,可以确认是由于固件版本过低导致了通讯错误。请继续下面的步骤去完成固件升级。
3) 点击窗口中的"Load..."按钮,在BDT工具所在目录下的config目录下的fw子目录找到最新的烧录器固件,如下图中的Firmware_v4.4.bin文件。
4) 点击Upgrade按钮完成烧录器固件升级。
5) 插拔烧录器的USB线,使烧录器重新上电。
LinuxBDT在Ubuntu平台上的使用步骤
在Ubuntu 20.04上, 打开终端,下载 LinuxBDT
。
wget https://wiki.telink-semi.cn/tools_and_sdk/others/Telink-BDT-Linux-X64-V1.6.4.zip
对下载到本地的 Telink-BDT-Linux-X64-V1.6.4.zip
进行解压缩:
unzip Telink-BDT-Linux-X64-V1.6.4.zip
打开 linux_release
文件夹,可以使用图形化的烧录调试工具 bdt_gui
或者命令行的 bdt
,去操纵Burning Evk对B92 EVB进行烧录。
bdt_gui
的使用方法和windows平台下的BDT.exe相似,因此下面主要介绍命令行 bdt
的使用步骤。
(1) 用Mini-USB线连接烧录器到电脑的USB口
(2) 检测Burning Evk与⽬标板B92 EVB的连接是否正常
进入烧录工具 LinuxBDT
的根目录下的,执行下面命令。
./bdt b92 sws
可以查看已连接的烧录器和B92 EVB,如下图:
(3) 激活MCU
B92 EVB上已有固件在运行时,直接使用Burning Evk烧录器进行擦除或者烧录,可能会遇到 "Swire err!" 错误。为了避免类似错误,请执行以下命令先激活MCU。
./bdt b92 ac
(4) 擦除Flash扇区
为避免旧的固件所占的尺寸大于新的固件,导致新刷入的固件后,Flash上存在以往的数据残留,请先执行下面的擦除命令。如果此时处于unlock状态,需要先解锁,否则擦除失败。
./bdt b92 wf 0 -s 2040k -e -f
-
MCU 种类 --
B92
-
可选命令 --
wf
(for write flash) -
将要被擦除的起始地址 --
0
-
可选命令 --
-s
(指定将要擦除的扇区大小) -
将要擦除的扇区大小 --
2040k
(64k, 128k, 256k, 512k...) -
可选命令 --
-e
(erase flash) -
可选命令 --
-f
(unlock flash)
等待约数十秒,擦除成功后,会显示:
(5) 将固件下载到MCU的Flash中
./bdt b92 wf 0 -i ~/Lighting_B92.bin
-
MCU 种类--
B92
-
可选命令 --
wf
(for write flash) -
将要被写入的起始地址 --
0
-
可选命令 --
-i
(指定将要写入的固件) -
将要写入的固件的路径 -- 如这里的
Lighting_B92.bin
执行上述命令可以所选的固件刷入Flash当中,成功后的输出如下:
(6) 重置MCU
./bdt b92 rst -f
-
MCU 种类--
B92
-
可选命令 --
rst
(for reset) -
可选命令 --
-f
(for Flash or OTP)
使用上述重置命令成功后的输出如下:
重置B92 EVB评估板后,整个MCU将被重新上电,随即开始运行刚刚烧录的固件。
对于更多命令的详细说明,请参考 LinuxBDT/doc
文件夹下的文档。
边界路由配置
边界路由需要的硬件和固件
OTBR边界路由需要由以下两个部分组成:
(1) Raspberry Pi 4:树莓派4,推荐使用4GB RAM版本。
树莓派的预置镜像可以在下面的微盘中找到:
https://drive.weixin.qq.com/s?k=AKwA0AfNAA8wYik1M0
预置镜像的用户名为pi,密码为raspberry。(pi: raspberry)
(2) Radio Co-Processor:RCP负责Thread通讯,由一个TLSR9528A评估板来实现。
RCP固件也在上述的微盘地址中:
- b92-zephyr-rcp-usb-cdc.bin -- 用于B92 dongle,USB连接
边界路由的树莓派镜像烧录
在Windows下可以通过balenaEtcher进行树莓派镜像的烧录,具体步骤如下:
(1) 下载balenaEtcher, 下面是下载地址:
https://github.com/balena-io/etcher/releases
(2) 下载所需版本后进行解压,运行 balenaEtcher.exe。
(3) 把Mirco SD卡插入读卡器中,再将读卡器插入Windows电脑。
注意:请确保用到的Mirco SD卡的容量是16G或以上。
(4) 在balenaEtcher的界面中,点击 从文件烧录,选择 rpi_ot_br_posix.iso。
(5) 点击 选择磁盘目标,选择了Micro SD卡所在的驱动盘符。
(6) 点击 现在烧录!,等待镜像写入完成,完成后可以看到如下界面。
树莓派和RCP的连接方式
根据用作RCP的硬件的不同,树莓派和RCP的连接方式也不同。
B92 dongle作为RCP
如果您使用B92 dongle作为RCP,则只需要在进行以下配置后将B92 dongle通过USB连接到树莓派上即可。
+ OTBR_AGENT_OPTS="-I wpan0 -B eth0 spinel+hdlc+uart:///dev/ttyACM0 trel://eth0"
- OTBR_AGENT_OPTS="-I wpan0 -B eth0 spinel+hdlc+uart:///dev/ttyAMA1?uart-flow-control trel://eth0"
Thread网络建立和通过BLE配网
建立Thread网络并获取Dataset
(1) 在浏览器中输入树莓派的IP地址,点击Form按钮,默认设置不用更改,点击FORM建立Thread网络。
(2) Thread网络建立后可以在Status下查看状态
(3) 获取DATASET。请以SSH方式登录树莓派(预置镜像中的用户名username:pi,密码password:raspberry),执行以下命令:
$sudo ot-ctl dataset active -x
DATASET 是类似于以下形式的一串十六进制的字符串,将其保存好。
注意:每次形成新的Thread网络,上面的DATASET将会被重新生成。即使每次生成Thread网络所设置的参数相同,其中间的部分...0708fd0b448cf7918bcf051000...也会不同。
配网过程
(1) 在主机上进行配网之前,请检查主机与树莓派之间的网络连接状态。
-
如果主机与树莓派之间是由带防火墙的路由器做转发,暂时关闭路由器上的防火墙,尤其是其禁止端口监听、端口扫描等功能。
-
如果使用运营商的光猫作为路由,可能会导致mDNS服务无法发现的错误,尝试将主机与树莓派用仅开启DHCP服务的其他路由器进行网线直连。
-
确保主机是独立的Ubuntu主机;若使用Windows上的VirtualBox等虚拟机充当主机,则需要给它提供并配置额外的蓝牙适配器。
(2) 检查Matter固件版本与chip-tool的是否相符
编译Matter设备的固件和chip-tool需要相同的Zephyr环境,否则进行配网时会出错。
重要提醒:若要使用自己构建的chip-tool和Matter设备的固件,必须保证它们使用了相同的commit的connectedhomeip工程目录进行构建,以避免出现兼容性问题。
(3) 在主机上的shell中配置好以下命令:
./chip-tool pairing ble-thread ${NODE_ID} hex:${DATASET} ${PIN_CODE} ${DISCRIMINATOR}
注意:运行chip-tool需退出镜像,并检查chip-tool的执行权限。
NODE_ID 可以是RCP初始化之后,未使用过的任何非零值,chip-tool将使用它来操作特定的Matter设备。
DATASET 即为树莓派上获取的字符串。
示例:
(4) Matter设备上电后,白灯闪烁,进入BLE广播状态,在主机上的shell中输入上面命令并运行,会让Matter设备与RCP所在的边界路由开始配对并配网。
这个过程会持续一段时间,如果一切顺利,Matter设备加入Thread网络后,你将能够从主机的shell中看到类似下面的信息:
使用chip-tool进行控制
在配网成功之后,可以使用chip-tool对Matter设备进行控制,主要的几个控制命令如下。
开关灯
./chip-tool onoff command_name [param1 param2 ...]
-
command_name是命令的名字,此处开关灯可以用到on(开灯)、off(关灯)、toggle(切换状态)
-
[param1 param 2 ...]是所使用的多个参数,此处开关灯用到的是节点ID
<node_id>
和端点ID<endpoint_id>
-
<node_id>
是之前设备进行配网时使用的节点ID,可以用 ${NODE_ID} 这样的shell变量表示 -
<endpoint_id>
是实现了OnOff Cluster的端点的ID
开灯命令示例:
./chip-tool onoff on ${NODE_ID} 1
关灯命令示例:
./chip-tool onoff off ${NODE_ID} 1
灯泡状态翻转命令示例:
./chip-tool onoff toggle ${NODE_ID} 1
查看亮灯情况
标准的读取属性的命令为:
./chip-tool onoff read attribute-name [param1 param2 ...]
-
attribute-name是要读取的属性名
-
[param1 param 2 ...]是所使用的多个参数
读取亮灯情况的命令示例:
./chip-tool onoff read on-off ${NODE_ID} 1
-
属性名为on-off
-
此处的两个参数为节点ID和端点ID
查看亮度
同样使用读取属性的命令,标准的读取属性的命令为:
./chip-tool onoff read attribute-name [param1 param2 ...]
-
attribute-name是要读取的属性名
-
[param1 param 2 ...]是所使用的多个参数
读取亮度属性的命令示例:
./chip-tool levelcontrol read current-level ${NODE_ID} 1
-
属性名为current-level
-
此处的两个参数为节点ID和端点ID
改变亮度
标准的命令为:
./chip-tool levelcontrol move-to-level <level> <transition_time> <option_mask> <option_override> <node_id> <endpoint_id>
-
<level>
是亮度值 -
<transition_time>
是过渡时间 -
<option_mask>
是option mask -
<option_override>
是option override -
<node_id>
是之前设备进行配网时使用的节点ID -
<endpoint_id>
是实现了LevelControl Cluster的端点的ID
改变亮度的示例命令:
./chip-tool levelcontrol move-to-level 32 0 0 0 ${NODE_ID} 1
连接灯和开关
对于配网在同一Matter网络的light-switch开关和lighting灯泡,可以通过以下步骤进行绑定。
(1) 使用chip-tool将访问控制列表ACL(Accsee Control List)写入accesscontrol Cluster,为每个灯泡设备添加合适的访问控制列表,执行如下命令:
./chip-tool accesscontrol write acl <acl_data> <node_id> <endpoint_id>
-
<acl_data>
是格式为JSON数组的ACL数据。 -
<node_id>
是要接收ACL的节点的ID。 -
<endpoint_id>
是实现accesscontrol Cluster的端点的ID。
命令示例:
./chip-tool accesscontrol write acl '[{"fabricIndex": 1, "privilege": 5, "authMode": 2, "subjects": [112233], "targets": null}, {"fabricIndex": 1, "privilege": 3, "authMode": 2, "subjects": [<light-switch-node-id>], "targets": [{"cluster": 6, "endpoint": 1, "deviceType": null}, {"cluster": 8, "endpoint": 1, "deviceType": null}]}]' <lighting-node-id> 0
在上面的命令中:
-
<lighting-node-id>
是之前灯泡设备进行配网时使用的节点ID,可以用 ${NODE_ID} 这样的shell变量表示。 -
<light-switch-node-id>
是之前开关设备进行配网时使用的节点ID,此处需要用数字表示。 -
{"fabricIndex": 1, "privilege": 5, "authMode": 2, "subjects": [112233], "targets": null}是和chip-tool通讯的访问控制列表。
-
{"fabricIndex": 1, "privilege": 5, "authMode": 2, "subjects": [\
], "targets": [{"cluster": 6, "endpoint": 1, "deviceType": null}, {"cluster": 8, "endpoint": 1, "deviceType": null}]} 是一个绑定的访问控制列表(cluster NO.6是On/Off cluster,cluster NO.8是Level Control cluster)。
此命令为照明应用设备添加权限,允许其接收来自开关设备的命令。
(2) 将绑定表添加到开关以通知设备端点:
./chip-tool binding write binding <binding_data> <node_id> <endpoint_id>
-
<binding_data>
是格式为JSON数组的绑定数据。 -
<node_id>
是要接受绑定的节点的ID。 -
<endpoint_id>
是实现binding Cluster的端点的ID。
命令示例:
### 如果仅有一个lighting设备
./chip-tool binding write binding '[{"fabricIndex": 1, "node": <lighting-node-id>, "endpoint": 1, "cluster": 6}]' <light-switch-node-id> 1
### 如果有多个lighting设备,则添加所有nodeid
./chip-tool binding write binding '[{"fabricIndex": 1, "node": <lighting-node-id_1>, "endpoint": 1, "cluster": 6}, {"fabricIndex": 1, "node": <lighting-node-id_2>, "endpoint": 1, "cluster": 6}]' <light-switch-node-id> 1
在上面的命令中:
-
<light-switch-node-id>
是之前开关设备进行配网时使用的节点ID,可以用 ${SWITCH_NODE_ID} 这样的shell变量表示。 -
<lighting-node-id>
是之前灯泡设备进行配网时使用的节点ID,此处需要用数字表示,若有多个灯泡设备,则按照示例在[]中依次添加所有灯泡设备使用的节点ID。 -
{"fabricIndex": 1, "node": <lighting-node-id>, "endpoint": 1, "cluster": 6}
是绑定On/Off Cluster。
体验OTA功能
启用OTA模块
OTA模块只在ota-requestor-app示例中默认启用,若要在其他Telink Matter示例中启用OTA模块,需要按照以下步骤:
- 在相应的
prj.conf
配置文件中设置"CONFIG_CHIP_OTA_REQUESTOR=y"
在通过以上配置启用OTA模块后,编译得到固件:
- zephyr.bin - 烧录到开发板上的bin文件
- zephyr-ota.bin - 用于OTA Provider的bin文件
所有的bin文件都拥有相同的SW版本,为了测试OTA,"zephyr-ota.bin"应该有比基础的SW更高的SW版本。在对应的 prj.conf
配置文件中设置"CONFIG_CHIP_DEVICE_SOFTWARE_VERSION=2"
OTA的用法
(1) 构建Linux OTA Provider
./scripts/examples/gn_build_example.sh examples/ota-provider-app/linux out/ota-provider-app chip_config_network_layer_ble=false
(2) 运行Linux OTA Provider
./chip-ota-provider-app -f zephyr-ota.bin
此处的zephyr-ota.bin是用来升级的固件。
(3) 打开另一个终端,用chip-tool准备Linux OTA Provider
./chip-tool pairing onnetwork ${OTA_PROVIDER_NODE_ID} 20202021
在这个命令中:
- ${OTA_PROVIDER_NODE_ID}是Linux OTA Provider的node id,类似于lighting-app的 NODE_ID,应该是一个之前没使用过的非零值。
(4) 配置ota-provider-app的ACL来允许访问
./chip-tool accesscontrol write acl '[{"fabricIndex": 1, "privilege": 5, "authMode": 2, "subjects": [112233], "targets": null}, {"fabricIndex": 1, "privilege": 3, "authMode": 2, "subjects": null, "targets": null}]' ${OTA_PROVIDER_NODE_ID} 0
- 此处的${OTA_PROVIDER_NODE_ID}是Linux OTA Provider的node id。
(5) 使用chip-tool通知ota-provider-app开始OTA进程。
./chip-tool otasoftwareupdaterequestor announce-otaprovider ${OTA_PROVIDER_NODE_ID} 0 0 0 ${DEVICE_NODE_ID} 0
在这个命令中:
- ${OTA_PROVIDER_NODE_ID}是Linux OTA Provider的node id
- ${DEVICE_NODE_ID}是配对设备的node id
如何基于/利用Github上的开源SDK进行开发
架构
-
Application:包含特定Matter设备的业务逻辑,作为用户交互的接口
-
ZCL Data Model:数据模型层,将应用程序与周围的环境连接起来,Matter中借鉴了ZCL(ZigBee Cluster Library)的数据格式
-
Matter Library:负责Matter信息的通信,加密/解密,与数据模型的交互,配网管理等工作
-
Matter Platform Layer:连接Matter软件库和特定的硬件平台
-
Zephyr RTOS: 提供运行Matter应用程序的实时操作系统环境
-
Zephyr Bluetooth Subsystem:在 Zephyr 环境中实现 BLE 协议
-
HCI Driver:一个Telink提供的兼容 Zephyr 的驱动程序,通过与硬件接口实现 BLE 通信
-
Zephyr Thread Subsystem:实现 OpenThread 功能,允许在 Zephyr 生态系统内进行基于 Thread 的通信
-
IEEE802154 Driver:一个Telink提供的兼容 Zephyr 的驱动程序,由 OpenThread 用于管理 IEEE 802.15.4 层级的通信
-
RF driver:Telink提供的射频驱动程序,促进 Zephyr OpenThread 和 BLE 的通信。
数据模型
这里以一个具备开关灯和亮度调节功能的灯泡设备为例,介绍 Matter 的数据模型。
-
Node 即为节点,表示物理设备,此处的灯泡设备就是一个节点。
-
Endpoint 是端点,表示设备类的逻辑功能单元,通讯就是靠本地的端点和设备上的端点进行交互来完成的。每个节点都有许多端点,在每个端点中又有许多 Cluster,这些 Cluster 就说明了这个端点的功能。图中以灯泡为例,Endpoint 0 是需要保留的,提供整个Matter节点的一些基础功能,例如 Basic Information Cluster(提供节点的一些基本信息,如固件版本、制造商等等),Access Control Cluster(允许为此节点配置访问控制列表),Network Commissioning Cluster(允许在此节点上配置网络,如Wi-Fi、以太网、Thread网络)。在 Endpoint 1 里有 On/Off 和Level Control 两个 Cluster,它们共同组成了 Endpoint 1 的功能。
-
Cluster 用来实现具体的功能,不同的 Cluster 可以组合实现不同的功能。图中的两个Cluster:On/Off 实现开关灯功能,Level Control 实现调节亮度的功能。Cluster 里定义了一些属性、命令和事件。
-
Cluster 使用的是 Client/Sever 的通讯模型,属性通常在 Server,说明了设备的属性,例如灯的开关状态、灯的亮度等。
-
Client 和 Server 之间通过预设好的命令进行控制,通常是 Client 发起请求,Server 进行应答的模式。例如,On/Off Cluster 用 On 命令来控制开灯,用 Off 命令来控制关灯,Level Control Cluster 也有 MoveToLevel、Move 等命令。
-
在某些情况下,当Server上的属性发生了变化,Server会通过事件(Event)主动通知Client,以便同步状态。
代码逻辑和重点源码
初始化函数
AppTaskCommon::InitCommonParts(void)中的初始化大致可以分成3个部分。
第一部分是如下的代码,主要是对硬件相关的初始化。InitCommonParts(void)函数一开始打印出软件版本信息,然后初始化了用于显示系统状态的LED灯,接着是对PWM和按键的初始化,最后初始化功能按钮定时器。
CHIP_ERROR AppTaskCommon::InitCommonParts(void)
{
...
CHIP_ERROR err;
LOG_INF("SW Version: %u, %s", CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION, CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING);
/* if use user mode ,should disable the hardware init to avoid conflict*/
#if APP_LIGHT_USER_MODE_EN
#if INDEPENDENT_FACTORY_RESET_BUTTON
IndependentFactoryReset(); // Open the factory_reset button separately.
#endif
#else
InitLeds();
UpdateStatusLED();
InitPwms();
InitButtons();
#endif
// Initialize function button timer
k_timer_init(&sFactoryResetTimer, &AppTask::FactoryResetTimerTimeoutCallback, nullptr);
k_timer_user_data_set(&sFactoryResetTimer, this);
...
}
第二部分代码如下:
CHIP_ERROR AppTask::Init()
{
...
// Initialize CHIP server
#if CONFIG_CHIP_FACTORY_DATA
ReturnErrorOnFailure(mFactoryDataProvider.Init());
SetDeviceInstanceInfoProvider(&mFactoryDataProvider);
SetDeviceAttestationCredentialsProvider(&mFactoryDataProvider);
SetCommissionableDataProvider(&mFactoryDataProvider);
// Read EnableKey from the factory data.
MutableByteSpan enableKey(sTestEventTriggerEnableKey);
err = mFactoryDataProvider.GetEnableKey(enableKey);
if (err != CHIP_NO_ERROR)
{
LOG_ERR("mFactoryDataProvider.GetEnableKey() failed. Could not delegate a test event trigger");
memset(sTestEventTriggerEnableKey, 0, sizeof(sTestEventTriggerEnableKey));
}
#else
SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider());
#endif
// Init ZCL Data Model and start server
static CommonCaseDeviceServerInitParams initParams;
static SimpleTestEventTriggerDelegate sTestEventTriggerDelegate{};
VerifyOrDie(sTestEventTriggerDelegate.Init(ByteSpan(sTestEventTriggerEnableKey)) == CHIP_NO_ERROR);
#if CONFIG_CHIP_OTA_REQUESTOR
static OTATestEventTriggerHandler sOtaTestEventTriggerHandler{};
VerifyOrDie(sTestEventTriggerDelegate.AddHandler(&sOtaTestEventTriggerHandler) == CHIP_NO_ERROR);
#endif
(void) initParams.InitializeStaticResourcesBeforeServerInit();
initParams.appDelegate = &sCallbacks;
initParams.testEventTriggerDelegate = &sTestEventTriggerDelegate;
ReturnErrorOnFailure(chip::Server::GetInstance().Init(initParams));
...
}
当CONFIG_CHIP_FACTORY_DATA配置项使能的时候,工厂数据将用于提供设备证明过程所需的信息(例如PAI和DAC),还有其他设备信息,具体请参考第三章中“厂商数据”,还有src/platform/telink目录中FactoryDataProvider.cpp的代码。
第三部分是下面的代码。
CHIP_ERROR AppTaskCommon::InitCommonParts(void)
{
...
#if APP_SET_DEVICE_INFO_PROVIDER
gExampleDeviceInfoProvider.SetStorageDelegate(&Server::GetInstance().GetPersistentStorage());
chip::DeviceLayer::SetDeviceInfoProvider(&gExampleDeviceInfoProvider);
#endif
ConfigurationMgr().LogDeviceConfig();
PrintOnboardingCodes(chip::RendezvousInformationFlags(chip::RendezvousInformationFlag::kBLE));
#if APP_SET_NETWORK_COMM_ENDPOINT_SEC
emberAfEndpointEnableDisable(kNetworkCommissioningEndpointSecondary, false);
#endif
PlatformMgr().SetDelegate(new PlatformMgrDelegate);
// Add CHIP event handler and start CHIP thread.
// Note that all the initialization code should happen prior to this point to avoid data races
// between the main and the CHIP threads.
PlatformMgr().AddEventHandler(ChipEventHandler, 0);
err = chip::Server::GetInstance().GetFabricTable().AddFabricDelegate(new AppFabricTableDelegate);
if (err != CHIP_NO_ERROR)
{
LOG_ERR("AppFabricTableDelegate fail");
return err;
}
return CHIP_NO_ERROR;
}
ConfigurationMgr().LogDeviceConfig()在日志中打印出设备配置信息,例如下面的打印输出。
I: 510 [DL] Device Configuration:
I: 514 [DL] Serial Number: TEST_SN
I: 519 [DL] Vendor Id: 65521 (0xFFF1)
I: 523 [DL] Product Id: 32773 (0x8005)
I: 527 [DL] Product Name: not-specified
I: 532 [DL] Hardware Version: 0
I: 537 [DL] Setup Pin Code (0 for UNKNOWN/ERROR): 20202021
I: 544 [DL] Setup Discriminator (0xFFFF for UNKNOWN/ERROR): 3840 (0xF00)
I: 552 [DL] Manufacturing Date: (not set)
I: 556 [DL] Device Type: 65535 (0xFFFF)
PrintOnboardingCodes()函数输出用于配网的二维码和手动配对码,下面是一个实际例子。
I: 563 [SVR]SetupQRCode: [MT:6FCJ142C00KA0648G00]
I: 568 [SVR]Copy/paste the below URL in a browser to see the QR Code:
I: 575 [SVR]https://project-chip.github.io/connectedhomeip/qrcode.html?data=MT%3A6FCJ142C00KA0648G00
I: 585 [SVR]Manual pairing code: [34970112332]
PlatformMgr().AddEventHandler()函数注册了一个回调函数AppTask::ChipEventHandler(),用于对特定的设备事件进行响应。
回调函数
Matter 代码中预留了很多的回调函数,好处是可以在不修改源码的情况下,最大程度地支持代码扩展。这里以 lighting-app 为例,介绍代码中数据模型涉及的重要回调函数,它的实现在 examples/lighting-app/telink/src/ZclCallback.cpp这个文件中。
回调函数是MatterPostAttributeChangeCallback(),它的默认实现在 src/app/util/generic-callback-stubs.cpp 这个文件中。如下面的代码所示,Matter 提供的默认实现是一个不包含任何代码的空函数。当用户提供了新的实现代码后,新的回调函数将替换该默认实现。
void __attribute__((weak)) MatterPostAttributeChangeCallback(const chip::app::ConcreteAttributePath & attributePath, uint8_t type,
uint16_t size, uint8_t * value)
{}
只要一个属性(可以是任何Cluster的属性)的内容被更新后,MatterPostAttributeChangeCallback()这个回调函数就会被调用。在lighting-app中,我们实现了如下的回调函数,作用是将属性的最新状态同步到硬件中。例如,用户通过chip-tool更新了On/Off Cluster的OnOff属性值后,开发板上的LED状态需要更新为OnOff属性对应的状态,这个动作就是在回调函数中完成的(具体是调用了下面代码中的GetAppTask().SetInitiateAction()函数)。同样的,如果用户通过chip-tool更新了Level Control Cluster的Current Level属性值后,下面的代码也通过调用GetAppTask().SetInitiateAction()更新了LED的亮度。
如果用户需要对其他属性的状态变化进行响应,可以在这个回调函数中添加代码进行处理。
void MatterPostAttributeChangeCallback(const chip::app::ConcreteAttributePath & attributePath, uint8_t type, uint16_t size,
uint8_t * value)
{
static HsvColor_t hsv;
static XyColor_t xy;
ClusterId clusterId = attributePath.mClusterId;
AttributeId attributeId = attributePath.mAttributeId;
if (clusterId == OnOff::Id && attributeId == OnOff::Attributes::OnOff::Id)
{
ChipLogDetail(Zcl, "Cluster OnOff: attribute OnOff set to %u", *value);
GetAppTask().SetInitiateAction(*value ? AppTask::ON_ACTION : AppTask::OFF_ACTION,
static_cast<int32_t>(AppEvent::kEventType_DeviceAction), value);
}
else if (clusterId == LevelControl::Id && attributeId == LevelControl::Attributes::CurrentLevel::Id)
{
if (GetAppTask().IsTurnedOn())
{
ChipLogDetail(Zcl, "Cluster LevelControl: attribute CurrentLevel set to %u", *value);
GetAppTask().SetInitiateAction(AppTask::LEVEL_ACTION, static_cast<int32_t>(AppEvent::kEventType_DeviceAction), value);
}
else
{
ChipLogDetail(Zcl, "LED is off. Try to use move-to-level-with-on-off instead of move-to-level");
}
}
else if (clusterId == ColorControl::Id)
{
/* Ignore several attributes that are currently not processed */
if ((attributeId == ColorControl::Attributes::RemainingTime::Id) ||
(attributeId == ColorControl::Attributes::EnhancedColorMode::Id) ||
(attributeId == ColorControl::Attributes::ColorMode::Id))
{
return;
}
/* XY color space */
if (attributeId == ColorControl::Attributes::CurrentX::Id || attributeId == ColorControl::Attributes::CurrentY::Id)
{
if (attributeId == ColorControl::Attributes::CurrentX::Id)
{
xy.x = *reinterpret_cast<uint16_t *>(value);
}
else if (attributeId == ColorControl::Attributes::CurrentY::Id)
{
xy.y = *reinterpret_cast<uint16_t *>(value);
}
ChipLogDetail(Zcl, "New XY color: %u|%u", xy.x, xy.y);
GetAppTask().SetInitiateAction(AppTask::COLOR_ACTION_XY, static_cast<int32_t>(AppEvent::kEventType_DeviceAction),
(uint8_t *) &xy);
}
/* HSV color space */
else if (attributeId == ColorControl::Attributes::CurrentHue::Id ||
attributeId == ColorControl::Attributes::CurrentSaturation::Id ||
attributeId == ColorControl::Attributes::EnhancedCurrentHue::Id)
{
if (attributeId == ColorControl::Attributes::EnhancedCurrentHue::Id)
{
hsv.h = (uint8_t) (((*reinterpret_cast<uint16_t *>(value)) & 0xFF00) >> 8);
hsv.s = (uint8_t) ((*reinterpret_cast<uint16_t *>(value)) & 0xFF);
}
else if (attributeId == ColorControl::Attributes::CurrentHue::Id)
{
hsv.h = *value;
}
else if (attributeId == ColorControl::Attributes::CurrentSaturation::Id)
{
hsv.s = *value;
}
ChipLogDetail(Zcl, "New HSV color: hue = %u| saturation = %u", hsv.h, hsv.s);
GetAppTask().SetInitiateAction(AppTask::COLOR_ACTION_HSV, static_cast<int32_t>(AppEvent::kEventType_DeviceAction),
(uint8_t *) &hsv);
}
/* Temperature Mireds color space */
else if (attributeId == ColorControl::Attributes::ColorTemperatureMireds::Id)
{
ChipLogDetail(Zcl, "New Temperature Mireds color = %u", *(uint16_t *) value);
GetAppTask().SetInitiateAction(AppTask::COLOR_ACTION_CT, static_cast<int32_t>(AppEvent::kEventType_DeviceAction),
value);
}
else
{
ChipLogDetail(Zcl, "Ignore ColorControl attribute (%u) that is not currently processed!", attributeId);
}
}
}
例程代码
目前支持的两个例程:
-
examples/lighting-app/telink
-
examples/light-switch-app/telink
文件 | 描述 |
---|---|
src/AppTask.cpp | 包含应用程序的主循环和事件处理程序 |
src/ZclCallbacks.cpp | 包含ZCL数据模型的回调函数的事件处理程序 |
prj.conf | 包含关于具体例程的Zephyr配置 |
CMakeLists.txt | 包含要生成的源代码列表及其路径 |
硬件平台代码
Telink B92评估板的相关代码:
- examples/patform/telink
文件 | 描述 |
---|---|
project_include/OpenThreadConfig.h | 包含OpenThread的配置的定义 |
util/src/ButtonManager.cpp | 包含负责TLSR9528A按键设置的代码 |
util/src/LEDManager.cpp | LED管理器的相关代码 |
util/src/ThreadUtil.cpp | 用静态密钥配置Thread网络的相关代码 |
Matter配置代码
Matter 的配置代码:
- config/telink
文件 | 描述 |
---|---|
app/enable-gnu-std.cmake | 包括负责支持 gnu++17 标准的CMake |
chip-gn/ | 包含gn特定文件的文件夹,以构建Telink Matter SDK |
chip-module/CMakeLists.txt | CMake配置文件,包含Telink Matter SDK的设置规则和依赖项。还包含gn设置到CMake的映射,以链接SDK与Zephyr |
chip-module/Kconig | 包含Matter SDK的Zephyr的Telink特定配置,也包括Matter的一般Zepyhr配置 |
Matter平台代码
Matter 的平台代码:
- src/platform/telink
文件 | 描述 |
---|---|
../../crypto/ | 包含硬件加密所需源代码的文件夹 |
BLEManagerImpl.cpp | 包含BLE Manager for Matter SDK实现的代码,基于Telink单连接BLE SDK |
BUILD.gn | 用于构建的gn文件 |
../Zephyr | Zephyr平台层 |
Matter 开发详解
从“Matter中国区开发者大会”直播回放的 07:10:40 开始,有关于 Matter 开发的详细介绍,并在最后介绍了一个简单的 Hello Matter Sensor 实现。
电脑端观看地址: https://wvk.h5.xeknow.com/sl/3x3C8A
手机端观看请扫描下方二维码:
附录1 - 生态配置
Google Matter Demo
Google Matter Demo概述
本章节以Telink Matter的lighting-app为例,将B92 EVK开发板作为一个Matter设备添加到Google Nest Hub Gen2上。 用户可以通过Google手机上的Google Home App控制开发板上的灯,可控内容为灯的亮灭,灯的亮度。
Google Matter所需的硬件
-
TLSR9528A 作为Matter灯设备
-
Google Nest Hub Gen2 作为Matter网络的Border Router
-
可连接谷歌服务器的无线路由器 提供WiFi接入点,为Google Nest Hub Gen2提供数据校验
-
Google Pixel6手机 作为Commissioner,用户控制灯入网、开关的平台
Google Matter所需的软件
-
Google手机系统Android13且更新最新安全补丁
-
Google Nest Hub Gen 2nd Gen固件版本1.56.324896
-
Google Home软件版本2.2.60.2
-
Telink Matter lighting-app固件
Google Matter拓扑结构
Google Matter连接步骤
(1) 将无线路由器上电,配置WiFi网络参数。
注意:此时的无线路由器需要配置VPN,才能正常访问 www.google.com
(2) 打开Google手机蓝牙,Google手机与Google Nest Hub Gen2连接到同一路由器的WiFi网络,在Google Home App中添加Google Nest Hub Gen2。
Google Nest Hub Gen2配置教程 https://support.google.com/googlenest/answer/7029485?hl=en&co=GENIE.Platform%3DAndroid&oco=0
(3) 将B92 EVK开发板连接电源,开发板的串口通过USB-TTL工具连接到电脑,然后将开发板上电。
开发板的PB2-TXD,PB3-RXD,串口配置信息115200,8N1,电脑端打开MobaXterm查看设备输出log。
(4) 当观察到开发板的红灯短亮并闪烁,从MobaXterm中找到设备二维码的网址(见图中红色框)。
(5) 复制网址到浏览器获取二维码。
(6) 打开Google Home App,在主界面左上角的“+”号。
(7) 选择Set up device。
(8) 选择New device。
(9) 选择一个要加入的home。
(10) 选择Matter-enabled device设备类型。
(11) 扫描浏览器上的二维码。
(12) 等待设备与Google Nest Hub Gen2之间完成commissioning。
(13) 设置设备名称。
(14) 成功添加Matter设备到Google Nest Hub Gen2,2rd floor light就是新添加的B92 EVK开发板。
(15) 进入操控界面,可以控制灯的亮灭和亮度。
Apple Matter Demo
Apple Matter Demo概述
本章节以Telink Matter的lighting-app为例,将B92 EVK开发板作为一个Matter灯设备添加到Apple HomePod Mini上。用户可以通过iPhone上的Home App控制开发板上的灯,可控内容为灯的亮灭,灯的亮度。
Apple Matter所需的硬件
-
TLSR9528A 作为Matter灯设备
-
Apple HomePod Mini 作为Matter网络的Border Router
-
无线路由器 提供WiFi接入点,为Apple HomePod Mini提供数据校验
-
iPhone手机 作为Commissioner,用户控制灯入网、开关的平台
Apple Matter所需的软件
-
iPhone手机系统iOS16.1.2
-
Apple HomePod Mini固件版本16.2
-
Telink Matter lighting-app固件
Apple Matter拓扑结构
Apple Matter连接步骤
(1) 将无线路由器上电,配置WiFi网络参数。
(2) 打开iPhone手机蓝牙,并将iPhone手机连接到配置好的WiFi网络下,将Apple HomePod Mini上电。等待顶部触控板白灯开始旋转后,将iPhone手机靠近Apple HomePod Mini。出现图中悬浮窗,点击设置。
(3) 将Apple HomePod Mini放入取景框。
(4) 等待Apple HomePod Mini设置完成。
(5) 按照手机提示操作,成功添加Apple HomePod Mini到Home App。
(6) 将B92 EVK开发板连接电源,开发板的串口连接到电脑,然后将开发板上电。
开发板的PB2-TXD,PB3-RXD,串口配置信息115200,8N1,电脑端打开MobaXterm查看设备输出log。
(7) 当观察到开发板的红灯短亮并闪烁,从MobaXterm中找到设备二维码的网址(见图中红色框)。
(8) 复制网址到浏览器获取二维码。
(9) 打开Apple Home App,在主界面右上角“+”号,选择添加或扫描配件。
(10) 扫描浏览器上的二维码。
(11) 点击“添加到‘Apple家庭’”。
(12) 出现弹窗,点击仍然添加。
(13) 设置设备名称。
(14) 成功添加B92 EVK到Apple HomePod Mini,light-1就是新添加的Matter灯设备。
(15) 进入操控界面,可以控制灯的亮灭和亮度。
Amazon Matter Demo
Amazon Matter Demo概述
本章节以Telink Matter的lighting-app为例,将B92 EVK开发板作为一个Matter设备添加到Amazon Echo上。 用户可以通过Google手机上的Amazon Alexa App控制开发板上的灯,可控内容为灯的亮灭,灯的亮度。
Amazon Matter所需的硬件
-
TLSR9528A 作为Matter灯设备
-
Amazon Echo 作为Matter网络的Border Router
-
无线路由器 提供WiFi接入点,为Amazon Echo提供数据校验
-
Google Pixel6手机 作为Commissioner,用户控制灯入网、开关的平台
Amazon Matter所需的软件
-
Google手机系统Android13且更新最新安全补丁
-
Amazon Echo软件版本0011040824196
-
Amazon Alexa APP版本2024.20
-
Telink Matter lighting-app固件
Amazon Matter拓扑结构
Amazon Matter连接步骤
(1) 将无线路由器上电,配置WiFi网络参数。
(2) 打开Google手机, 在Amazon Alexa App中添加Amazon Echo。
(3) 将B92 EVK开发板连接电源,开发板的串口连接到电脑,然后将开发板上电。
开发板的PB2-TXD,PB3-RXD,串口配置信息115200,8N1,电脑端打开MobaXterm查看设备输出log。
(4) 当观察到开发板的白灯短亮并闪烁,从MobaXterm中找到设备二维码的网址(见图中红色框)。
(5) 复制网址到浏览器获取二维码。
(6) 打开Amazon Alexa App,在主界面左上角的“+”号。
(7) 选择Add Device。
(8) 选择Matter Device。
(9) 选择YES,有一个Matter logo。
(10) 确保设备处于广播状态后,选择YES,设备处于power on。
(11) 选择Scan QR Code
(12) 扫描浏览器上的二维码。
(13) 选择YES,设备是与Matter兼容的。
(14) 等待设备与Amazon Echo之间完成commissioning。
(15) 设置设备名称和设备房间,均可选择skip。
(16) 成功添加Matter设备到Amazon Echo,first light就是新添加的B92 EVK开发板。
(17) 进入操控界面,可以控制灯的亮灭和亮度。
Samsung Matter Demo
Samsung Matter Demo概述
本章节以Telink Matter的lighting-app为例,将B92 EVK开发板作为一个Matter设备添加到SmartThings Station上。 用户可以通过Google手机上的SmartThings App控制开发板上的灯,可控内容为灯的亮灭,灯的亮度。
Samsung Matter所需的硬件
-
TLSR9528A 作为Matter灯设备
-
SmartThings Station 作为Matter网络的Border Router
-
无线路由器 提供WiFi接入点,为SmartThings Station提供数据校验
-
Google Pixel6手机 作为Commissioner,用户控制灯入网、开关的平台
Samsung Matter所需的软件
-
Google手机系统Android13且更新最新安全补丁
-
SmartThings Station Hub firmware版本000.053.00019
-
SmartThings APP版本1.8.18.21
-
Telink Matter lighting-app固件
Samsung Matter拓扑结构
Samsung Matter连接步骤
(1) 打开 SmartThings App, 选择右上角的 +
, 选择 Add device
.
(2) 选择 Partner devices, 点击 Add
.
(3) 选择 Matter
.
(4) 扫描二维码并选择 Continue
.
(5) 等待连接完成, 设置好设备名称和房间.
(6) 此时设备可以被SmartThings App控制
附录2 - 环境搭建(docker)
需要 Ubuntu 版本为 20.04 LTS。在正文的第三章体验Matter的实现和功能,我们介绍了手动搭建 Matter 的工程环境的方法,在此附录内我们会继续介绍使用docker搭建 master 分支环境的步骤。
安装依赖项
sudo apt-get install git gcc g++ pkg-config libssl-dev libdbus-1-dev \
libglib2.0-dev libavahi-client-dev ninja-build python3-venv python3-dev \
python3-pip unzip libgirepository1.0-dev libcairo2-dev libreadline-dev
安装Docker
运行 docker 容器(在首次运行时会花费一些时间):
对于 Matter master 分支,使用以下命令:
docker run -it --rm -v $PWD:/host -w /host ghcr.io/project-chip/chip-build-telink:$(wget -q -O - https://raw.githubusercontent.com/project-chip/connectedhomeip/master/.github/workflows/examples-telink.yaml 2> /dev/null | grep chip-build-telink | awk -F: '{print $NF}')
兼容的 docker 镜像版本可以在 Matter 工程目录的以下文件中找到:
.github/workflows/examples-telink.yaml
或者,可以查看 GitHub 上的记录: https://github.com/project-chip/connectedhomeip/blob/master/.github/workflows/examples-telink.yaml
搭建Matter工程环境
(1. 获取Matter工程
下载 Matter 工程到本地目录,如 /home/${YOUR_USERNAME}/workspace/matter。
git clone https://github.com/project-chip/connectedhomeip
(2) 切换到master分支上的指定commit并更新子模块
cd ./connectedhomeip
git checkout 68068cbe663add7c7be8b2ff6c016e9a03b287fb
git submodule update --init --recursive
(3) 运行引导程序
执行 bootstrap,准备 Matter 的环境,第一次运行通常需要很长时间。
source scripts/bootstrap.sh
注意:每次切换 commit、改变环境,都可能要重新运行引导程序。
此步骤将生成一个在 Matter 根目录 connectedhomeip 下的叫做 .environment 的隐藏文件夹。在中国大陆它可能会花费额外的时间或遭遇失败。
提示:如果 Matter 构建环境有任何问题,您可以尝试:
1) 移除环境(在 Matter 项目的根目录中):
rm -rf .environment
2) 再次重做引导程序:
source scripts/bootstrap.sh
构建 Matter 示例
(1) 激活 Matter 环境
source scripts/activate.sh
(2) 转到示例所在目录
cd examples/${app}/telink
${app}
: lighting-app 或者 light-switch-app 等
(3) 如果此前已经存在构建,则删除
rm -rf build/
(4) 构建示例
west build -b <build_target>
tlsr9518adk80d
、tlsr9528a
。
并且,在编译命令中需要根据您使用开发板的flash大小来指定 -DFLASH_SIZE
,例如您使用的是2MB flash的 B92开发板,则编译命令为:
west build -b tlsr9528a -- -DFLASH_SIZE=2m
你可以在 build/zephyr 文件夹下找到名为 zephyr.bin 的目标构建文件。
附录3 - CD证书
对某些使用自己PAA证书的厂商会需要生成自己的认证证书(Certification Declaration ,CD),用于设备通过CSA认证之前的认证测试。
第一步:使用chip-cert工具,源码路径:connectedhomeip/src/tools/chip-cert,用以下命令生成chip-cert:
source scripts/activate.sh
gn gen src/tools/chip-cert/out/host
ninja -C src/tools/chip-cert/out/host chip-cert
第二步:使用chip-cert工具生成认证证书。
./src/tools/chip-cert/out/host/chip-cert gen-cd \
-C credentials/test/certification-declaration/Chip-Test-CD-Signing-Cert.pem \
-K credentials/test/certification-declaration/Chip-Test-CD-Signing-Key.pem \
--out telink_cd.bin \
-f 1 \
-V 1141 \
-p 8005 \
-d 0100 \
-c "ZIG0000000000000000" \
-l 0 \
-i 0 \
-n 0001 \
-t 1
厂商可能需要设置的参数为:
命令 | 描述 |
---|---|
-V 1141 | Vendor ID,厂商标识,0x1411为Telink VID |
-p 8005 | Product ID,产品标识,基于具体产品设置的标识 |
-d 0100 | Device ID,设备标识,基于产品类型的标识,具体设备对应的标识在Matter标准中有详细规定,示例中设置的0x100为可调光的灯 |
-t 1 | Certification-type,证书类型,Matter协议中规定的证书类型分三种:\ -t 0 - 开发和测试阶段使用,Matter默认类型 \ -t 1 - 临时使用,过认证时可使用这个类型 \ -t 2 - 认证通过后,会从CSA得到正式的认证证书 |
生成后的认证证书为bin格式,可以用以下命令验证认证证书的合法性:
./src/tools/chip-cert/out/host/chip-cert print-cd ./telink_cd.bin
第三步:替换Matter工程中的认证证书(CD)
首先将二进制的证书转化为数组格式
xxd -i telink_cd.bin > telink_cd.h
当前Matter工程中,认证证书保存在宏定义CHIP_DEVICE_CONFIG_CERTIFICATION_DECLARATION的数组中,只要用生成的telink_cd.h替换词宏定义即可。
宏定义CHIP_DEVICE_CONFIG_CERTIFICATION_DECLARATION路径: connectedhomeip/src/platform/telink/CHIPDevicePlatformConfig.h
附录4 - 工厂数据
工厂数据是在制造过程中写入非易失性存储器的一组设备参数。本章节描述了使用 Telink Matter 来创建和编写工厂数据的过程。
工厂数据参数集包括不同类型的信息,例如关于设备证书、加密密钥、设备标识符,以及硬件。所有的这些参数都是特定于厂商的,并且在制造过程中,必须添写到设备的持久性存储器中。工厂数据参数将会在设备启动时被读取,然后它们可以被用在 Matter 栈和用户应用程序中(例如在配网过程中)。
所有的工厂数据参数都受保护,以免于被软件修改。在设备使用周期内,固件的数据参数集必须保持不变。在实现固件时,除了某些厂商定义的情况,您必须确保在设备固件更新或恢复出厂设置期间,工厂数据不被重写或覆盖。
对于 Telink 平台,工厂数据默认存储在内部闪存的一个单独的分区中。
概述
您可以用多种方式实现工厂数据组件表,只要最终的 HEX/BIN 文件包含表中定义的所有强制的组件。
在本节中,生成工厂数据和使用工厂数据构建一个示例应用描述了其中一种由Telink平台维护者创建的工厂数据集的实现方式。
在此过程结束时,您将得到一个包含 CBOR
格式的工厂数据分区的十六进制和二进制文件。
工厂数据访问器是一个组件,它从设备的持久存储中读取和解析工厂数据参数,并创建一个接口,将它们全部提供给 Matter 栈和用户应用程序。
工厂数据访问器的默认的实现认定存储在设备闪存中的工厂数据是以 CBOR
格式提供的。但是,也可以不使用Telink脚本来生成工厂数据集,而是实现另一个解析器和工厂数据访问器。如果新提供的实现和工厂数据提供程序中所规定的一致,则这是可能的。
注意:本功能还没有提供工厂数据分区的加密和安全性。
工厂数据组件表
下表列出了工厂数据集的参数:
Key name | Full name | Length | Format | Conformance | Description |
---|---|---|---|---|---|
count | number of factory binaries | 4 B | uint32 | optional | 要产生的生成分区二进制文件的数量。默认值为 1。 |
output | output directory | N/A | ASCII string | optional | 存储生成数据的输出路径。 |
spake2-path | spake2 path | N/A | ASCII string | mandatory | 提供 Spake2+ 工具路径 |
chip-tool-path | chip tool path | N/A | ASCII string | mandatory | 提供 chip-tool 路径 |
chip-cert-path | chip cert path | N/A | ASCII string | mandatory | 提供 chip-cert 路径 |
overwrite | overwrite | N/A | bool | optional | 如果输出目录存在,此参数允许生成新的工厂数据并覆盖它。 |
in-tree | in Matter tree | N/A | bool | optional | 仅在从 Matter 源代码构建工厂数据时使用它。 |
enable-key | enable key | N/A | byte string | optional | 仅在认证测试期间使用,不应出现在生产设备上。 |
passcode | SPAKE passcode | 4 B | uint32 | optional | 配对密码是一个 27 位无符号整数,用作配网期间的所有权证明。它的值必须限制在从“0x0000001”到“0x5F5E0FE”(十进制的“00000001”到“99999998”)之间的值,不包括以下无效密码值: 00000000 , 11111111 , 22222222 , 33333333 , 44444444 , 55555555 , 66666666 , 77777777 , 88888888 , 99999999 , 12345678 , 87654321 。 |
spake2-it | SPAKE2+ iteration counter | 4 B | uint32 | mandatory | SPAKE2+ 迭代计数器是在生成 SPAKE2+ 验证程序期间使用的加密过程中 PBKDF2(密钥派生函数)交互的数量。 |
discriminator | Discriminator | 2 B | uint16 | mandatory | 与设置代码中同名字段匹配的 12 位值。 鉴别码在发现过程中使用。 |
commissioning-flow | commisioning flow | 4 B | uint32 | optional | 设备配网流程, 0:Standard, 1:User-Intent, 2:Custom. 默认值为 0,选项为 [0, 1, 2] |
discovery-mode | discovery mode | 4 B | uint32 | optional | 可配网设备网络发现技术。 0:WiFi-SoftAP, 1:BLE, 2:On-network. 默认为 BLE, 选项为 [0, 1, 2] |
vendor-id | vendor ID | 2 B | uint16 | mandatory | CSA为负责生产设备的组织分配的ID。 |
vendor-name | vendor name | <1, 32> B | ASCII string | mandatory | 一个人类可读的供应商名称,它提供一个简单的字符串,其中包含用于应用程序和Matter栈目的的设备供应商标识。 |
product-id | product ID | 2 B | uint16 | mandatory | 设备供应商分配的唯一ID,用于标识产品。它默认为CSA分配的ID,用于指定非生产或测试产品。 |
product-name | product name | <1, 32> B | ASCII string | mandatory | 一个人类可读的产品名称,它提供一个简单的字符串,其中包含用于应用程序和Matter栈目的的产品标识。 |
hw-ver | hardware version | 2 B | uint16 | mandatory | 硬件版本号,指定了设备的硬件的版本号码。值的含义和版本控制方案由供应商定义。 |
hw-ver-str | hardware version string | <1, 64> B | uint16 | mandatory | 一个硬件版本字符串参数,指定设备的硬件版本,作为比硬件版本整型值更用户友好的值。值的含义和版本控制方案由供应商定义。 |
mfg-date | manufacturing date | <8, 10> B | ISO 8601 | mandatory | 制造日期指定设备制造的日期。使用的日期格式是 ISO 8601,例如 YYYY-MM-DD 。 |
serial-num | serial number | <1, 32> B | ASCII string | mandatory | 序列号参数定义了制造设备的唯一编号。序列号的最大长度为32个字符。 |
enable-rotating-device-id | enable rotating device id | N/A | bool | optional | 在生成的二进制文件中启用轮换设备id |
rd-id-uid | rotating device ID unique ID | <16, 32> B | byte string | mandatory | 轮换设备ID的唯一ID,由随机生成的128位(或更长)八位字节字符串组成。在初次引入设备后,该参数应防止通过空中读取或写入,并在设备的生命周期内保持固定。 |
cert | certificate path | N/A | ASCII string | optional | 输入的证书文件为PEM格式。 |
key | certificate key path | N/A | ASCII string | optional | PEM格式的输入密钥文件。 |
cert-dclrn | certificate declaration path | N/A | ASCII string | mandatory | DER格式的证书声明文件。 |
dac-cert | DAC certificate path | N/A | ASCII string | optional | 输入的DAC证书文件为PEM格式。 |
dac-key | DAC certificate key path | N/A | ASCII string | optional | 输入的DAC私钥文件为PEM格式。 |
cn-prefix | common name prefix | N/A | ASCII string | optional | 生成的证书主体的通用名称前缀。 |
lifetime | certificate lifetime | 4 B | uint32 | optional | 生成的证书的有效期。默认值是4294967295(如果没有指定),这表示证书没有明确定义的过期日期。 |
valid-from | certificate start date | <8, 19> B | ISO 8601 | optional | 证书有效期的开始日期,格式为 YYYY-MM-DD [ HH:MM:SS ]。默认为当前日期。 |
paa | PAA | N/A | bool | optional | 使用输入证书 cert 作为PAA证书。 |
pai | PAI | N/A | bool | optional | 使用输入证书 cert 作为PAI证书。 |
product-label | product label | N/A | ASCII string | optional | 产品标签。 |
product-url | product url | N/A | ASCII string | optional | 产品网址。 |
part_number | part number | N/A | ASCII string | optional | 提供可读的产品编号。 |
offset | factory partition offset | 4 B | uint32 | mandatory | 分区偏移量-设备NVM内存中的地址,工厂数据将存储在这里 |
size | factory partition size | 2 B | uint16 | mandatory | 最大分区大小 |
工厂数据格式
工厂数据集必须保存到一个十六进制或二进制文件中,该文件可以写入到Matter设备的闪存中。
在Telink示例中,工厂数据集以 CBOR
格式表示,并存储在十六进制或二进制文件中。然后,该文件将被烧录到一个设备上。
JSON 格式被用作一种中间的、人类可读的数据表示。该格式由JSON模式文件规定。
工厂数据集的所有参数都是强制参数或可选参数:
-
必须始终提供强制性参数,因为示例在进行配网进入Matter网络时需要它们。
-
可选参数可用于开发和测试目的。例如,用户数据参数包含了特定制造商所需要的且不包含在强制性参数中的所有数据。
在工厂数据集中,使用了以下格式:
-
uint16
和uint32
-- 这些是分别表示两字节长度无符号整数,和四字节长度无符号整数的数字格式。此值以大端顺序存储在十六进制文件中 -
Byte string
-- 该参数表示在0到255之间(包括255)的整数序列,没有任何编码。由于JSON格式不允许使用字节字符串,因此将hex:
前缀添加到参数中,并将其转换为十六进制字符串。
例如,一个ASCII字符串 abba
在JSON文件中被表示为十六进制:hex:61626261
,然后以 0x61626261
存储在十六进制文件中。
JSON文件中的十六进制字符串长度是字节字符串加上前缀大小的两倍。
-
ASCII string
是ASCII编码中的字符串表示形式,没有空终止。 -
ISO 8601
格式是一种日期格式,表示以YYYY-MM-DD
或YYYYMMDD
格式提供的日期。 -
存储在工厂数据中的所有证书都以X.509格式提供。
启用工厂数据支持
默认情况下,在所有的 Telink 示例中都禁用了工厂数据支持,并且 Telink 设备使用了来自 Matter 核心的预定义参数,您不应该更改这些参数。
要开始使用存储在闪存和 Telink 平台中的工厂数据和 Telink 平台的 Factory Data Provider,请使用以下选项构建一个示例:
west build -- -DCONFIG_CHIP_FACTORY_DATA=y
生成工厂数据
本节介绍使用以下 Telink Python 脚本生成工厂数据。
依赖项
在使用生成器工具之前,请确保您已具备以下工具。
1) 使用以下命令在 path/to/connectedhomeip/build/out/host
生成 chip-tool, spake2p and chip-cert
cd path/to/connectedhomeip
source scripts/activate.sh
gn gen build/out/host
ninja -C build/out/host
2) 在 $PATH 中加入工具路径
export PATH="$PATH:path/to/connectedhomeip/build/out/host"
(2) 在设备上准备工厂数据分区
工厂数据分区是设备持久存储中存储工厂数据集的区域。这个区域在 DeviceTrees 文件里进行配置。
- 对于 Matter v1.1-branch 分支,配置文件在Matter工程中,路径为:
connectedhomeip/src/platform/telink/tlsr9518adk80d.overlay
- 对于 Matter master 分支,配置文件在Matter工程中。
不过,将对分区的声明从 tlsr9528a.overlay
中提取出来,分别写作 tlsr9528a_2m_flash.overlay
和 tlsr9528a_4m_flash.overlay
。那么,可以根据所选的芯片的 Flash 尺寸,去选择合适的配置文件。
若要准备一个客制化的支持工厂数据的示例,请在 tlsr9528a-common.dtsi
、tlsr9518adk80d.overlay
或 Xm_flash.overlay
文件中添加或修改一个名为 factory-data
的分区。分区大小应该是一个 flash page 的倍数(对于B91 SoC,单个 page 大小等于 4kB)。
可以参考闪存布局 中的工厂数据分区作为示例,详细在 Xm_flash.overlay
文件中。
factory-data
分区大小被设置为一个 flash page 大小(4kB)。
脚本使用
若要使用此脚本,请完成以下步骤:
(1) 进入 connectedhomeip
根目录。
(2) 使用 -h
选项运行脚本,以查看所有可能的选项:
python scripts/tools/telink/mfg_tool.py -h
(3) 准备一个参数列表:
a. 填写所有强制性参数:
--serial-num --vendor-id, --product-id, --vendor-name, --product-name, --mfg-date, --hw-ver, --hw-ver-str, --enable-rotating-device-id, --spake2-path, --chip-tool-path, --chip-cert-path, --offset, --size
b. 添加输出文件路径:
--output <output_dir>
c. 添加证书声明路径(必选):
-cd <path to Certificate Declaration in der format>
d. 指定使用哪个证书:
- 用户:
--dac-cert <path to DAC certificate in pem format>
--dac-key <path to DAC key in pem format>
--cert <path to PAI certificate in pem format>
--key <path to PAI key in pem format>
--pai
- 生成DAC和PAI:
--cert <path to PAA certificate in pem format>
--key <path to PAA key in pem format>
--paa
e. 使用以下选项之一为轮换设备 ID 添加新的唯一 ID:
- 提供一个已存在的 ID:
--rdid--uid <rotating device ID unique ID>
- 生成一个新的 ID 并提供:
--enable-rotating-device-id
f. (可选)指定您自己的密码:
--passcode <passcode>
g. (可选)指定您自己的鉴别码:
--discriminator <discriminator>
h. (可选)添加覆盖现有输出文件的请求:
--overwrite
i. 指定分区偏移量和大小:
--offset <partition_address_in_memory>
--size <partition_size>
In this command:
-
是设备的持久存储区域中的地址,分区数据集将存储在其中。 -
是设备持久存储区域中分区的大小。根据这个值检查新数据,看它的大小是否适合。
重要提示:
对 Matter v1.1-branch 分支使用:
--offset 0x104000 --size 0x1000
对最新的 Matter master 分支(2MB flash)使用:
--offset 0x107000 --size 0x1000
(4) 使用已准备好的参数列表运行该脚本:
python3 mfg_tool.py <arguments>
例如,对Python脚本的最终调用看起来类似于下面的用法:
$ python3 scripts/tools/telink/mfg_tool.py \
--vendor-id 0xFFF2 --product-id 0x8001 \
--serial-num AABBCCDDEEFF11223344556677889900 \
--vendor-name "Telink Semiconductor" \
--product-name "not-specified" \
--mfg-date 2022-12-12 \
--hw-ver 1 \
--hw-ver-str "prerelase" \
--enable-rotating-device-id \
--pai \
--key credentials/test/attestation/Chip-Test-PAI-FFF2-8001-Key.pem \
--cert credentials/test/attestation/Chip-Test-PAI-FFF2-8001-Cert.pem \
-cd credentials/test/certification-declaration/Chip-Test-CD-FFF2-8001.der \
--spake2-path build/out/host/spake2p \
--chip-tool-path build/out/host/chip-tool \
--chip-cert-path build/out/host/chip-cert \
--offset 0x107000 --size 0x1000 \
--out ./factory_data_for_2mb_flash
作为上述示例的结果,下面列出的文件将被创建:
factory_data_for_2mb_flash
├── device_sn.csv
└── fff2_8001
└── aabbccddeeff11223344556677889900
├── factory_data.bin
├── factory_data.hex
├── internal
│ ├── DAC_cert.der
│ ├── DAC_cert.pem
│ ├── DAC_key.pem
│ ├── DAC_private_key.bin
│ ├── DAC_public_key.bin
│ └── pai_cert.der
├── onb_codes.csv
├── pin_disc.csv
├── qrcode.png
└── summary.json
(5) (可选示例)生成5个工厂分区 [可选参数 :--count]
$ python3 scripts/tools/telink/mfg_tool.py --count 5 -v 0xFFF2 -p 0x8001 \
--serial-num AABBCCDDEEFF11223344556677889900 \
--vendor-name "Telink Semiconductor" \
--product-name "not-specified" \
--mfg-date 2022-12-02 \
--hw-ver 1 \
--hw-ver-str "prerelase" \
--enable-rotating-device-id \
--pai \
--key credentials/test/attestation/Chip-Test-PAI-FFF2-8001-Key.pem \
--cert credentials/test/attestation/Chip-Test-PAI-FFF2-8001-Cert.pem \
-cd credentials/test/certification-declaration/Chip-Test-CD-FFF2-8001.der \
--spake2-path build/out/host/spake2p \
--chip-tool-path build/out/host/chip-tool \
--chip-cert-path build/out/host/chip-cert \
--offset 0x107000 --size 0x1000 \
--out ./factory_data_for_2mb_flash
作为上述示例的结果,下面列出的文件将被创建:
factory_data_for_2mb_flash
├── device_sn.csv
└── fff2_8001
├── aabbccddeeff11223344556677889900
│ ├── factory_data.bin
│ ├── factory_data.hex
│ ├── internal
│ │ ├── DAC_cert.der
│ │ ├── DAC_cert.pem
│ │ ├── DAC_key.pem
│ │ ├── DAC_private_key.bin
│ │ ├── DAC_public_key.bin
│ │ └── pai_cert.der
│ ├── onb_codes.csv
│ ├── pin_disc.csv
│ ├── qrcode.png
│ └── summary.json
├── aabbccddeeff11223344556677889901
│ ├── factory_data.bin
│ ├── factory_data.hex
│ ├── internal
│ │ ├── DAC_cert.der
│ │ ├── DAC_cert.pem
│ │ ├── DAC_key.pem
│ │ ├── DAC_private_key.bin
│ │ ├── DAC_public_key.bin
│ │ └── pai_cert.der
│ ├── onb_codes.csv
│ ├── pin_disc.csv
│ ├── qrcode.png
│ └── summary.json
├── aabbccddeeff11223344556677889902
│ ├── factory_data.bin
│ ├── factory_data.hex
│ ├── internal
│ │ ├── DAC_cert.der
│ │ ├── DAC_cert.pem
│ │ ├── DAC_key.pem
│ │ ├── DAC_private_key.bin
│ │ ├── DAC_public_key.bin
│ │ └── pai_cert.der
│ ├── onb_codes.csv
│ ├── pin_disc.csv
│ ├── qrcode.png
│ └── summary.json
└── aabbccddeeff11223344556677889903
├── factory_data.bin
├── factory_data.hex
├── internal
│ ├── DAC_cert.der
│ ├── DAC_cert.pem
│ ├── DAC_key.pem
│ ├── DAC_private_key.bin
│ ├── DAC_public_key.bin
│ └── pai_cert.der
├── onb_codes.csv
├── pin_disc.csv
├── qrcode.png
└── summary.json
注意:默认情况下,覆盖现有输出目录是禁用的。这意味着您不能在与现有文件相同的位置创建具有相同名称的新目录。要允许覆盖,请将
--overwrite
选项添加到 Python 脚本的参数列表中。
使用工厂数据构建一个示例应用
您可以使用上述的生成工厂数据部分中描述的说明手动生成工厂数据集。也可以使用 Telink 平台构建系统,该系统使用 Kconfig 选项自动创建工厂数据内容。
要启用自动生成工厂数据集,请转到示例应用的目录,并使用以下选项构建示例应用:
west build -- -DCONFIG_CHIP_FACTORY_DATA=y -DCONFIG_CHIP_FACTORY_DATA_BUILD=y
或者,您还可以将 CONFIG_CHIP_FACTORY_DATA_BUILD=y
的Kconfig设置添加到示例应用的 prj.conf
文件中。
注意,如果这一步遇到了 ModuleNotFoundError 的报错,请在 connectedhomeip 目录下执行以下命令更新依赖项后,再次尝试构建:
.environment/pigweed-venv/bin/python3 -m pip install -r scripts/setup/requirements.telink.txt
构建成功后会得到开启了工厂数据分区的应用的固件,和独立的工厂数据集二进制文件,烧录时需要分别烧录它们。
每个工厂数据参数都有一个默认值。这些在 Kconfig文件 中有描述。要为工厂数据参数设置一个新值,可以通过将其作为构建参数列表提供,或使用交互式 Kconfig 界面来完成。
提供工厂数据参数作为生成参数列表
这种提供工厂数据的方式可以与第三方构建脚本一起使用,因为它只使用一个命令。可以通过west命令的附加选项开启工厂数据功能:
west build -- -DCONFIG_CHIP_FACTORY_DATA=y --DCONFIG_CHIP_FACTORY_DATA_BUILD=y --DCONFIG_CHIP_DEVICE_DISCRIMINATOR=0xF11
或者,您也可以将相关的 Kconfig 选项行添加到示例应用的 prj.conf
文件中。
分开烧录应用固件和工厂数据集
我们的应用固件和工厂数据集都是二进制 BIN 文件,可以使用 BDT 工具和 Telink burning key 烧录到设备的Flash指中。 需要注意的是,需要根据上面章节设置的flash分区实际情况,去选择工厂数据集的烧录地址。
烧录时使用 Telink BDT 工具的多地址烧录即可:
(1) 选择 Tool 中的 Multi-address download
(2) 此处以 v1.1-branch 分支上的固件为例,工厂数据的偏移值是 0x104000
:
设置工厂数据
将独立的工厂数据集,合并到示例应用的固件之中的一种方法,是使用在使用工厂数据构建一个示例应用中描述的Telink平台构建系统,并使用附加下面的选项构建示例应用 -DCONFIG_CHIP_FACTORY_DATA_MERGE_WITH_FIRMWARE=y
:
$ west build -- \
-DCONFIG_CHIP_FACTORY_DATA=y \
-DCONFIG_CHIP_FACTORY_DATA_BUILD=y \
-DCONFIG_CHIP_FACTORY_DATA_MERGE_WITH_FIRMWARE=y
为了更好地理解以上设置项所对应的需求场景,可以参见下面的表格:
场景 | 需求 | 描述 |
---|---|---|
Scenario(1) | 不需要配置工厂数据集,也不需要开启工厂数据分区的应用固件 | 将采用代码中的硬编码数值做为厂商的数据。 |
Scenario(2) | 需要,而且已有工厂数据集,但仅需要开启工厂数据分区的应用固件 | 工厂数据集不会合并到最终固件的二进制文件中。分区镜像必须以其他方式烧录,否则在启动时会报告运行时错误,因为工厂数据访问器期望工厂数据分区内有有效数据存在。 |
Scenario(3) | 需要,但没有工厂数据集,去生成工厂数据集,并且包含生成的工厂数据集的应用固件 | 工厂数据集将由构建系统创建,并合并到最终固件的二进制文件中。推荐用于开发目的。 |
Scenario(4) | 需要,而且已有工厂数据集,并且需要包含已有的工厂数据集的应用固件 | 构建系统期望在 connectedhomeip/config/telink/chip-module/CMakeLists.txt 中指定的路径(例如${PROJECT_BINARY_DIR}/factory/factory_data.bin)上,具有外部生成的工厂数据集(例如由“脚本使用”章节中描述的脚本生成)。 |
对选择设置项 (根据不同的需求场景) | (1) | (2) | (3) | (4) |
---|---|---|---|---|
CONFIG_CHIP_FACTORY_DATA | n | y | y | y |
CONFIG_CHIP_FACTORY_DATA_BUILD | don't care | don't care | y | n |
CONFIG_CHIP_FACTORY_DATA_MERGE_WITH_FIRMWARE | don't care | n | y | y |
您还可以构建一个使用自动生成的新CD、DAC和PAI证书的示例应用。新生成的证书将被自动添加到工厂数据集里。要生成新证书,通过使用附加选项构建示例应用来禁用默认证书 -DCHIP_FACTORY_DATA_USE_DEFAULT_CERTS=n
:
$ west build -- \
-DCONFIG_CHIP_FACTORY_DATA=y \
-DCONFIG_CHIP_FACTORY_DATA_BUILD=y \
-DCONFIG_CHIP_FACTORY_DATA_MERGE_WITH_FIRMWARE=y \
-DCONFIG_CHIP_FACTORY_DATA_USE_DEFAULT_CERTS=n
注意:要使用Telink平台构建系统生成新的证书,您需要系统变量PATH中的
chip-cert
可执行文件。要了解如何获取chip-cert
,请参考构建matter工具中的步骤,并将新构建的可执行文件添加到系统变量PATH中。Cmake构建系统将自动找到这个可执行文件。
然后,在示例应用目录中,可以使用生成的一个二进制固件,便可以同时写入应用固件和新生成的工厂数据。
使用自己的工厂数据实现
上面介绍的工厂数据生成过程仅是对Telink平台有效的示例应用。您可以创建一个包含任意格式的所有工厂数据组件表的HEX文件,然后实现一个解析器来读取所有参数并将它们传递给提供程序。
每个制造商都可以通过在Matter栈中实现解析器和工厂数据访问器来自行实现工厂数据集。使用Telink工厂数据提供程序和工厂数据解析器作为示例。
根据用途和格式的不同,您可以用不同的方式从设备的闪存中读取工厂数据集。在Telink示例中,工厂数据以 CBOR
格式存储。
设备使用工厂数据解析器读取输出原始数据,将其解码并存储在 FactoryData
结构中。
工厂数据提供程序实现使用这个解析器获取所有需要的工厂数据参数,并将它们提供给Matter核心。
在Telink示例中, FactoryDataProvider
是一个模板类,继承自DeviceAttestationCredentialsProvider
、CommissionableDataProvider
和 DeviceInstanceInfoProvider
类。您的自定义实现还必须继承这些类并实现它们的功能来从设备的闪存中获取所有工厂数据集。
这些类是虚类,需要由派生类重写。要覆盖继承的类,请完成以下步骤:
(1) 覆盖以下方法:
// ===== Members functions that implement the DeviceAttestationCredentialsProvider
CHIP_ERROR GetCertificationDeclaration(MutableByteSpan & outBuffer) override;
CHIP_ERROR GetFirmwareInformation(MutableByteSpan & out_firmware_info_buffer) override;
CHIP_ERROR GetDeviceAttestationCert(MutableByteSpan & outBuffer) override;
CHIP_ERROR GetProductAttestationIntermediateCert(MutableByteSpan & outBuffer) override;
CHIP_ERROR SignWithDeviceAttestationKey(const ByteSpan & messageToSign, MutableByteSpan & outSignBuffer) override;
// ===== Members functions that implement the CommissionableDataProvider
CHIP_ERROR GetSetupDiscriminator(uint16_t & setupDiscriminator) override;
CHIP_ERROR SetSetupDiscriminator(uint16_t setupDiscriminator) override;
CHIP_ERROR GetSpake2pIterationCount(uint32_t & iterationCount) override;
CHIP_ERROR GetSpake2pSalt(MutableByteSpan & saltBuf) override;
CHIP_ERROR GetSpake2pVerifier(MutableByteSpan & verifierBuf, size_t & verifierLen) override;
CHIP_ERROR GetSetupPasscode(uint32_t & setupPasscode) override;
CHIP_ERROR SetSetupPasscode(uint32_t setupPasscode) override;
// ===== Members functions that implement the DeviceInstanceInfoProvider
CHIP_ERROR GetVendorName(char * buf, size_t bufSize) override;
CHIP_ERROR GetVendorId(uint16_t & vendorId) override;
CHIP_ERROR GetProductName(char * buf, size_t bufSize) override;
CHIP_ERROR GetProductId(uint16_t & productId) override;
CHIP_ERROR GetSerialNumber(char * buf, size_t bufSize) override;
CHIP_ERROR GetManufacturingDate(uint16_t & year, uint8_t & month, uint8_t & day) override;
CHIP_ERROR GetHardwareVersion(uint16_t & hardwareVersion) override;
CHIP_ERROR GetHardwareVersionString(char * buf, size_t bufSize) override;
CHIP_ERROR GetRotatingDeviceIdUniqueId(MutableByteSpan & uniqueIdSpan) override;
(2) 将新创建的解析器和提供程序文件移动到项目目录中。
(3) 把文件添加到 CMakeList.txt
中。
(4) 禁用工厂数据提供程序的默认实现和Telink实现,以开始使用您自己的工厂数据解析器和提供程序实现。 这可以通过以下方式之一来实现:
-
把Kconfig设置
CONFIG_CHIP_FACTORY_DATA_CUSTOM_BACKEND=y
加到prj.conf
文件中。 -
用以下选项构建一个示例:
west build -- -DCONFIG_CHIP_FACTORY_DATA_CUSTOM_BACKEND=y
附录5 - ZAP工具
ZCL Advanced Platform(ZAP)
ZCL Advanced Platform(ZAP)是一个基于 Matter Clusters 的 node.js 模板引擎,为 Matter应用程序和 SDK 提供以下功能:
-
在 GUI 界面配置 Matter Endpoint、Cluster、Attribute,以及其他的设备功能
-
创建自动生成数据模型定义、回调函数和其他 Matter 源代码的模板。
-
创建和使用预配置的 ZAP 文件以包含在您的 SDK 中
安装ZAP
请参考 scripts/zap.json
和 scripts/tools/zap/zap_execution.py
来确认支持的最早 ZAP 版本 ZAP_VERSION。例如:ZAP_VERSION=v2023.10.14-nightly
mkdir -p /opt/zap-${ZAP_VERSION}
cd /opt/zap-${ZAP_VERSION}
wget https://github.com/project-chip/zap/releases/download/${ZAP_VERSION}/zap-linux-x64.zip
unzip zap-linux-x64.zip
可能需要添加 sudo
来获取在 opt
和 usr
路径下操作的权限。
使用 ZAP
(1) 在安装了 ZAP 之后,可以在 ZAP 安装目录通过运行可执行文件启动:
./zap
在运行之后可以看到 ZAP 界面:
(2) 打开 zap 文件
点击菜单栏中的 "File",选择 "Open File",在以下跳出的界面中选择您想要打开的 .zap 文件, ZAP 文件是定义端点、命令、属性和其他设备功能的 JSON 模板,例如,light-switch-app.zap 在 connectedhomeip/examples/light-switch-app/light-switch-common
选中后点击右下角的 Open,就可以看到如下界面:
(3) 更改产品制造商
在右上角的 ZCL GLOBAL OPTION 中可以更改产品制造商。泰凌微电子的序号为为 Telink Micro(0x1141)
(4) 配置 zap 文件
- 在 Endpoint 1 中点击 "EDIT",可以选择不同的 Matter 设备
-
在右侧就是 Endpoint 1 中的 Cluster,可以自己选择 Cluster 的状态,设备是作为 Sever 还是作为 Client,或是 Not Enabled 的状态。
-
在 Cluster 的右侧,可以点击小齿轮进入属性的界面:
图中是 Identify Cluster 的界面,在这里您可以启用或禁用属性,设置各种属性选项。
- 点击上方的 COMMANDS,可以为这个 Cluster 配置命令
如图,在 Identify Cluster 中启用了 Identify,TrrigerEffect 命令。
(5) 生成ZAP源文件
在您对 Endpoint 有任何的修改以后,可以点击左上角的 File 中的 save 选项进行保存。
附录6 - Mars_B91
概述
Mars_B91 是泰凌为推广芯片产品而生的一套子母开发板。本附录以基于 Telink Matter V1.2 SDK 开发的 lighting-app 和temperature-measurement-app 为例,将 Mars_B91 开发板作为 Matter 设备添加到 Apple 的智能家居生态之中。用户可以通过 iPhone 上的 Home App 控制灯的开关/亮度/色温,或者读取到环境温度。
Mars_B91开发板
Mars_B91 开发板分为底板和子板两部分,子板型号为 Mars_B91_V1.1
,底板型号为 Mars_B91_Model_A_V2.2
。
Mars_B91_v1.1
是一款模组板,其核心芯片为TLSR9218,支持ZigBee,BLE,Thread等通讯协议。用户可以方便地进行芯片评估,也可把模组板集成到自己的电路系统中,为自己的系统扩展无线功能。
Mars_B91_V1.1
原理图 https://github.com/telink-semi/openboard/blob/main/opensdk/Mars_B91/Schematic/Mars_B91/mboard_core.pdf
Mars_B91_Model_A_V2.2
(又名 Mars_B91_Mother_V2.2
)是为 Mars_B91_v1.1
子板提供支持的底板。该底板内置了丰富的传感器和接口,通过引脚复用,底板支持IIC、UART、PWM、ADC等多种功能,同时具备USB调试接口。
Mars_B91_Model_A_V2.2
原理图 https://github.com/telink-semi/openboard/blob/main/opensdk/Mars_B91/Schematic/Mars_B91_Mother_V2.2/Mars_B91_Mother_V2.2_Sch.pdf
下面是Matter应用在Mars_B91 开发板上所使用到的一些外设:
(1) 底板上带有温湿度传感器SHT30,可以采集环境温度。
(2) 有数字RGB LED灯珠WS2812,可以发出不同颜色的光。
(3) 有拨轮按键,连续向左按三次可以触发Factory Reset,恢复出厂数据。
(4) 底板上有两个USB-C接口,正面左边为 USB_UART 口,Matter设备log从此口输出,右边为 USB 口,可通过此口烧录固件。
(5) 子板上有一个红色LED灯,用于指示设备状态。
关于
Mars_B91_Model_A_V2.2
外设的详细介绍,可以访问 https://debug.telink-semi.cn/doc/site/boards/Mars_B91_Model_A_V2.2 进行了解
将Matter设备配网进入智能家居生态
拓扑结构
将以Apple Home为例进行配网。
配网所需的设备
-
Mars_B91开发板 作为Matter温度传感器设备或Matter灯设备
-
Apple HomePod Mini 作为Matter网络的Border Router
-
无线路由器 提供WiFi接入点,为Apple HomePod Mini提供数据校验
-
iPhone手机 作为Commissioner,用户控制设备入网、获取温度数据或者控制灯的平台
配网所需的软件
-
iPhone手机系统iOS17.0.3
-
Apple HomePod Mini固件版本17.1
-
包含 Bootloader 的 Telink Matter V1.2 lighting-app 固件
-
单独的 Telink Matter V1.2 temperature-measurement-app 固件
可以通过下面网盘下载链接获取到所要使用的预置固件,同时里面也包含了一些做为示例的视频片段: https://drive.weixin.qq.com/s?k=AKwA0AfNAA8yj9zSEr
配网操作步骤
下面将以色温灯为例,介绍配网的步骤:
(1) 将无线路由器和HomePod Mini上电,建立Apple网络。
(2) 包含 Bootloader 的固件 ColorLighting_v1.bin
已预先烧录到开发板上,将Mars_B91开发板如图连接到电脑,然后将开发板上电。
USB-C数据线接到开发板USB_UART口,串口配置信息115200,8N1,电脑端打开任意串口工具查看设备输出log。
(3) 等待若干秒,待 Bootloader 完成自检,可以观察到开发板的红灯短亮并闪烁,从设备输出log中找到设备二维码的网址(见图中红色框)。
(4) 复制网址到浏览器获取二维码。
(5) 使用iPhone将设备添加到 Apple Home 的生态环境。
手机上执行配网的操作流程和附录一中 Apple Matter Demo 相近,详细的步骤可以参考网盘中所提供的视频 lighting-attaching.mp4
。
(6) 添加成功后Home界面会出现一个灯组件。
(7) 操纵色温灯
色温灯除了拥有打开、关闭和调节亮度的功能外,还可以支持调整至不同的颜色。在 Apple Home 上详细地控制方法可以参考示例视频 light-control.mp4
。
以DFU方式更新固件
我们还提供了不包含 Bootloader 的色温灯和温度计应用的固件。本小节将介绍如何通过 DFU 方式更新设备固件,将新的固件 TemperatureSensor_v2.signed.bin
更新到 Mars_B91 开发板。
硬件要求
-
Mars_B91 作为Matter设备
-
Linux主机 运行DFU软件,至少带有一个USB端口
软件要求
dfu-util
工具,用于更新固件
连接方式
DFU操作步骤
(1) 在Linux主机上打开命令行,输入命令,安装 `dfu-util``
$ sudo apt install dfu-util
(2) 进行DFU前,最好先对设备进行factory reset。
如果设备还未上电,先上电,待红色LED开始闪烁后,将开发板上的拨轮按键向左拨动3次,直到红色LED恢复短亮,并闪烁表示重置完成,然后拔下设备。
(3) 将设备的拨轮按键向中间按下,按住按键同时用数据线连接到设备的USB口,设备红色LED常亮代表进入DFU模式。
(4) 在Linux主机命令行输入命令
$ sudo dfu-util --alt 1 --download TemperatureSensor_v2.signed.bin
本文以应用的固件
TemperatureSensor_v2.signed.bin
为例,实际使用中,可以采用自己的固件路径名替换即可。
(5) DFU更新
更新过程可以参考示例视频 DFU-process.mp4
,进度条结束后还需要固件校验,不要断电保持连接直到红色LED开始短亮并闪烁,此时DFU完成。
验证更新固件
将温度计添加到智能家居生态的的步骤和色温灯一样,完成添加后点击设备即可看到如图所示界面。
成功地按照上一节步骤将温度传感器在 Apple Home 生态中完成配网后,可以在 iPhone 上读取环境温度。