1. 简介
OpenThread 是 Thread® 网络协议的开源实现,是一种可靠且安全的无线网状网络协议,专为物联网 (IoT) 设备而设计。OpenThread 是由 Google 的 Nest 团队开发的,可作为开源项目免费提供给开发者社区。
Thread 规范为智能家居和商业建筑中常用的资源受限设备建立了可靠、安全且节能的无线通信协议。OpenThread 包含 Thread 中的完整网络层范围,例如 IPv6、6LoWPAN、IEEE 802.15.4(具有 MAC 安全性、网状网链路建立和网格路由)。
Telink 已将 OpenThread 实现集成到 Zephyr RTOS,从而可与 Telink 硬件无缝兼容。此集成的源代码可在 GitHub 上轻松获取,并且还提供了一个软件开发套件 (SDK) 的形式。
在此 Codelab 中,您将在实际硬件上为 OpenThread 编程,创建和管理 Thread 网络,并在节点之间交换消息。下图显示了硬件设置,其中包含此 Codelab 中的 OT 边界路由器 (OTBR) 和 Thread 设备。
学习内容
- 使用 Telink Zephyr 开发环境设置 OpenThread 实现。
- 构建 OpenThread CLI 示例(
ot-cli-ftd
和ot-rcp
)并将其刷写到 Telink B91 开发板上。 - 在 Raspberry Pi 3B 及更高版本上使用 Docker 设置 OpenThread 边界路由器 (OTBR)。
- 在 OTBR 上创建线程网络。
- 使用带外调试将设备添加到 Thread 网络。
- 使用 CLI 验证 Thread 网络节点之间的连接情况。
所需条件
硬件:
- 两个 B91 开发板。
- 一个搭载 Raspberry Pi 3B 或更高型号的 Raspbian OS 映像。
- 具有至少两个 USB 端口的 Linux 机器。
- 互联网连接(或路由器)和几根以太网线缆。
软件:
- Telink 燃烧和调试工具 — LinuxBDT。
- 串行端口终端工具,例如 PuTTY。
- 其他工具,例如 Git 和 West。
2. 前提条件
线程概念和 OpenThread CLI
在学习此 Codelab 之前,建议您完成 OpenThread 模拟 Codelab 以熟悉基本 Thread 概念和 OpenThread CLI。
Linux 机器
Linux 机器(Ubuntu v20.04 LTS 或更高版本)充当构建机器,用于设置 Telink Zephyr 开发环境并刷写所有 Thread 开发板。为了完成这些任务,Linux 机器需要两个可用的 USB 端口和互联网连接。
串行端口连接和终端
您可以直接将设备插入 Linux 计算机的 USB 端口。此外,您还需要一个串行端口终端工具来访问设备。
在此 Codelab 中,终端工具 PuTTY 用于控制 FTD 联接和 Raspberry Pi。它可以提供使用概览,也可以采用其他终端软件。
Telink B91 开发套件
此 Codelab 需要两套 B91 开发套件。下面的照片在一个集中显示了所需的最基本的组件。
其中一个套件将用作 RCP(无线协处理器),而另一个套件将用作 FTD(全线程设备)。如果您还没有该套件,可以从 Telink 官方网站获取更多详细信息。需要使用的部分组件如下:
索引 | 名称 |
1 | Telink B91 开发板 |
2 | Telink 燃烧板 |
3 | 2.4Ghz 天线 |
4 | USB 线(USB A 转迷你 USB) |
使用 Raspbian OS 映像的 Raspberry Pi 3B 及更高版本
在本 Codelab 中,我们需要一个 Raspberry Pi 3B 及更高版本,其中包含Raspbian Bullseye Lite OS 映像或带 Rasbian Bullseye 的桌面平台。它通过以太网连接到互联网,并配置为 OpenThread 边界路由器 (OTBR) 的主机。
网络连接类型
可连接到互联网的开关(或路由器)以及多根以太网线缆。它们用于将 Raspberry Pi 连接到 Linux 机器,从而通过主机简化 Raspberry Pi 的用户配置。
LinuxBDT
Telink 错误和调试工具 (BDT) 适用于所有 Telink 芯片组,可用于清空 OpenThread 固件并将其刷写到 Telink B91 开发板。在 Linux 计算机上安装基于 X86 的 Linux 版本 linuxBDT。
其他
- Git,用于设置 Telink Zephyr 开发环境。
- 西部,用于管理 Zephyr 项目和构建 OpenThread 二进制文件。
3. 设置固件
设置 Telink Zephyr 开发环境
在 Linux 计算机上,打开 CLI 终端并首先执行以下命令,以确保您的 APT 是最新版本。
$ sudo apt update $ sudo apt upgrade
完成后,请执行以下步骤。
- 安装依赖项。
$ 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 镜像切换到稳定且最新的镜像,或手动更新这些依赖项。 - 向西安装。
$ pip3 install --user -U west $ echo 'export PATH=~/.local/bin:"$PATH"' >> ~/.bashrc $ source ~/.bashrc
确保~/.local/bin
位于$PATH
环境变量中。 - 获取 Zephyr 项目源代码。
$ west init ~/zephyrproject $ cd ~/zephyrproject $ west update $ west blobs fetch hal_telink $ west zephyr-export
- 为 Zephyr 安装其他 Python 依赖项。
$ pip3 install --user -r ~/zephyrproject/zephyr/scripts/requirements.txt
- 设置 Zephyr 工具链。将 Zephyr 工具链(大约 1-2 GB)下载到本地目录,便于刷写大多数开发板。
$ wget https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.16.1/zephyr-sdk-0.16.1_linux-x86_64.tar.xz $ wget -O - https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.16.1/sha256.sum | shasum --check --ignore-missing
下载 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] 是可选文字,可以是任何文字,例如 -0.16.1。安装 SDK 后,无法移动该目录。然后,安装 Zephyr 工具链。$ tar xvf zephyr-sdk-0.16.1_linux-x86_64.tar.xz $ cd zephyr-sdk-0.16.1 $ ./setup.sh -t riscv64-zephyr-elf -h -c
- 构建 Hello World 示例。首先,使用 Hello World 示例验证 Zephyr 官方项目的配置是否正确,然后继续设置你的自定义项目。
$ cd ~/zephyrproject/zephyr $ west build -p auto -b tlsr9518adk80d samples/hello_world
使用 West build 命令从 Zephyr 代码库的根目录构建 hello_world 示例。您可以在build/zephyr directory
下找到名为zephyr.bin
的固件。 - 将 Zephyr 环境脚本添加到
~/.bashrc
。执行以下命令。$ echo "source ~/zephyrproject/zephyr/zephyr-env.sh" >> ~/.bashrc $ source ~/.bashrc
- 添加 Telink Zephyr 远程代码库。在本地将 Telink 代码库作为开发分支下载并进行更新。
$ cd ~/zephyrproject/zephyr $ git remote add telink-semi https://github.com/telink-semi/zephyr $ git fetch telink develop $ git checkout develop $ west update $ west blobs fetch hal_telink
有关详情,请参阅 Zephyr 文档 - 入门指南。
设置 Telink LinuxBDT
下载 Telink LinuxBDT 工具,并将其解压缩到 Linux 计算机上的本地目录(例如主目录 ~
)下,从而将固件刷写到 B91 开发板上。
$ cd ~ $ wget http://wiki.telink-semi.cn/tools_and_sdk/Tools/BDT/LinuxBDT.tar.bz2 $ tar -vxf LinuxBDT.tar.bz2
通过 USB 接口将燃烧板连接到 Linux 机器,然后输入以下命令。
$ cd LinuxBDT $ sudo ./bdt lsusb -v Bus 002 Device 001: ID 1d6b:0003 xHCI Host Controller Bus 001 Device 003: ID 0bda:565a Integrated_Webcam_HD Bus 001 Device 023: ID 413c:301a Dell MS116 USB Optical Mouse Bus 001 Device 037: ID 248a:826a Telink Web Debugger v3.6 Bus 001 Device 001: ID 1d6b:0002 xHCI Host Controller
如果您看到“Telink Web Debugger v3.6”这一消息,这表示 BDT 程序程序已成功连接到 Linux 计算机。
固件编译
此 Codelab 将构建两种类型的 OpenThread 固件:
ot-cli-ftd
、- 和
ot-rcp
。
编译方法如下所示:
- 无线装置处理器 (
ot-rcp
)$ cd ~/zephyrproject $ rm -rf build_ot_coprocessor $ west build -b tlsr9518adk80d -d build_ot_coprocessor zephyr/samples/net/openthread/coprocessor -- -DDTC_OVERLAY_FILE="usb.overlay" -DOVERLAY_CONFIG=overlay-rcp-usb-telink.conf
- 功能齐全且带有交互式命令行的线程设备 (
ot-cli-ftd
)$ cd ~/zephyrproject $ rm -rf build_ot_cli_ftd $ west build -b tlsr9518adk80d -d build_ot_cli_ftd zephyr/samples/net/openthread/cli -- -DOVERLAY_CONFIG=overlay-telink-fixed-mac.conf -DCONFIG_OPENTHREAD_FTD=y
固件闪光灯
使用 USB 线将 B91 开发板连接到刻录板,如下图所示。
在命令行中,执行以下命令以执行固件烧录(以刷写 ot-cli-ftd
固件为例)。
$ cd ~/zephyrproject/build_ot_cli_ftd/zephyr $ cp zephyr.bin ~/LinuxBDT/bin/ot-cli-ftd.bin $ cd ~/LinuxBDT $ sudo ./bdt 9518 ac Activate OK! $ sudo ./bdt 9518 wf 0 -i bin/ot-cli-ftd.bin EraseSectorsize... Total Time: 2181 ms Flash writing... [100%][-] [##################################################] File Download to Flash at address 0x000000: 491700 bytes Total Time: 30087 ms
ot-rcp
的刷写方法与 ot-cli-ftd
的 Flash 方法基本相同。不过,固件路径和名称存在差异。
刷写后,通过将两个 B91 开发板进行相应标记加以区分。将刷入了 ot-cli-ftd
的板标记为“FTD Joiner”(带有 FTD 连接符),并将包含 ot-rcp
的板标记为“RCP”。
4. 为 FTD 联接设备配置配置控制台
如图所示,直接将 FTD 连接器插入 Linux 计算机的 USB 端口。
将 FTD 联接设备连接到 Linux 机器后,打开 PuTTY。然后创建一个新终端,设置串行端口信息并打开串行端口。
OpenThread 命令行参考位于:OpenThread CLI 参考文档。请务必为所有命令添加 ot
前缀。
示例:
> ot state disabled Done > ot channel 11 Done >
5. 将 Raspberry Pi 设置为 OpenThread 边界路由器
OpenThread 边界路由器由两个主要部分组成:
- Raspberry Pi 包含充当边界路由器 (BR) 所需的所有服务和固件。
- RCP 负责 Thread 通信。
无线装置处理器 (RCP)
如需刷写 ot-rcp
固件,请按照与 ot-cli-ftd
固件刷写流程相同的步骤操作。将 B91 开发板连接到 Raspberry Pi 上的 USB 端口,如下图所示。
覆盆子 Pi
- 确保Raspbian Bullseye Lite OS 映像或桌面版 Rasbian Bullseye 电脑版已正确写入 SD 卡。
- 您可以选择通过 SSH 连接到 Raspberry Pi,或者直接使用 Raspbian Desktop。此 Codelab 将使用 SSH。
- 在下一步中安装 OTBR Docker 之前,请务必先更新本地代码库和软件包管理器。
$ sudo apt-get update $ sudp apt-get upgrade
安装 Docker
如果您刚刚在上一步中更新了本地代码库和软件包管理器 APT,请重新启动 Raspberry Pi,然后打开 SSH 终端窗口。
- 安装 Docker:
$ curl -sSL https://get.docker.com | sh
- 将当前帐号归入 Docker 群组以授予权限,这样就无需在每个命令前添加
sudo
。$ sudo usermod -aG docker $USER
您需要重启 Raspberry Pi 才能生效。 - 如果 Docker 尚未启动,请执行以下操作:
$ sudo dockerd
- OTBR 防火墙脚本会在 Docker 容器内生成规则。在此之前,执行
modprobe
加载 iptables 的内核模块。$ sudo modprobe ip6table_filter
配置并运行 Docker
此 Codelab 直接从 OpenThread Docker Hub 提取 OTBR Docker 映像。此映像已通过 OpenThread 团队的测试和验证。
- 拉取最新的映像:
$ docker pull openthread/otbr:latest
- 检查 Docker 容器中的映像列表:
$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE openthread/otbr latest db081f4de15f 6 days ago 766MB
- 通过检查
/dev
确定 RCP 设备的串行端口名称,ttyACM0
表示 RCP 是否正确连接。$ ls /dev/tty* ... /dev/ttyACM0 ...
- 首次运行 OTBR Docker,并引用 RCP 串行端口 (
ttyACM0
)。如果您要继续使用此 OTBR Docker,请使用命令 docker start otbr。$ docker run --name "otbr" --sysctl "net.ipv6.conf.all.disable_ipv6=0 net.ipv4.conf.all.forwarding=1 net.ipv6.conf.all.forwarding=1" -p 8080:80 --dns=127.0.0.1 -it --volume /dev/ttyACM0:/dev/ttyACM0 --privileged openthread/otbr --radio-url spinel+hdlc+uart:///dev/ttyACM0
- 打开新的 SSH 终端窗口以测试 Raspberry Pi 和 RCP 之间的连接。
$ docker exec -ti otbr sh -c "sudo ot-ctl" > state disabled Done
可选的 Docker 命令:
- 获取正在运行的 Docker 容器的相关信息:
$ docker ps -aq
- 停止 OTBR Docker:
$ docker stop otbr
- 移除 OTBR Docker:
$ docker rm otbr
- 重新加载 OTBR Docker:
$ docker restart otbr
此时,FTD 联接设备和 OTBR 已准备就绪,您可以继续执行下一步以构建 Thread 网络。
6. 创建线程网络
在 RCP 上创建线程网络
我们使用 OTBR 上的 ot-ctl shell 建立线程网络。如果您在上一部分中退出了 shell,请输入以下命令,在 SSH 终端中重新启动:
$ docker exec -ti otbr sh -c "sudo ot-ctl"
接下来,按照表中指定的顺序输入命令,并确保每个步骤都实现了预期结果,然后再执行下一个步骤。
索引 | 命令 | 简介 | 预期响应 | ||
1 |
| 创建一个新的随机网络数据集。 | 完成 | ||
2 |
| 将新数据集提交到非易失性存储空间中的活跃操作数据集。 | 完成 | ||
3 |
| 启动 IPv6 接口。 | 完成 | ||
4 |
| 启用 Thread 协议操作并连接到 Thread 网络。 | 完成 | ||
等待 10 秒,让线程接口开启。 | |||||
5 |
| 检查设备状态。可以多次调用此命令,直到它成为主要副本,然后继续执行下一步。 | 领导者 | ||
6 |
| 检查完整的活跃操作数据集并记录网络键。 | 。 |
当 ot-cli-ftd
设备加入此 Thread 网络时,系统会使用 OTBR 在网络创建期间随机生成的网络密钥。
通过带外调试将 FTD 联接器添加到 Thread
带外调试指的是将网络凭据传输到等待通过非无线方法加入网络的设备(例如,在 OpenThread CLI 中手动输入)。在串行控制台中按顺序向 FTD 联接人员输入以下命令。
索引 | 命令 | 简介 | 预期响应 | ||
1 |
| 只需一个网络密钥即可让设备连接到 Thread 网络。 | 完成 | ||
2 |
| 将新数据集提交到非易失性存储空间中的活跃操作数据集。 | 完成 | ||
3 |
| 启动 IPv6 接口。 | 完成 | ||
4 |
| 启用 Thread 协议操作并连接到 Thread 网络。 | 完成 | ||
等待 20 秒,等待设备加入并自行配置。 | |||||
5 |
| 检查设备状态。 | 儿童/路由器 |
拓扑
在 SSH 终端中输入 ipaddr
、child table
和 router table
等命令,以获取类似以下代码段的响应。
> ipaddr rloc fd8c:60bc:a98:c7ba:0:ff:fe00:b000 Done > child table | ID | RLOC16 | Timeout | Age | LQ In | C_VN |R|D|N|Ver|CSL|QMsgCnt|Suprvsn| Extended MAC | +-----+--------+------------+------------+-------+------+-+-+-+---+---+-------+-------+------------------+ | 1 | 0xb001 | 240 | 23 | 3 | 51 |1|1|1| 3| 0 | 0 | 129 | 82bc12fbe783468e | Done > router table | ID | RLOC16 | Next Hop | Path Cost | LQ In | LQ Out | Age | Extended MAC | Link | +----+--------+----------+-----------+-------+--------+-----+------------------+------+ | 44 | 0xb000 | 63 | 0 | 0 | 0 | 0 | 7ae354109d611f7e | 0 | Done ... > child table | ID | RLOC16 | Timeout | Age | LQ In | C_VN |R|D|N|Ver|CSL|QMsgCnt|Suprvsn| Extended MAC | +-----+--------+------------+------------+-------+------+-+-+-+---+---+-------+-------+------------------+ Done > router table | ID | RLOC16 | Next Hop | Path Cost | LQ In | LQ Out | Age | Extended MAC | Link | +----+--------+----------+-----------+-------+--------+-----+------------------+------+ | 33 | 0x8400 | 63 | 0 | 3 | 3 | 13 | e61487c1cda940a6 | 1 | | 44 | 0xb000 | 63 | 0 | 0 | 0 | 0 | 7ae354109d611f7e | 0 | Done
OTBR 的 RLOC16
为 0xb000
,FTD 联接器的 RLOC16
最初为 0xb001
。然后,FTD 联接方的 RLOC16
将在获得路由器 ID 后变为 0x8400
。您可以看到,FTD 联接已从儿童升级为路由器。
当前的 Thread 网络包含两个节点,并且拓扑如下图所示。
7. 线程设备之间的通信
ICMPv6 通信
我们使用 ping
命令来检查同一网络中的线程设备是否可以相互通信。首先,使用 ipaddr
命令获取设备的 RLOC。
> ipaddr fd8c:60bc:a98:c7ba:0:ff:fe00:fc11 fdbd:7274:649c:1:1d19:9613:f705:a5af fd8c:60bc:a98:c7ba:0:ff:fe00:fc10 fd8c:60bc:a98:c7ba:0:ff:fe00:fc38 fd8c:60bc:a98:c7ba:0:ff:fe00:fc00 fd8c:60bc:a98:c7ba:0:ff:fe00:b000 # Routing Locator (RLOC) fd8c:60bc:a98:c7ba:5249:34ab:26d1:aff6 fe80:0:0:0:78e3:5410:9d61:1f7e Done
在 FTD 联接器的串行控制台中输入以下命令,以执行 ping 操作。
> ot ping fd8c:60bc:a98:c7ba:0:ff:fe00:b000 16 bytes from fd8c:60bc:a98:c7ba:0:ff:fe00:b000: icmp_seq=1 hlim=64 time=19ms 1 packets transmitted, 1 packets received. Packet loss = 0.0%. Round-trip min/avg/max = 19/19.0/19 ms. Done
串行端口的输出响应表明 OTBR 端已收到 ping 请求,而 FTD 联接器已收到 OTBR 返回的 ping 响应。两台设备之间的通信已成功完成。
UDP 通信
OpenThread 提供的应用服务也包括 UDP。您可以使用 UDP API 在 Thread 网络中的节点之间传递信息,也可以通过边界路由器向外部网络传递信息。如需详细了解 OpenThread 的 UDP API,请参阅 OpenThread CLI - UDP 示例。此 Codelab 将使用它中的某些 API 在 OTBR 和 FTD 联接器之间传输信息。
首先,获取 OTBR 的 Mesh-Local EID。此地址也是 Thread 设备的 IPv6 地址之一,可用于访问同一 Thread 网络分区中的 Thread 设备。
> ipaddr mleid fd8c:60bc:a98:c7ba:5249:34ab:26d1:aff6 Done
在 SSH 终端中输入以下命令以启用 OTBR UDP 并绑定设备的 1022 端口。
> udp open Done > udp bind :: 1022 Done
在串行控制台中输入以下命令,并启用 FTD 联接器的 UDP。绑定设备的 1022 端口,然后向 OTBR 发送 5 字节的 hello
消息。
> ot udp open Done > ot udp bind :: 1022 Done > ot udp send fd8c:60bc:a98:c7ba:5249:34ab:26d1:aff6 1022 hello Done
SSH 终端会输出以下信息。OTBR 从 FTD 联接器接收 hello
消息,这意味着 UDP 通信成功。
> 5 bytes from fd8c:60bc:a98:c7ba:9386:63cf:19d7:5a61 1022 hello
8. 恭喜
您创建了一个简单的 Thread 网络并验证了此网络中的通信。
您现在已经知道:
- 如何构建和使用 Telink Zephyr 开发环境。
- 如何构建
ot-cli-ftd
和ot-rcp
二进制文件,以及如何将它们刷写到 Telink B91 开发板。 - 如何使用 Docker 将 Raspberry Pi 3B 及更高版本设置为 OpenThread 边界路由器 (OTBR)。
- 如何在 OTBR 上创建线程网络。
- 如何通过带外调试将设备添加到 Thread 网络。
- 如何验证 Thread 网络中的节点之间的连接。
延伸阅读
查看 openthread.io 和 GitHub,了解各种 OpenThread 资源,包括:
- 支持的平台 - 发现支持 OpenThread 的所有平台
- 构建 OpenThread - 详细了解如何构建和配置 OpenThread
- Thread Primer - 涵盖此 Codelab 中介绍的所有 Thread 概念
参考文档: