使用 nRF52840 板和 OpenThread 建構 Thread 網路

透過集合功能整理內容 你可以依據偏好儲存及分類內容。

1. 簡介

26b7f4f6b3ea0700.png

Google 發布的 OpenThreadThread® 網路通訊協定的開放原始碼實作。Google Nest 已發布 OpenThread,讓開發人員以廣泛的方式使用 Nest 產品所採用的技術,加快智慧聯網家庭的產品開發速度。

Thread 規格定義了以 IPv6 為基礎的可靠、低功耗的無線裝置對裝置通訊通訊協定,適用於家庭應用程式。OpenThread 實作所有 Thread 網路層,包括 IPv6、6LoWPAN、IEEE 802.15.4 及 MAC 安全、網格連結建立和網格轉送。

在本程式碼研究室中,您要在實際硬體上編寫 OpenThread,建立及管理 Thread 網路,並在節點之間傳遞訊息。

4806d16a8c137c6d.jpeg

課程內容

  • 將 OpenThread CLI 二進位檔建構並閃爍至開發板
  • 建立由 Linux 機器和開發板組成的 RCP
  • 使用 OpenThread Daemon 和 ot-ctl 與 RCP 通訊
  • 使用 GNU 螢幕和 OpenThread CLI 手動管理 Thread 節點
  • 將裝置安全分配到 Thread 網路中
  • IPv6 多播功能的運作方式
  • 在有 UDP 的執行緒節點之間傳送訊息

軟硬體需求

硬體:

  • 3 個北歐半導體 nRF52840 開發板
  • 3 USB 轉 Micro-USB 傳輸線以連接 Jamboard
  • 配備至少 3 個 USB 連接埠的 Linux 機器

軟體:

  • GNU 工具鍊
  • 北歐 nRF5x 指令列工具
  • Segger J-Link 軟體
  • OpenThread
  • Git

2. 開始使用

OpenThread 模擬

在開始之前,建議您先執行 OpenThread 模擬程式碼研究室,熟悉 Thread 的基本概念和 OpenThread CLI。

序列埠終端機

您應該已經熟悉如何透過終端機連線至序列埠。本程式碼研究室會使用 GNU 螢幕並提供使用總覽,但其他終端機軟體也都能使用。

Linux 機器

本程式碼研究室旨在使用 i386 或 x86 型 Linux 機器,做為無線電共同處理器 (RCP) Thread 裝置的主機,並刷新所有 Thread 開發板。所有步驟均在 Ubuntu 14.04.5 LTS (Trusty Tahr) 上進行測試。

北歐半導體 nRF52840 電路板

本程式碼研究室使用三個 nRF52840 PDK 電路板

a6693da3ce213856.png

我們使用 SEGGER J-Link 來編寫具備內建 JTAG 模組的 nRF52840 板。在 Linux 電腦上進行安裝。

為機器下載適當的套件,並安裝在適當位置。在 Linux 中則為 /opt/SEGGER/JLink

安裝 nRF5x 指令列工具

nRF5x 指令列工具可以讓您將 OpenThread 二進位檔閃爍到 nRF52840 板。在 Linux 電腦上安裝適當的 nRF5x-Command-Line-Tools-<OS> 版本。

將擷取的套件放入根資料夾 ~/

安裝 ARM GNU 工具鍊

ARM GNU 工具鍊用於建構。

建議您將擷取的封存檔案放在 Linux 機器的 /opt/gnu-mcu-eclipse/arm-none-eabi-gcc/ 中。按照封存readme.txt檔案的操作說明進行安裝操作說明。

安裝畫面 (選用)

螢幕是一種簡單的工具,可用於存取透過序列埠連線的裝置。本程式碼研究室會使用螢幕,但您可以使用任何序列埠終端機應用程式。

$ sudo apt-get install screen

3. 複製存放區

OpenThread

複製並安裝 OpenThread。script/bootstrap 指令會確保工具鍊已安裝且環境設定正確:

$ mkdir -p ~/src
$ cd ~/src
$ git clone --recursive https://github.com/openthread/openthread.git
$ cd openthread
$ ./script/bootstrap

建構 OpenThread Daemon:

$ script/cmake-build posix -DOT_DAEMON=ON

現在你可以開始建構 nRF52840 黑板上的 OpenThread 並刷新。

4. 設定 RCP 結合器

建構及刷新

使用結合器和原生 USB 功能建構 OpenThread nRF52840 範例。裝置使用「彙整」角色進行安全驗證,並提交至 Thread 網路。原生 USB 可讓您使用 USB CDC ACM 做為 nRF52840 和主機之間的序列傳輸。

一律先執行 rm -rf build 來清理先前的建構作業的存放區。

$ cd ~/src
$ git clone --recursive https://github.com/openthread/ot-nrf528xx.git
$ cd ot-nrf528xx
$ script/build nrf52840 USB_trans

前往使用 OpenThread RCP 二進位檔的目錄,並將其轉換為十六進位格式:

$ cd ~/src/ot-nrf528xx/build/bin
$ arm-none-eabi-objcopy -O ihex ot-rcp ot-rcp.hex

將 USB 傳輸線接上 Min-USB 偵錯連接埠,找到 nRF52840 白板上的外接電源接頭,然後插入 Linux 電腦。將 nRF52840 板上的 nRF 電源開關切換至 VDD。正確連線後,即可啟動 LED5

20a3b4b480356447.png

如果這是連接至 Linux 機器的第一個 Jamboard,會顯示為序列埠 /dev/ttyACM0 (所有 nRF52840 板均使用 ttyACM 做為序列埠 ID)。

$ ls /dev/ttyACM*
/dev/ttyACM0

請注意,用於 RCP 的 nRF52840 板的序號:

c00d519ebec7e5f0.jpeg

前往 nRFx 指令列工具的位置,並使用 Board' 序號將 OpenThread RCP 十六進位檔案閃爍到 nRF52840 白板。請注意,如果省略 --verify 旗標,系統會顯示警告訊息,說明 Flash 處理程序可能會失敗,且不會發生錯誤。

$ cd ~/nrfjprog/
$ ./nrfjprog -f nrf52 -s 683704924  --verify --chiperase --program \
       ~/src/ot-nrf528xx/build/bin/ot-rcp.hex --reset

輸出成功時,會產生下列輸出內容:

Parsing hex file.
Erasing user available code and UICR flash areas.
Applying system reset.
Checking that the area to write is not protected.
Programing device.
Applying system reset.
Run.

為 Jamboard 加上「RCP」標籤,這樣稍後就會避免混淆該角色。

連線至原生 USB

由於 OpenThread RCP 建構允許使用原生 USB CDC ACM 做為序列傳輸,因此您必須使用 nRF52840 板上的 nRF USB 通訊埠與 RCP 主機 (Linux 機器) 進行通訊。

從閃爍的 nRF52840 電路板的偵錯連接埠上拔除 USB 傳輸線的 Micro-USB 端,然後重新接上 RESET 按鈕旁邊的 Micro-USB nRF USB 連接埠。將「nRF 電源」切換按鈕設為「USB」

46e7b670d2464842.png

啟動 OpenThread Daemon

在 RCP 設計中,使用 OpenThread Daemon 與 Thread 裝置通訊及管理。使用 -v 詳細旗標來啟動 ot-daemon,以便查看記錄輸出內容並確認裝置正在運作:

$ cd ~/src/openthread
$ sudo ./build/posix/src/posix/ot-daemon -v \
    'spinel+hdlc+uart:///dev/ttyACM0?uart-baudrate=115200'

如果成功,詳細模式中的 ot-daemon 會產生類似以下的輸出內容:

ot-daemon[12463]: Running OPENTHREAD/thread-reference-20200818-1938-g0f10480ed; POSIX; Aug 30 2022 10:55:05
ot-daemon[12463]: Thread version: 4
ot-daemon[12463]: Thread interface: wpan0
ot-daemon[12463]: RCP version: OPENTHREAD/thread-reference-20200818-1938-g0f10480ed; SIMULATION; Aug 30 2022 10:54:10

請將這個終端機視窗保持開啟,以便查看「ot-daemon」的記錄檔。

使用 ot-ctl 與 RCP 節點通訊。ot-ctl 使用與 OpenThread CLI 應用程式相同的 CLI。因此,您可以使用與其他模擬 Thread 裝置相同的方式控制 ot-daemon 節點。

在第二個終端機視窗中啟動 ot-ctl

$ sudo ./build/posix/src/posix/ot-ctl
>

檢查您使用 ot-daemon 啟動的節點 2 (RCP 節點) state

> state
disabled
Done

5. 設定 FTD

本程式碼研究室使用的另外兩個執行緒節點,皆是標準晶片系統 (SoC) 設計的全執行緒裝置 (FTD)。在實際工作環境設定中,您可以透過使用實際工作環境等級的網路介面驅動程式 wpantund 來控管 OpenThread NCP 執行個體,但在本程式碼研究室中,我們會使用 ot-ctl 這個 OpenThread CLI。

一部裝置做為佣金,可用來安全地透過該網路驗證及委託裝置。其他裝置也能做為彙整器,做為對 Thread 網路的驗證者。

建構及刷新

為 nRF52840 平台建構 OpenThread FTD 範例,並啟用「佣金與彙整者」角色:

$ cd ~/src/ot-nrf528xx
$ rm -rf build
$ script/build nrf52840 USB_trans -DOT_JOINER=ON -DOT_COMMISSIONER=ON

前往含有 OpenThread 完整執行緒裝置 (FTD) CLI 二進位檔的目錄,並將其轉換為十六進位格式:

$ cd ~/src/ot-nrf528xx/build/bin
$ arm-none-eabi-objcopy -O ihex ot-cli-ftd ot-cli-ftd.hex

將 USB 傳輸線連接到 Min-USB 連接埠和 nRF52840 板上外接電源接頭的 USB 連接埠,然後插入 Linux 電腦。如果 RCP 仍連接至 Linux 電腦,這個新板應顯示為序列埠 /dev/ttyACM1 (所有 nRF52840 Jamboard 均使用 ttyACM 做為序列埠 ID)。

$ ls /dev/ttyACM*
/dev/ttyACM0  /dev/ttyACM1

和先前一樣,記下用於 FTD 的 nRF52840 板的序號:

c00d519ebec7e5f0.jpeg

瀏覽至 nRFx 指令列工具的位置,並使用 board 的序號為 Openn CLI FTD 十六進位檔案閃爍:

$ cd ~/nrfjprog/
$ ./nrfjprog -f nrf52 -s 683704924 --verify --chiperase --program \
       ~/src/ot-nrf528xx/build/bin/ot-cli-ftd.hex --reset

將 Jamboard 標示為「Commissioner」。

連線至原生 USB

由於 OpenThread FTD 版本可讓您使用原生 USB CDC ACM 做為序列傳輸,因此您必須使用 nRF52840 板上的 nRF USB 通訊埠與 RCP 主機 (Linux 機器) 進行通訊。

從閃爍的 nRF52840 電路板的偵錯連接埠上拔除 USB 傳輸線的 Micro-USB 端,然後重新接上 RESET 按鈕旁邊的 Micro-USB nRF USB 連接埠。將「nRF 電源」切換按鈕設為「USB」

46e7b670d2464842.png

驗證版本

從終端機視窗使用 GNU 螢幕存取 OpenThread CLI,即可確認建構成功。nRF52840 電路板的波特率為 115200。

$ screen /dev/ttyACM1 115200

在新視窗中按鍵盤上的 Enter 鍵數次,即可開啟 OpenThread CLI > 提示。啟動 IPv6 介面並檢查位址:

> ifconfig up
Done
> ipaddr
fe80:0:0:0:1cd6:87a9:cb9d:4b1d
Done

使用 Ctrl + A 鍵 →

d 從 FTD Commissioner CLI 畫面中卸離,然後返回 Linux 終端機,讓下一個 Jamboard 能夠閃爍。您隨時可以透過指令列使用 screen -r。如要查看可用畫面的清單,請使用 screen -ls

$ screen -ls
There is a screen on:
        74182.ttys000.mylinuxmachine        (Detached)
1 Socket in /tmp/uscreens/S-username.

設定 FTD 聯合

使用現有的 ot-cli-ftd.hex 版本重複上述步驟,以轉換第三個 nRF52840 白板。完成後,請務必使用 nRF USB 連接埠將 Jamboard 重新連接至電腦,然後將 nRF 電源開關設為 VDD

如果另外兩個節點連接至 Linux 機器時,如果附加了此三板,則序列應顯示為序列埠 /dev/ttyACM2

$ ls /dev/ttyACM*
/dev/ttyACM0  /dev/ttyACM1  /dev/ttyACM2

將 Jamboard 標示為「聯合」,

使用 Screen 驗證時,請勿重新透過指令列建立新的 Screen 執行個體,請重新連結現有的執行個體,然後在其中開啟一個視窗 (用於 FTD 佣金):

$ screen -r

使用 Ctrl + A 鍵 → 在畫面中建立新視窗。c

系統隨即會顯示新的指令列提示。存取 FTD 彙整器的 OpenThread CLI:

$ screen /dev/ttyACM2 115200

在新視窗中按鍵盤上的 Return 鍵,開啟 OpenThread CLI > 提示。啟動 IPv6 介面並檢查位址:

> ifconfig up
Done
> ipaddr
fe80:0:0:0:6c1e:87a2:df05:c240
Done

現在 FTD 結合器 CLI 與 FTD 調度工具的螢幕執行個體相同,可以使用 Ctrl+a → n 進行切換。

使用 Ctrl + A 鍵 →

d 即可隨時退出畫面。

6. 終端機視窗設定

今後,你會在經常切換的 Thread 裝置之間進行切換,因此請確保所有裝置都處於直播狀態且易於存取。截至目前為止,我們一直都使用螢幕存取兩個 FTD,這項工具也可讓您在相同的終端機視窗中允許分割畫面。請使用此功能,瞭解其中一個節點如何回應另一個節點上發出的指令。

在理想情況下,您應有四個視窗:

  1. ot-daemon 服務/記錄
  2. RCP 連接者 (透過 ot-ctl)
  3. 透過 OpenThread CLI 執行 FTD 委員會
  4. 透過 OpenThread CLI 執行 FTD 聯合

如要使用自己的終端機 / 序列埠設定或工具,歡迎跳到下一個步驟。以最適合您的方式設定所有裝置的終端機視窗。

使用螢幕

為求使用方便,建議您僅啟動一個螢幕畫面工作階段。設定這兩種 FTD 時,您應該已經具備這項規定。

螢幕畫面中的所有指令都以 Ctrl+a 開頭。

基本螢幕指令:

透過指令列重新附加至螢幕工作階段

screen -r

離開螢幕工作階段

Ctrl + A 鍵 → d

在「螢幕」工作階段中開啟新視窗

Ctrl + A 鍵 → c

在同一個螢幕工作階段中切換視窗

Ctrl+A → n (前進) Ctrl + A 鍵 → p (返回)

在螢幕工作階段中終止目前的視窗

Ctrl + A 鍵 → k

分割畫面

使用螢幕時,您可以將終端機分割為多個視窗:

f1cbf1258cf0a5a.png

可使用 Ctrl+a 存取 screen 中的指令。每個指令都應該以這個存取金鑰組合開始。

如果您已確實遵循程式碼研究室,則應在相同的「畫面」執行個體中有兩個視窗 (FTD 委員會、FTD 加入器)。如要將螢幕畫面分割為兩個畫面,請先輸入您現有的螢幕工作階段:

$ screen -r

你必須使用其中一種 FTD 裝置。請在畫面中按照下列步驟操作:

  1. 按住 Ctrl + A 鍵 → S,即可水平分割視窗
  2. Ctrl + A → Tab,即可將遊標移至新的空白視窗
  3. 按下 Ctrl + A 鍵 → n,即可將這個新視窗切換至下一個視窗
  4. 如果檢視視窗與頂端視窗相同,請再次按下 Ctrl+A → n 鍵,查看其他 FTD 裝置

已一併顯示。按下 Ctrl+A → Tab 鍵即可切換。建議你使用 Ctrl+a → A 為每個視窗重新命名,以免混淆。

進階用途

如要進一步將畫面分割為象限,查看 ot-daemon 記錄和 RCP 彙整器 ot-ctl,就必須在同一個「畫面」執行個體中啟動這些服務。如要這麼做,請停止 ot-daemon 並結束 ot-ctl,然後在新的視窗中重新啟動 (Ctrl+A → c)。

這並非強制設定,而是做為使用者進行的運動。

使用下列指令分割及瀏覽視窗:

開啟新視窗

Ctrl + A 鍵 → c

垂直分割視窗

Ctrl + A 鍵 →

水平分割視窗

Ctrl + A 鍵 → S

跳到下一個顯示視窗

Ctrl + A 鍵 → Tab

將顯示的視窗向前或向後切換

Ctrl + A → np

重新命名目前的視窗

Ctrl + A 鍵 → A

按下 Ctrl+a → d 鍵即可隨時離開螢幕,然後透過指令列重新附加 screen -r

如要進一步瞭解螢幕,請參閱 GNU 螢幕快速參考指引

7. 建立 Thread 網路

現在,您已設定所有終端機視窗和畫面,接著就讓我們建立 Thread 網路。在 FTD Commissioner 中,建立新的作業資料集,並將其視為使用中的資料集。作業資料集是指您建立的 Thread 網路設定。

## FTD Commissioner ##
----------------------

> dataset init new
Done
> dataset
Active Timestamp: 1
Channel: 11
Channel Mask: 07fff800
Ext PAN ID: c0de7ab5c0de7ab5
Mesh Local Prefix: fdc0:de7a:b5c0/64
Network Key: 1234c0de7ab51234c0de7ab51234c0de
Network Name: OpenThread-c0de
PAN ID: 0xc0de
PSKc: ebb4f2f8a68026fc55bcf3d7be3e6fe4
Security Policy: 0, onrcb
Done

記下網路金鑰 1234c0de7ab51234c0de7ab51234c0de,稍後會用到。

將這個資料集設為使用中的資料集:

> dataset commit active
Done

啟動 IPv6 介面:

> ifconfig up
Done

啟動 Thread 通訊協定作業:

> thread start
Done

稍候片刻,即可查看裝置狀態。應為領導者。也可取得 RLOC16 以供日後參考。

## FTD Commissioner ##
----------------------

> state
leader
Done
> rloc16
0c00
Done

查看裝置的 IPv6 位址:

## FTD Commissioner ##
----------------------

> ipaddr
fdc0:de7a:b5c0:0:0:ff:fe00:fc00        # Leader Anycast Locator (ALOC)
fdc0:de7a:b5c0:0:0:ff:fe00:c00         # Routing Locator (RLOC)
fdc0:de7a:b5c0:0:6394:5a75:a1ad:e5a    # Mesh-Local EID (ML-EID)
fe80:0:0:0:1cd6:87a9:cb9d:4b1d         # Link-Local Address (LLA)

系統現在會從其他 Thread 裝置掃描時,顯示「程式碼研究室」網路。

RCP 加入人上的 ot-ctl 中:

## RCP Joiner ##
----------------

> scan
| PAN  | MAC Address      | Ch | dBm | LQI |
+------+------------------+----+-----+-----+
| c0de | 1ed687a9cb9d4b1d | 11 | -36 | 232 |

透過 FTD 彙整工具的 OpenThread CLI:

## FTD Joiner ##
----------------

> scan
| PAN  | MAC Address      | Ch | dBm | LQI |
+------+------------------+----+-----+-----+
| c0de | 1ed687a9cb9d4b1d | 11 | -38 | 229 |

如果「程式碼研究室」網路未顯示在清單中,請嘗試重新掃描。

8. 新增 RCP 結合器

「網路調度」並非啟用網路,這代表我們必須將 RCP 加入至我們剛才透過架構外調度程序建立的 Thread 網路。

在「FTD 委員會」中,我們記下了網路金鑰,例如 1234c0de7ab51234c0de7ab51234c0de。如果您需要再次查詢網路金鑰,請在 FTD Commissioner 中執行下列指令:

## FTD Commissioner ##

> dataset networkkey
1234c0de7ab51234c0de7ab51234c0de
Done

接著,在 RCP 結合器上,將啟用的資料集網路金鑰設為 FTD Commissioner 網路金鑰:

## RCP Joiner ##
----------------

> dataset networkkey 1234c0de7ab51234c0de7ab51234c0de
Done
> dataset commit active
Done

請檢查資料集,確保資料集設定正確無誤。

## RCP Joiner ##
----------------

> dataset
Network Key: 1234c0de7ab51234c0de7ab51234c0de

啟動 Thread,以讓 RCP 結合器加入「codelab」網路。等待幾秒鐘,檢查狀態 RLOC16 及其 IPv6 位址:

## RCP Joiner ##
----------------

> ifconfig up
Done
> thread start
Done
> state
child
Done
> rloc16
0c01
Done
> ipaddr
fdc0:de7a:b5c0:0:0:ff:fe00:0c01         # Routing Locator (RLOC)
fdc0:de7a:b5c0:0:66bf:99b9:24c0:d55f    # Mesh-Local EID (ML-EID)
fe80:0:0:0:18e5:29b3:a638:943b          # Link-Local Address (LLA)
Done

請記下網格-本機 IPv6 位址 (在這裡為 fdc0:de7a:b5c0:0:66bf:99b9:24c0:d55f),以便稍後使用。

返回 FTD 委員會,查看路由器和子表格,確認兩部裝置都屬於同一個網路。使用 RLOC16 來識別 RCP 結合器。

## FTD Commissioner ##
----------------------

> router table
| ID | RLOC16 | Next Hop | Path Cost | LQ In | LQ Out | Age | Extended MAC     |
+----+--------+----------+-----------+-------+--------+-----+------------------+
|  3 | 0x0c00 |        3 |         0 |     0 |      0 |  35 | 1ed687a9cb9d4b1d |

Done
> child table
| ID  | RLOC16 | Timeout    | Age        | LQ In | C_VN |R|S|D|VER| Extended MAC     |
+-----+--------+------------+------------+-------+------+-+-+-+---+------------------+
|   1 | 0x0c01 |        240 |         25 |     3 |   89 |1|1|1|  2| 1ae529b3a638943b |
Done

連線偵測 RCP 彙整器的網格本機位址 (從 RCP 結合器取得的網格本機位址,並使用 ipaddr 輸出內容) 來驗證連線:

## FTD Commissioner ##
----------------------

> ping fdc0:de7a:b5c0:0:66bf:99b9:24c0:d55f
> 8 bytes from fdc0:de7a:b5c0:0:66bf:99b9:24c0:d55f: icmp_seq=1 hlim=64 time=40ms

我們現在包含一個包含兩個節點的執行緒網路,如下圖所示:

otcodelab_top01C_2nodes.png

拓撲圖

在您瀏覽程式碼研究室的其餘部分時,每當網路狀態變更,我們都會顯示新的執行緒拓撲圖。節點角色的如下所示:

b75a527be4563215.png

路由器一律為五邊型,而「終端裝置」則一律為圓形。每個節點上的數字代表 CLI 輸出中顯示的路由器 ID 或子項 ID,視每個節點目前的角色和狀態而定。

9. 委託 FTD 加入會議

現在,將第三個 Thread 裝置新增至「codelab」網路。我們這次會使用更安全的頻帶佣金程序,並僅允許 FTD 加入會議。

在「FTD Contacter」中取得 eui64,以便 FTD 委員會進行識別:

## FTD Joiner ##
----------------

> eui64
2f57d222545271f1
Done

在「FTD Commissioner」中,啟動調度工具,並指定可加入裝置的 eui64 以及加入器憑證,例如 J01NME。「彙整者憑證」是指由所有大寫字母組成的裝置專屬字串 (0-9 和 A-Y,可讀性包括 I、O、Q 和 Z),長度必須介於 6 到 32 個字元之間。

## FTD Commissioner ##
----------------------

> commissioner start
Done
> commissioner joiner add 2f57d222545271f1 J01NME
Done

切換至 FTD 聯合。根據您剛才在 FTD 委員會中設定的彙整憑證,開始加入彙整者角色:

## FTD Joiner ##
----------------

> ifconfig up
Done
> joiner start J01NME
Done

您會在一分鐘內收到確認成功的確認訊息:

## FTD Joiner ##
----------------

>
Join success

建立 Thread,讓 FTD 聯合加入「codelab」網路,並立即檢查狀態和 RLOC16:

## FTD Joiner ##
----------------

> thread start
Done
> state
child
Done
> rloc16
0c02
Done

請檢查裝置的 IPv6 位址。請注意,沒有任何 ALOC。原因在於這部裝置不是領導品牌,或具備需要 ALOC 的 Anycast 專屬角色。

## FTD Joiner ##
----------------

> ipaddr
fdc0:de7a:b5c0:0:0:ff:fe00:c02         # Routing Locator (RLOC)
fdc0:de7a:b5c0:0:3e2e:66e:9d41:ebcd    # Mesh-Local EID (ML-EID)
fe80:0:0:0:e4cd:d2d9:3249:a243         # Link-Local Address (LLA)

立即切換至 FTD 委員會,並檢查路由器和子表格,確認「程式碼研究室」網路中有三個裝置:

## FTD Commissioner ##
----------------------

> router table
| ID | RLOC16 | Next Hop | Path Cost | LQ In | LQ Out | Age | Extended MAC     |
+----+--------+----------+-----------+-------+--------+-----+------------------+
|  3 | 0x0c00 |        3 |         0 |     0 |      0 |  50 | 1ed687a9cb9d4b1d |

> child table
| ID  | RLOC16 | Timeout    | Age        | LQ In | C_VN |R|S|D|N| Extended MAC     |
+-----+--------+------------+------------+-------+------+-+-+-+-+------------------+
|   1 | 0x0c01 |        240 |         25 |     3 |   89 |1|1|1|1| 1ae529b3a638943b |
|   2 | 0x0c02 |        240 |         15 |     3 |   44 |1|1|1|1| e6cdd2d93249a243 |
Done

根據 RLOC16 的規定,FTD 連接器已透過網路 (子項) 連接至網路。更新後的拓撲如下:

otcodelab_top01C_ed01.png

10. 執行緒實際運作

本程式碼研究室中的執行緒裝置是一種名為「路由器適用終端裝置」(REED) 的全執行緒裝置 (FTD)。這代表其可以做為路由器或終端裝置使用,並可以將其從最終裝置推送到路由器。

Thread 最多可支援 32 個路由器,但試著將路由器數量維持在 16 到 23 個之間。如果 REED 是以結束裝置 (子項) 的方式附加,且路由器的數量低於 16,則在兩分鐘的隨機時間結束後,系統就會自動將路由器升級為路由器。

如果新增 FTD 彙整器後,您的執行緒清單中有兩個子項,請等待至少兩分鐘,然後在 FTD 委員會重新檢查路由器和子資料表:

## FTD Commissioner ##
----------------------

> router table
| ID | RLOC16 | Next Hop | Path Cost | LQ In | LQ Out | Age | Extended MAC     |
+----+--------+----------+-----------+-------+--------+-----+------------------+
|  3 | 0x0c00 |        3 |         0 |     0 |      0 |  50 | 1ed687a9cb9d4b1d |
| 46 | 0xb800 |       63 |         0 |     3 |      3 |   1 | e6cdd2d93249a243 |

> child table
| ID  | RLOC16 | Timeout    | Age        | LQ In | C_VN |R|S|D|N| Extended MAC     |
+-----+--------+------------+------------+-------+------+-+-+-+-+------------------+
|   1 | 0x0c01 |        240 |         61 |     3 |   89 |1|1|1|1| 1ae529b3a638943b |
Done

FTD 加入者 (Extended MAC = e6cdd2d93249a243) 已自行升級為路由器。請注意,RLOC16 不同 (b800 而非 0c02)。這是因為 RLOC16 是以裝置的路由器 ID 和子項 ID 為基礎。從端對端裝置轉換為路由器時,路由器 ID 和子 ID 值也會隨之改變,RLOC16 也是如此。

otcodelab_top01C.png

FTD 聯合上確認新狀態和 RLOC16:

## FTD Joiner ##
----------------

> state
router
Done
> rloc16
b800
Done

降級 FTD 加入會議者

如要測試這個行為,您可以手動將「FTD 聯合工具」從路由器降級回最終裝置。將狀態變更為子項並檢查 RLOC16:

## FTD Joiner ##
----------------

> state child
Done
> rloc16
0c03
Done

otcodelab_top01C_ed02.png

返回「FTD 委員會」後,FTD 加入會議程式現在會顯示於子資料表中 (ID = 3)。轉換期間也可能發生上述情形:

## FTD Commissioner ##
----------------------

> router table
| ID | RLOC16 | Next Hop | Path Cost | LQ In | LQ Out | Age | Extended MAC     |
+----+--------+----------+-----------+-------+--------+-----+------------------+
|  3 | 0x0c00 |        3 |         0 |     0 |      0 |  50 | 1ed687a9cb9d4b1d |
| 46 | 0xb800 |       63 |         0 |     3 |      3 |   1 | e6cdd2d93249a243 |

> child table
| ID  | RLOC16 | Timeout    | Age        | LQ In | C_VN |R|S|D|N| Extended MAC     |
+-----+--------+------------+------------+-------+------+-+-+-+-+------------------+
|   1 | 0x0c01 |        240 |         61 |     3 |   89 |1|1|1|1| 1ae529b3a638943b |
|   3 | 0x0c03 |        240 |         16 |     3 |   94 |1|1|1|1| e6cdd2d93249a243 |
Done

一段時間後,就會切換回 RLOC 為 b800 的路由器。

otcodelab_top01C.png

移除主管

所有執行緒執行緒均會自動選取領導者。也就是說,如果目前的領導者已從執行緒網路中移除,其他路由器就會成為新的領導者。

在「FTD Commissioner」中,關閉 Thread 從 Thread 網路中移除:

## FTD Commissioner ##
----------------------

> thread stop
Done
> ifconfig down
Done

在 2 分鐘內,FTD 接頭將成為新的執行緒領導者。檢查 FTD 聯合驗證的狀態和 IPv6 位址,以確認下列事項:

## FTD Joiner ##
----------------

> state
leader
Done
> ipaddr
fdc0:de7a:b5c0:0:0:ff:fe00:fc00       # Now it has the Leader ALOC!
fdc0:de7a:b5c0:0:0:ff:fe00:b800
fdc0:de7a:b5c0:0:3e2e:66e:9d41:ebcd
fe80:0:0:0:e4cd:d2d9:3249:a243
Done

otcodelab_top02C_01.png

請查看子表格。請注意,有新的 RLOC16。這是 RCP 結合器 (如其 ID 和擴充 MAC) 所指示。為使 Thread 網路保持搭配使用,我們已將上層路由器從 FTD 主持人改為 FTD 加入會議者。這會導致 RCP 彙整器發生新的 RLOC16 (因為其路由器 ID 已從 3 變更為 46)。

## FTD Joiner ##
----------------

> child table
| ID  | RLOC16 | Timeout    | Age        | LQ In | C_VN |R|S|D|N| Extended MAC     |
+-----+--------+------------+------------+-------+------+-+-+-+-+------------------+
|   1 | 0xb801 |        240 |         27 |     3 |  145 |1|1|1|1| 1ae529b3a638943b |
Done

您可能需要等待幾分鐘,讓 RCP 加入會議者以 FTD 彙整器的形式附加至兒童。查看狀態和 RLOC16 以確認:

## RCP Joiner ##
--------------

> state
child
> rloc16
b801

重新附加 FTD 委員會

有兩個節點的 Thread 網路並不有趣。讓 FTD 委員會重新上線。

在「FTD Commissioner」中,重新啟動 Thread:

## FTD Commissioner ##
----------------------

> ifconfig up
Done
> thread start
Done

這項服務會在兩分鐘內自動重新連線至「程式碼研究室」網路,做為「最終裝置」,然後自行推送至路由器。

## FTD Commissioner ##
----------------------

> state
router
Done

檢查 FTD 連接器上的路由器和子資料表,以確認:

## FTD Joiner ##
----------------

> router table
| ID | RLOC16 | Next Hop | Path Cost | LQ In | LQ Out | Age | Extended MAC     |
+----+--------+----------+-----------+-------+--------+-----+------------------+
|  3 | 0x0c00 |       63 |         0 |     3 |      3 |   0 | 1ed687a9cb9d4b1d |
| 46 | 0xb800 |       46 |         0 |     0 |      0 |  15 | e6cdd2d93249a243 |

> child table
| ID  | RLOC16 | Timeout    | Age        | LQ In | C_VN |R|S|D|N| Extended MAC     |
+-----+--------+------------+------------+-------+------+-+-+-+-+------------------+
|   1 | 0xb801 |        240 |        184 |     3 |  145 |1|1|1|1| 1ae529b3a638943b |
Done

otcodelab_top02C_02.png

我們的 Thread 網路包含三個節點。

11. 疑難排解

在不同終端機或螢幕視窗中管理含有多個裝置的 Thread 網路可能很複雜。如有任何問題,請利用這些提示來「重設」網路或工作區狀態。

螢幕

如果您因為設定遺失 (例如太多螢幕視窗或螢幕上的螢幕),請繼續使用 Ctrl+a → k 鍵終止畫面視窗,直到不存在為止,指令列指令列上的 screen -ls 則會輸出 No Sockets found。然後重新建立每部裝置的螢幕視窗。即使裝置螢幕終止,系統仍會保留裝置狀態。

執行緒節點

如果這個程式碼研究室未說明執行緒網路拓撲,或基於某些原因而中斷節點連線 (原因可能是 Linux 機器為這些裝置提供休眠功能),則建議先關閉 Thread 並清除網路憑證,再從「建立 Thread 網路」步驟重新開始。

如要重設 FTD:

## FTD Commissioner or FTD Joiner ##
------------------------------------

> thread stop
Done
> ifconfig down
Done
> factoryreset
Done

RCP 可以透過相同的方式重設 ot-ctl

## RCP Joiner ##
----------------

> thread stop
Done
> ifconfig down
Done
> factoryreset
Done

12. 使用多播

使用多播功能,可將資訊一次傳送到一組裝置。在 Thread 網路中,系統會針對特定裝置群組保留特定位址,以便用於不同的裝置群組 (視範圍而定)。

IPv6 位址

範圍

已送達

ff02::1

連結本機

所有 FTD 和 MED

ff02::2

連結本機

所有 FTD 和邊界路由器

ff03::1

網格-本地

所有 FTD 和 MED

ff03::2

網格-本地

所有 FTD 和邊界路由器

由於我們未在本程式碼研究室中使用邊界路由器,因此讓我們將焦點放在兩個 FTD 和 MED 多播位址。

「連結本機」範圍包含可透過單一無線電傳輸功能或單一「躍點」觸及的所有 Thread 介面。網路拓撲會決定哪些裝置回應 ff02::1 多點傳送地址。

呼叫 FTD 委員會ff02::1

## FTD Commissioner ##
----------------------

> ping ff02::1
> 8 bytes from fe80:0:0:0:e4cd:d2d9:3249:a243: icmp_seq=2 hlim=64 time=9ms

網路中還有另外兩部裝置 (FTD 聯合群組和 RCP 加入者),但 FTD 委員會收到來自 FTD 聯合連結 (LLA) 的一則回應。這表示 FTD 接線員是唯一能在單一躍點中到達的 FTD 導師。

otcodelab_top02C_02_LL.png

現在,請偵測 FTD 彙整工具ff02::1

## FTD Joiner ##
----------------

> ping ff02::1
> 8 bytes from fe80:0:0:0:1cd6:87a9:cb9d:4b1d: icmp_seq=1 hlim=64 time=11ms
8 bytes from fe80:0:0:0:18e5:29b3:a638:943b: icmp_seq=1 hlim=64 time=24ms

有兩則回覆!檢查其他裝置的 IPv6 位址時,我們發現第一個 IP 位址 (結尾為 4b1d) 是 FTD 委員會的 LLA,第二組 (結尾為 943b) 是 RCP 的加入者 LLA。

otcodelab_top02C_02_LL02.png

這意味著 FTD 追蹤者可以直接與 FTD 委員會和 RCP 聯合人員聯絡,以確認我們的拓撲。

網格-本地

Metal-Local 範圍包含可透過同一個 Thread 網路存取的所有 Thread 介面。讓我們看看對 ff03::1 多播地址的連線偵測 (ping) 回應。

呼叫 FTD 委員會ff03::1

## FTD Commissioner ##
----------------------

> ping ff03::1
> 8 bytes from fdc0:de7a:b5c0:0:0:ff:fe00:b800: icmp_seq=3 hlim=64 time=9ms
8 bytes from fdc0:de7a:b5c0:0:66bf:99b9:24c0:d55f: icmp_seq=3 hlim=64 time=68ms

這次,FTD 委員會收到了兩則回應,分別來自 FTD 聯合追蹤者 (RLOC、結尾為 b800) 和 RCP 結合者 (結尾為 b800,結尾為 d55f) 的回覆。這是因為網格區域範圍包含整個 Thread 網路。無論裝置位於哪個網路,系統都會訂閱 ff03::1 位址。

otcodelab_top02C_02_ML.png

透過 FTD 連接器連線偵測 ff03::1,以確認相同的行為:

## FTD Joiner ##
----------------

> ping ff03::1
> 8 bytes from fdc0:de7a:b5c0:0:0:ff:fe00:c00: icmp_seq=2 hlim=64 time=11ms
8 bytes from fdc0:de7a:b5c0:0:66bf:99b9:24c0:d55f: icmp_seq=2 hlim=64 time=23ms

otcodelab_top02C_02_LL02.png

請留意這兩個 ping 輸出內容的回覆時間。RCP 加入者花費的時間超過 68 毫秒,導致觸及 FTD 委員會 (28 毫秒)。因為 FTD 聯合接洽者需要兩個躍點才能進入 FTD 委員會,

您可能也注意到,網狀區域多播連線偵測 (ping) 是針對兩種 FTD (而非 RCP 連接器) 回應 RLOC。這是因為 FTD 是網路中的路由器,而 RCP 則是終端裝置。

查看 RCP 結合器的狀態以確認:

## RCP Joiner ##
----------------

> state
child

13. 使用 UDP 傳送訊息

OpenThread 提供的應用程式服務之一是「使用者資料元通訊協定」(UDP),這是一種傳輸層通訊協定。使用 OpenThread 建構的應用程式可利用 UDP API,在 Thread 網路中的節點之間或外部網路 (如網際網路) 的其他裝置上傳遞訊息 (前提是 Thread 網路含有邊界路由器)。

UDP 通訊端是透過 OpenThread CLI 公開。讓它在兩個 FTD 之間傳遞訊息。

取得 FTD 彙整工具的網格本機 EID 位址。我們可以使用此位址,因為可在 Thread 網路中的任何位置存取。

## FTD Joiner ##
----------------

> ipaddr
fdc0:de7a:b5c0:0:0:ff:fe00:fc00        # Leader Anycast Locator (ALOC)
fdc0:de7a:b5c0:0:0:ff:fe00:b800        # Routing Locator (RLOC)
fe80:0:0:0:e4cd:d2d9:3249:a243         # Link-Local Address (LLA)
fdc0:de7a:b5c0:0:3e2e:66e:9d41:ebcd    # Mesh-Local EID (ML-EID)
Done

針對任何 IPv6 位址啟動 UDP 並將其繫結至通訊端:

## FTD Joiner ##
----------------

> udp open
Done
> udp bind :: 1212

切換至 FTD Commissioner,啟動 UDP,然後透過設定的 ML-EID,連線至您在 FTD 聯合會所設定的通訊端:

## FTD Commissioner ##
----------------------

> udp open
Done
> udp connect fdc0:de7a:b5c0:0:3e2e:66e:9d41:ebcd 1212
Done

UDP 連線應在兩個節點之間生效。向 FTD 委員會發送訊息:

## FTD Commissioner ##
----------------------

> udp send hellothere
Done

已在 FTD 加入工具上收到 UDP 訊息!

## FTD Joiner ##
----------------

> 10 bytes from fdc0:de7a:b5c0:0:0:ff:fe00:c00 49153 hellothere

14. 恭喜!

你已建立實體執行緒網路!

b915c433e7027cc7.png

現在你知道:

  • Thread 裝置類型、角色和範圍之間的差異
  • Thread 裝置如何在網路中管理狀態
  • 如何使用 UDP 在節點之間傳送簡單訊息

後續步驟

以本程式碼研究室為基礎,請嘗試以下練習:

  • 使用 ot-cli-mtd 二進位檔將 FTD 彙整畫面重新以 MTD 重新整理,並觀察它本身不會升級為路由器,或試圖成為領導者
  • 在網路中新增更多裝置 (試試不同的平台!),並使用路由器和子表格,以及拓撲的多點傳送連線偵測 (ping),以便宣告拓撲
  • 使用 pyspinel 控制 NCP
  • 使用 OpenThread Border 路由器將 NCP 轉換為邊界路由器,並將 Thread 網路連線至網際網路

延伸閱讀

查看 openthread.ioGitHub,取得各式各樣的 OpenThread 資源,包括:

參考資料: