使用 B91 开发板和 OpenThread 构建 Thread 网络

1. 简介

26b7f4f6b3ea0700.png

OpenThreadThread® 网络协议的开源实现,线程是专为物联网 (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 设备。

codelab_overview.png

学习内容

  • 使用 Telink Zephyr 开发环境设置 OpenThread 实现。
  • 构建 OpenThread CLI 示例(ot-cli-ftdot-rcp)并将其刷写到 Telink B91 开发板上。
  • 在 Raspberry Pi 3B 或更高版本上使用 Docker 设置 OpenThread 边界路由器 (OTBR)。
  • 在 OTBR 中创建 Thread 网络。
  • 使用带外调试功能将设备添加到 Thread 网络。
  • 使用 CLI 验证 Thread 网络中节点之间的连接。

所需条件

硬件:

  • 两块 B91 开发板。
  • 一台搭载 Raspbian OS 映像的 Raspberry Pi 3B 或更高版本。
  • 一台至少有两个 USB 端口的 Linux 计算机。
  • 一个连接到互联网的交换机(或路由器)和几根以太网网线。

软件:

  • Telink Burning 和调试工具 - LinuxBDT。
  • 串行端口终端工具,例如 PuTTY。
  • 其他工具,例如 Git 和 West。

2. 前提条件

Thread 概念和 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。它可提供其用法概述,但也可以使用其他终端软件。

此 Codelab 需要两套 B91 开发套件。下图显示了一组所要求的最低限度。

overview.png

其中一个套件将用作 RCP(无线电协同处理器),另一个套件将用作 FTD(全线程设备)。如果您还没有准备好该套件,请访问 Telink 官方网站了解详情。要使用的一些组件如下:

索引

名称

1

Telink B91 开发板

2

Telink Burning Board

3

2.4GHz 天线

4

USB 线(USB A 转 mini USB)

Raspberry Pi 3B 或更高版本以及 Raspbian OS 映像

在此 Codelab 中,需要搭载 Raspbian Bullseye Lite 操作系统映像的 Raspberry Pi 3B 或更高版本,或桌面版 Raspbian Bullseye。它通过以太网连接到互联网,并将被配置为 OpenThread 边界路由器 (OTBR) 的主机。

网络连接

一个连接到互联网的交换机(或路由器)和几根以太网网线。它们用于将 Raspberry Pi 连接到 Linux 计算机,从而简化用户通过主机配置 Raspberry Pi 的过程。

LinuxBDT

Telink 燃烧和调试工具 (BDT) 适用于所有 Telink 芯片系列,可让您清除 OpenThread 固件并将其刷写到 Telink B91 开发板上。在 Linux 计算机上安装基于 X86 的 linux 版本 linuxBDT

其他

  • Git,用于设置 Telink Zephyr 开发环境。
  • West,用于管理 Zephyr 项目和构建 OpenThread 二进制文件。

3. 设置固件

在 Linux 计算机上,打开 CLI 终端并首先执行以下命令,以确保您的 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) 和设备树编译器 (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
    
  4. 为 Zephyr 安装其他 Python 依赖项。
    $ pip3 install --user -r ~/zephyrproject/zephyr/scripts/requirements.txt
    
  5. 设置 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
    
  6. 构建 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 的固件。
  7. 将 Zephyr 环境脚本添加到 ~/.bashrc。执行以下命令。
    $ echo "source ~/zephyrproject/zephyr/zephyr-env.sh" >> ~/.bashrc
    $ source ~/.bashrc
    
  8. 添加 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 Doc - 入门指南

下载 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 接口将 Burning Board 连接到 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

编译方法如下所示:

  1. 无线装置协同处理器 (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
    
  2. 具有交互式命令行 (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 开发板连接到 Burning Board。

connection_overview.png

在命令行中执行以下命令,以执行固件烧录(以刷写 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 的 Flash 方法与 ot-cli-ftd 的 Flash 方法基本相同。不过,固件路径和名称有所不同。

刷写后,通过对两块 B91 开发板进行相应的标记来区分它们。将刷写了 ot-cli-ftd 的开发板标记为“FTD Joiner”,将板刷写了 ot-rcp 标记为“RCP”。

4. 为 FTD 连接符设备配置串行控制台

如图所示,将 FTD 连接器直接插入 Linux 计算机的 USB 端口。

usb_connection.png

将 FTD 连接符设备连接到 Linux 计算机后,打开 PuTTY。然后创建一个新的终端,设置串行端口信息,并打开串行端口。

uart_console.png

OpenThread 命令行参考位于:OpenThread CLI 参考文档。务必为所有命令添加 ot 前缀。

示例:

> ot state
disabled
Done
> ot channel
11
Done
>

5. 将 Raspberry Pi 设置为 OpenThread 边界路由器

OpenThread 边界路由器是一种设备,由两个主要部分组成:

  • Raspberry Pi 包含充当边界路由器 (BR) 所需的所有服务和固件。
  • RCP 负责线程通信。

无线电协同处理器 (RCP)

如需刷写 ot-rcp 固件,请按照与 ot-cli-ftd 固件刷写过程相同的步骤操作。将 B91 开发板连接到 Raspberry Pi 上的 USB 端口,如下图所示。

OTBR_overview.png

树莓派 (Raspberry Pi)

  1. 确保 Raspbian Bullseye Lite 操作系统映像Raspbian Bullseye with Desktop(桌面设备版)已正确写入 SD 卡。
  2. 您可以选择通过 SSH 连接到 Raspberry Pi 或直接使用 Raspbian 桌面。此 Codelab 将使用 SSH。
  3. 在下一步中继续安装 OTBR Docker 之前,请务必先更新本地代码库和软件包管理器。
    $ sudo apt-get update
    $ sudp apt-get upgrade
    

安装 Docker

如果您只是在上一步中更新了本地代码库和软件包管理器 APT,请重新启动 Raspberry Pi,然后打开 SSH 终端窗口。

  1. 安装 Docker:
    $ curl -sSL https://get.docker.com | sh
    
  2. 将当前帐号放入 Docker 组中,以授予权限,这样就无需在每个命令前面添加 sudo
    $ sudo usermod -aG docker $USER
    
    您需要重启 Raspberry Pi 才能生效。
  3. 如果 Docker 尚未启动,请将其启动:
    $ sudo dockerd
    
  4. OTBR 防火墙脚本在 Docker 容器内生成规则。在此之前,请执行 modprobe 以加载 iptables 的内核模块。
    $ sudo modprobe ip6table_filter
    

配置并运行 Docker

此 Codelab 直接从 OpenThread Docker Hub 拉取 OTBR Docker 映像。此映像已经过 OpenThread 团队测试和验证。

  1. 拉取最新映像:
    $ docker pull openthread/otbr:latest
    
  2. 检查 Docker 容器中的映像列表:
    $ docker images
    REPOSITORY        TAG       IMAGE ID       CREATED      SIZE
    openthread/otbr   latest    db081f4de15f   6 days ago   766MB
    
  3. 通过检查 /dev 确定 RCP 设备的串行端口名称,ttyACM0 表示 RCP 已正确连接。
    $ ls /dev/tty*
    ...
    /dev/ttyACM0
    ... 
    
  4. 首次运行 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
    
  5. 打开新的 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. 创建 Thread 网络

在 RCP 上创建 Thread 网络

我们使用 OTBR 上的 ot-ctl shell 建立 Thread 网络。如果您在上一部分中退出了 shell,请输入以下命令以在 SSH 终端中重新启动:

$ docker exec -ti otbr sh -c "sudo ot-ctl"

接下来,请按照表中指定的顺序输入命令,并确保每个步骤都达到预期结果,然后再继续下一个步骤。

索引

命令

简介

预期响应

1

dataset init new

创建一个新的随机网络数据集。

完成

2

dataset commit active

将新数据集提交到非易失性存储空间中的活跃操作数据集。

完成

3

ifconfig up

调出 IPv6 接口。

完成

4

thread start

启用 Thread 协议操作并连接到 Thread 网络。

完成

等待 10 秒,让线程接口启动。

5

state

检查设备状态。可以多次调用此命令,直到它成为主要实例并继续执行下一步。

主管
完成

6

dataset active

检查完整的活跃运营数据集并记录网络密钥。

Active Timestamp: 1
Channel: 13Channel Mask: 0x07fff800">Ext PAN ID: b07476e168eda4fc
Mesh Local Prefix: fd8-8c:8<ph type="x-smartling-void-element"><br></ph><ph type="x-smartling-void-element"><br></ph><ph type="x-smartling-void-element"><br></ph><ph type="x-smartling-void-element"><br></ph><ph type="x-smartling-void-element"><br></ph><ph type="x-smartling-void-element"><br></ph><ph type="x-smartling-void-element"><br></ph><ph type="x-smartling-void-element"><br></ph><ph type="x-smartling-void-element"><br></ph><ph type="x-smartling-void-element"><br></ph><ph type="x-smartling-void-element"><br></ph><br>







ot-cli-ftd 台设备加入此 Thread 网络时,系统将使用 OTBR 在网络创建期间随机生成的网络密钥。

通过带外调试将 FTD 连接符添加到线程

带外调试是指将网络凭据传输到等待通过非无线方式(例如,在 OpenThread CLI 中手动输入)加入网络的设备。在串行控制台中按顺序向 FTD 联接器输入以下命令。

索引

命令

简介

预期响应

1

ot dataset networkkey c312485187484ceb5992d2343baaf93d

只有网络密钥可以让设备连接到 Thread 网络。

完成

2

ot dataset commit active

将新数据集提交到非易失性存储空间中的活跃操作数据集。

完成

3

ot ifconfig up

调出 IPv6 接口。

完成

4

ot thread start

启用 Thread 协议操作并连接到 Thread 网络。

完成

等待 20 秒,让设备加入并自行配置。

5

ot state

检查设备状态。

子级/路由器
完成

拓扑

在 SSH 终端中输入 ipaddrchild tablerouter 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 的 RLOC160xb000,FTD 联接器的 RLOC16 最初为 0xb001。然后,在获得路由器 ID 后,FTD 联接器的 RLOC16 会变为 0x8400。可以看到,FTD 联接器已从子级升级为路由器。

当前 Thread 网络包含两个节点,其拓扑如下图所示。

topology.png

7. Thread 设备之间的通信

ICMPv6 通信

我们使用 ping 命令检查同一网络中的 Thread 设备能否相互通信。首先,使用 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 将使用此 Codelab 中的一些 API 在 OTBR 和 FTD Joiner 之间传输信息。

首先,获取 OTBR 的网状网本地 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-ftdot-rcp 二进制文件,并将其刷写到 Telink B91 开发板上。
  • 如何使用 Docker 将 Raspberry Pi 3B 及更高版本设置为 OpenThread 边界路由器 (OTBR)。
  • 如何在 OTBR 上创建 Thread 网络。
  • 如何通过带外调试将设备添加到 Thread 网络。
  • 如何验证 Thread 网络中节点之间的连接。

更多详情

访问 openthread.ioGitHub,了解各种 OpenThread 资源,包括:

参考文档: