使用 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) 取得。

在本程式碼研究室中,您將在實際硬體上編寫 OpenThread 程式、建立及管理 Thread 網路,並在節點之間交換訊息。下圖顯示硬體設定,包括 OT 邊界路由器 (OTBR) 和一個 Codelab 中的 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 開發板。
  • Raspberry Pi 3B+ 以上版本,並安裝 Raspbian OS 映像檔。
  • 至少有兩個 USB 連接埠的 Linux 電腦。
  • 連上網際網路的交換器 (或路由器) 和數條乙太網路線。

軟體:

  • Telink Burning and Debugging Tool (LinuxBDT)。
  • 序列埠終端機工具,例如 PuTTY。
  • 其他工具,例如 Git 和 West。

2. 先決條件

Thread 概念和 OpenThread CLI

建議您先完成 OpenThread 模擬程式碼研究室,熟悉 Thread 的基本概念和 OpenThread CLI,再開始進行本程式碼研究室。

Linux 電腦

Linux 電腦 (Ubuntu v20.04 LTS 以上版本) 會做為建構電腦,用來設定 Telink Zephyr 開發環境,並將所有 Thread 開發板刷寫至最新版本。如要完成這些工作,Linux 電腦必須有兩個可用的 USB 連接埠,並連上網際網路。

序列埠連線和終端機

你可以直接將裝置插入 Linux 電腦的 USB 連接埠。此外,您還需要序列埠終端機工具才能存取裝置。

在本程式碼研究室中,終端機工具 PuTTY 用於控制 FTD Joiner 和 Raspberry Pi。這項工具會提供使用情況的總覽,但您也可以使用其他終端機軟體。

本程式碼研究室需要兩組 B91 開發套件。下圖顯示一組中至少須包含的元件。

overview.png

其中一個開發套件會做為 RCP (無線電共同處理器),另一個則會做為 FTD (完整 Thread 裝置)。如果還沒有開發套件,請前往 Telink 官方網站瞭解詳情。可使用的元件如下:

索引

名稱

1

Telink B91 開發板

2

Telink Burning Board

3

2.4Ghz 天線

4

USB 傳輸線 (USB A 對迷你 USB)

Raspberry Pi 3B+ 以上版本,並搭載 Raspbian OS 映像檔

在本程式碼研究室中,您需要使用 Raspberry Pi 3B+ 以上版本,並安裝 Raspbian Bullseye Lite OS 映像檔Raspbian Bullseye with Desktop。這部裝置會透過乙太網路連上網際網路,並設定為 OpenThread 邊界路由器 (OTBR) 的主機。

網路連線

連上網際網路的交換器 (或路由器) 和數條乙太網路線。用來將 Raspberry Pi 連接至 Linux 電腦,方便使用者透過主機設定 Raspberry Pi。

LinuxBDT

Telink Burning and Debugging Tool (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) 和 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
    
  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 建構指令,從 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 文件 - 入門指南

下載 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 電腦。

韌體編譯

本程式碼研究室將建構兩種類型的 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. 具備完整功能的 Thread 裝置,提供互動式指令列 (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 開發板連接至燒錄板,如下圖所示。

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 的閃光燈方法基本上與 ot-cli-ftd 相同。不過,韌體路徑和名稱有所不同。

刷機完成後,請標示這兩塊 B91 開發板,以利區分。將閃爍 ot-cli-ftd 的開發板標示為「FTD Joiner」,閃爍 ot-rcp 的開發板標示為「RCP」。

4. 設定 FTD Joiner 裝置的序列埠控制台

如圖片所示,將 FTD Joiner 直接插入 Linux 電腦的 USB 連接埠。

usb_connection.png

將 FTD Joiner 裝置連線至 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 負責 Thread 通訊。

無線電協同處理器 (RCP)

如要刷入 ot-rcp 韌體,請按照刷入 ot-cli-ftd 韌體的相同步驟操作。如下圖所示,將 B91 開發板連接至 Raspberry Pi 的 USB 連接埠。

OTBR_overview.png

Raspberry Pi

  1. 確認 Raspbian Bullseye Lite OS 映像檔Raspbian Bullseye with Desktop 已正確寫入 SD 卡。
  2. 您可以選擇透過 SSH 連線至 Raspberry Pi,或是直接使用 Raspbian Desktop。本程式碼研究室會使用 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 尚未啟動,請啟動 Docker:
    $ sudo dockerd
    
  4. OTBR 防火牆指令碼會在 Docker 容器內產生規則。在此之前,請執行 modprobe 來載入 iptables 的核心模組。
    $ sudo modprobe ip6table_filter
    

設定及執行 Docker

本程式碼研究室會直接從 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 Joiner 裝置和 OTBR 已準備就緒,你可以繼續下一個步驟,建構 Thread 網路。

6. 建立 Thread 網路

在 RCP 上建立 Thread 網路

我們會在 OTBR 上使用 ot-ctl 殼層建立 Thread 網路。如果您在上一節中退出了殼層,請在 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: 13
Channel Mask: 0x07fff800
Ext PAN ID: b07476e168eda4fc
Mesh Local Prefix: fd8c:60bc:a98:c7ba::/64
Network Key: c312485187484ceb5992d2343baaf93d
Network Name: OpenThread-599c
PAN ID: 0x599c
PSKc: 04f79ad752e8401a1933486c95299f60
Security Policy: 672 onrc 0
Done

ot-cli-ftd 裝置加入這個 Thread 網路時,會使用 OTBR 在建立網路時隨機產生的網路金鑰。

透過頻外委派,將 FTD Joiner 新增至 Thread

頻外委派是指透過非無線方式 (例如在 OpenThread CLI 中手動輸入),將網路憑證傳輸至等待加入網路的裝置。在序列埠控制台中,依序輸入下列指令給 FTD Joiner。

索引

指令

簡介

預期的回覆

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

檢查裝置狀態。

child/router
完成

拓撲

在 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 的 RLOC16 最初為 0xb000,FTD Joiner 的 RLOC16 最初為 0xb001。然後,FTD Joiner 的 RLOC16 會在取得路由器 ID 後變成 0x8400。從中可看出 FTD Joiner 已從子項升級為路由器。

目前的 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 Joiner 的序列埠控制台中輸入下列指令,執行 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 Joiner 已收到 OTBR 傳回的 Ping 回應。兩部裝置之間的通訊成功。

UDP 通訊

OpenThread 提供的應用程式服務也包含 UDP。您可以使用 UDP API 在 Thread 網路中的節點之間傳遞資訊,或透過邊界路由器將資訊傳遞至外部網路。如需 OpenThread UDP API 的詳細介紹,請參閱 OpenThread CLI - UDP 範例。本程式碼研究室會使用其中的部分 API,在 OTBR 和 FTD Joiner 之間傳輸資訊。

首先,請取得 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 Joiner 的 UDP。繫結裝置的 1022 連接埠,然後將 5 位元組的 hello 訊息傳送至 OTBR。

> 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 Joiner 的 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 資源,包括:

參考文件: