1. 简介
由 Google Nest 团队发布的 OpenThread 是 Thread® 网络协议的开源实现,旨在加快智能互联家居产品的开发速度。线程规范针对家用和商用建筑应用,定义了基于 IPv6 的可靠、安全、低功耗的无线设备到设备通信协议。
Espressif 已移植了基于 FreeRTOS 和 LwIP 的 OpenThread 堆栈,使开发者能够快速构建 Thread 网络。相关源代码可以从 GitHub 获取。同时,Espressif 还基于 RTOS 实现了线程边界路由器。
在此 Codelab 中,您将在真实硬件上对 OpenThread 进行编程,创建和管理 Thread 网络,并在节点之间传递消息。
学习内容
- 构建 OpenThread CLI 二进制文件并将其刷写到 ESP 板。
- 正在构建边界路由器并刷写到 ESP 线程边界路由器板。
- 使用 ESP Monitor 和 OpenThread CLI 手动管理 Thread 节点。
- 在线程边界路由器上构建 Thread 网络。
- 对设备进行安全调试,以将其连接到 Thread 网络。
- 在 Thread 节点之间 ping IPv6 地址。
- 使用 UDP 在 Thread 节点之间传递消息。
所需条件
硬件:
软件:
2. 使用入门
- ESP-IDF 安装。
请按照 ESP-IDF 编程指南安装软件开发环境。
- 克隆 ESP 线程边界路由器 SDK。
ESP-THREAD-BR 是官方 ESP 线程边界路由器 SDK。它支持构建 Thread 边界路由器的所有基本网络功能,并集成了丰富的产品级功能,以实现快速产品化。
$ cd <your-local-workspace> $ git clone --recursive https://github.com/espressif/esp-thread-br.git
3. 构建和刷写
如需在包含 IEEE 802.15.4 模块的 ESP 板上构建和刷写 ot-cli-ftd 二进制文件,您可以参阅 ESP-IDF 示例 ot_cli 了解详情:
$ cd <your-idf-path>/examples/openthread/ot_cli $ idf.py set-target <your-board-type>
通过 menuconfig 启用联接功能:
$ idf.py menuconfig
组件配置 >OpenThread >启用 Joiner,然后构建并刷写。
$ idf.py -p <your-local-port> build flash monitor
如需在 ESP 线程边界路由器板上构建和刷写 ot-br 二进制文件,您需要先构建 RCP 二进制文件。此 RCP 二进制文件无需明确刷写到 ESP 线程边界路由器板上的设备。它将包含在边界路由器二进制文件中,并在首次启动(或 RCP 固件发生更改)时刷写到 ESP32-H2 芯片。如需了解详情,请参阅 ESP 线程 BR 文档:
$ cd <your-idf-path>/examples/openthread/ot_rcp $ idf.py set-target esp32h2 $ idf.py build $ cd <your-esp-thread-br-path>/examples/basic_thread_border_router $ idf.py set-target esp32s3
通过 menuconfig 启用调试器功能:
$ idf.py menuconfig
组件配置 >OpenThread >启用 Commissioner,然后进行构建和刷写。
$ idf.py -p <your-local-port> build flash monitor
4. 在线程边界路由器上构建 Thread 网络
现在,您可以在 ESP 线程边界路由器板 (BR Commissioner) 上使用 OpenThread 命令行构建 Thread 网络:
## BR Commissioner ## ---------------------- > dataset init new Done > dataset Active Timestamp: 1 Channel: 21 Channel Mask: 0x07fff800 Ext PAN ID: 151975d11bea97b5 Mesh Local Prefix: fd6a:b54b:d6a3:b05a::/64 Network Key: 731ab6a60a64a0a0b14b259b86b2be01 Network Name: OpenThread-1444 PAN ID: 0x1444 PSKc: 54e7f18d2575014da94db09df29c5df0 Security Policy: 672 onrc 0 Done
提交此数据集作为活跃数据集:
> dataset commit active Done
启动 IPv6 接口:
> ifconfig up I (59329) OPENTHREAD: Platform UDP bound to port 49153 Done I (59329) OT_STATE: netif up
启动 Thread 协议操作:
> thread start I(61709) OPENTHREAD:[N] Mle-----------: Role disabled -> detached Done > I(62469) OPENTHREAD:[N] Mle-----------: Attach attempt 1, AnyPartition reattaching with Active Dataset I(69079) OPENTHREAD:[N] RouterTable---: Allocate router id 11 I(69079) OPENTHREAD:[N] Mle-----------: RLOC16 fffe -> 2c00 I(69089) OPENTHREAD:[N] Mle-----------: Role detached -> leader I(69089) OPENTHREAD:[N] Mle-----------: Partition ID 0x28b518c6 I (69099) OPENTHREAD: Platform UDP bound to port 49154
片刻之后,检查设备状态。它应该是领先变体。
> state leader Done >
5. 通过 networkkey 加入 Thread 网络
在此 Codelab 中,有两个带有 IEEE 802.15.4 模块的 ESP 开发板已准备好加入 BR 组建的网络。在此会话中,我们将向网络添加 Board1。
从 BR 获取网络密钥:
## BR Commissioner ## ---------------------- > networkkey 731ab6a60a64a0a0b14b259b86b2be01 Done >
将此网络密钥设置为一个具有 IEEE 802.15.4 模块的 ESP 板(Board1 Joiner):
## Board1 Joiner ## ---------------------- > dataset networkkey 731ab6a60a64a0a0b14b259b86b2be01 Done
提交此数据集作为活跃数据集:
> dataset commit active Done
启动 IPv6 接口:
> ifconfig up Done I (20308) OT_STATE: netif up
启动 Thread 协议操作:
> thread start I(23058) OPENTHREAD:[N] Mle-----------: Role disabled -> detached Done > I(23408) OPENTHREAD:[N] Mle-----------: Attach attempt 1, AnyPartition reattaching with Active Dataset I(30028) OPENTHREAD:[N] Mle-----------: Attach attempt 1 unsuccessful, will try again in 0.288 seconds I(30328) OPENTHREAD:[N] Mle-----------: Attach attempt 2, AnyPartition I(33498) OPENTHREAD:[N] Mle-----------: Delay processing Announce - channel 21, panid 0x1444 I(33758) OPENTHREAD:[N] Mle-----------: Processing Announce - channel 21, panid 0x1444 I(33758) OPENTHREAD:[N] Mle-----------: Role detached -> disabled I(33758) OPENTHREAD:[N] Mle-----------: Role disabled -> detached I(34178) OPENTHREAD:[N] Mle-----------: Attach attempt 1, AnyPartition I(35068) OPENTHREAD:[N] Mle-----------: RLOC16 fffe -> 2c01 I(35068) OPENTHREAD:[N] Mle-----------: Role detached -> child
片刻之后,检查设备状态。它应该是子项。
> state child Done
将角色设置为路由器。
> state router Done I(51028) OPENTHREAD:[N] Mle-----------: RLOC16 2c01 -> 2800 I(51028) OPENTHREAD:[N] Mle-----------: Role child -> router I(51028) OPENTHREAD:[N] Mle-----------: Partition ID 0x28b518c6 >
6. 通过安全调试加入 Thread 网络
在此会话中,我们将通过安全调试将 Board2 添加到网络中:
从巴西专员获取 PSKc 和 panid:
## BR Commissioner ## ---------------------- > pskc 54e7f18d2575014da94db09df29c5df0 Done > panid 0x1444 Done
配置 Board2 的网络信息:
## Board2 Joiner ## ---------------------- > dataset pskc 54e7f18d2575014da94db09df29c5df0 Done > dataset panid 0x1444 Done
提交此数据集作为活跃数据集:
## Board2 Joiner ## ---------------------- > dataset commit active Done
启动 IPv6 接口:
## Board2 Joiner ## ---------------------- > ifconfig up Done I (29146) OT_STATE: netif up
从 Board2 获取 eui64:
## Board2 Joiner ## ---------------------- > eui64 4831b7fffec02be1 Done
在 BR 调试器上,启动调试器并指定可以加入的设备的 eui64
以及连接器凭据,例如 J01NME
。连接符凭据是设备专用的字符串,由全部大写字母数字字符(0-9 和 A-Y,为便于阅读,不包括 I、O、Q 和 Z)组成,长度介于 6 到 32 个字符之间。
## BR Commissioner ## ---------------------- > commissioner start Commissioner: petitioning Done Commissioner: active > commissioner joiner add 4831b7fffec02be1 J01NME Done
切换到 Board2 Joiner。使用您刚刚在巴西监管机构设置的“Joiner Credential”来开启“Joiner 角色”:
## Board2 Joiner ## ---------------------- > ifconfig up Done > joiner start J01NME Done
在大约一分钟内,您会收到身份验证成功的确认消息:
## Board2 Joiner ## ---------------------- > Join success
之后,您可以启动并加入由巴西专员组成的 Thread 网络。
启动 Thread 协议操作:
> thread start I(35727) OPENTHREAD:[N] Mle-----------: Role disabled -> detached Done > I(36197) OPENTHREAD:[N] Mle-----------: Attach attempt 1, AnyPartition reattaching with Active Dataset I(37007) OPENTHREAD:[N] Mle-----------: RLOC16 fffe -> 2801 I(37007) OPENTHREAD:[N] Mle-----------: Role detached -> child
将角色设置为路由器。
> state router Done I(46057) OPENTHREAD:[N] Mle-----------: RLOC16 2801 -> 4400 I(46057) OPENTHREAD:[N] Mle-----------: Role child -> router I(46057) OPENTHREAD:[N] Mle-----------: Partition ID 0x28b518c6 >
现在,您将获得一个具有如下所示的拓扑的 Thread 网络:
7. 在 Thread 节点之间 ping IPv6 地址
您可以使用 ping 命令在任何两块开发板之间进行通信。使用命令 ipaddr
输出每个开发板的 IPv6 地址:
## BR Commissioner ## ---------------------- > ipaddr fd6a:b54b:d6a3:b05a:0:ff:fe00:fc00 # Leader Anycast Locator (ALOC) fd6a:b54b:d6a3:b05a:0:ff:fe00:2c00 # Routing Locator (RLOC) fd6a:b54b:d6a3:b05a:a8df:eb43:63d8:bda0 # Mesh-Local EID (ML-EID) fe80:0:0:0:687c:7248:cc14:9c4d # Link-Local Address (LLA) Done >
## Board1 Joiner ## ---------------------- > ipaddr fd6a:b54b:d6a3:b05a:0:ff:fe00:2800 # Routing Locator (RLOC) fd6a:b54b:d6a3:b05a:e461:db08:c833:1248 # Mesh-Local EID (ML-EID) fe80:0:0:0:18ac:df04:4671:6a45 # Link-Local Address (LLA) Done
## Board2 Joiner ## ---------------------- > ipaddr fd6a:b54b:d6a3:b05a:0:ff:fe00:4400 # Routing Locator (RLOC) fd6a:b54b:d6a3:b05a:d7dc:8e90:9bc9:ecbc # Mesh-Local EID (ML-EID) fe80:0:0:0:a8cc:1483:f696:91a2 # Link-Local Address (LLA) Done
例如,要从 BR 调试器对 Board2 MLE-ID 执行 ping 操作,您可以在 BR 调试器上运行此命令:
## BR Commissioner ## ---------------------- > ping fd6a:b54b:d6a3:b05a:d7dc:8e90:9bc9:ecbc 16 bytes from fd6a:b54b:d6a3:b05a:d7dc:8e90:9bc9:ecbc: icmp_seq=1 hlim=255 time=123ms 1 packets transmitted, 1 packets received. Packet loss = 0.0%. Round-trip min/avg/max = 123/123.0/123 ms. Done
8. 使用 UDP 在 Thread 节点之间传递消息
在此课程中,您将学习如何在两台 Thread 设备之间发送消息。例如,打开 udp 并将其绑定在端口 20617
上,然后监听 BR 上的所有地址:
## BR Commissioner ## ---------------------- > udp open Done > udp bind :: 20617 I (1298739) OPENTHREAD: Platform UDP bound to port 20617 Done
然后,从 Board1 向 BR MLE-ID 地址和端口 20617
发送消息:
## Board1 Joiner ## ---------------------- > udp open Done > udp send fd6a:b54b:d6a3:b05a:a8df:eb43:63d8:bda0 20617 ESP
您可以查看在 BR 收到的邮件:
## BR Commissioner ## ---------------------- 3 bytes from fd6a:b54b:d6a3:b05a:e461:db08:c833:1248 49154 ESP
9. 恭喜!
您已经使用 ESP 板创建了一个物理 Thread 网络!
您现在已了解:
- 构建 OpenThread CLI 二进制文件并将其刷写到 ESP 板。
- 构建闪烁的边界路由器到 ESP 线程边界路由器板。
- 使用 ESP Monitor 和 OpenThread CLI 手动管理 Thread 节点。
- 在线程边界路由器上构建 Thread 网络。
- 对设备进行安全调试,以将其连接到 Thread 网络。
- 在 Thread 节点之间 ping IPv6 地址。
- 使用 UDP 在 Thread 节点之间传递消息。
深入阅读
您可以访问 openthread.io 和 GitHub,获取各种 OpenThread 资源,包括:
- 支持的平台 - 探索支持 OpenThread 的所有平台
- 构建 OpenThread - 进一步详细了解如何构建和配置 OpenThread
- Thread Primer - 介绍了此 Codelab 中介绍的所有 Thread 概念
参考: