透過 nRF52840 主機板和 OpenThread 建立 Thread 網路

一、簡介

26b7f4f6b3ea0700.png

Google 提供的 OpenThread 是一種開放原始碼的 Thread® 網路通訊協定實作。Google Nest 已推出 OpenThread,讓開發人員廣泛使用 Nest 產品所開發的技術,藉此加快智慧聯網家庭產品的開發速度。

Thread 規格定義了家用應用程式專用的 IPv6 穩定、安全且低功耗裝置對裝置通訊通訊協定。OpenThread 會實作所有 Thread 網路層,包括具備 MAC 安全性的 IPv6、6LoWPAN、IEEE 802.15.4、網格網格建立以及網格路由。

在這個程式碼研究室中,您將使用真正的硬體編寫 OpenThread、建立及管理 Thread 網路,以及在節點之間傳送訊息。

4806d16a8c137c6d.jpeg

須知事項

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

事前準備

硬體:

  • 3 北歐半導體 nRF52840 開發電路板
  • 3 個 USB 對 Micro-USB 傳輸線連接主機板
  • 具備至少 3 個 USB 連接埠的 Linux 電腦

軟體:

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

2. 開始使用

OpenThread 模擬

開始之前,建議您先透過 OpenThread 模擬程式碼研究室,熟悉基本的執行緒概念和 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 為 nRF52840 電路板進行程式設計,該板上有 JTAG 模組。請在 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 合併程式

建立和閃光燈

使用 Join 和原生 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 傳輸線插入 nRF52840 電路上外部電源插頭旁的 Micro-USB 偵錯連接埠,然後插入 Linux 電腦。將 nRF52840 電路板的 nRF 電源開關設為 VDD。正確連線後,LED5 為開啟狀態。

20a3b4b480356447.png

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

$ ls /dev/ttyACM*
/dev/ttyACM0

請注意,RCP 使用的 nRF52840 電路序號:

c00d519ebec7e5f0.jpeg

前往 nRFx 指令列工具的位置,接著使用 Openboard 的序號開啟 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 電腦) 通訊。

將 USB 傳輸線的 Micro-USB 端從快閃的 nRF52840 電路板的偵錯連接埠拔除,然後再插回 RESET 按鈕旁邊的 Micro-USB nRF USB 連接埠的 Google Ads 新帳戶重新申請驗證。將「nRF 電源」開關設為 [USB]

46e7b670d2464842.png

開啟 OpenThread Daemon

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

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

成功後,動詞的 ot-daemon 會產生類似以下的輸出內容:

ot-daemon[228024]: Running OPENTHREAD/20191113-00831-gfb399104; POSIX; Jun  7 2020 18:05:15
ot-daemon[228024]: Thread version: 2
ot-daemon[228024]: RCP version: OPENTHREAD/20191113-00831-gfb399104; SIMULATION; Jun  7 2020 18:06:08

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

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

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

$ ./build/posix/bin/ot-ctl
>

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

> state
disabled
Done

5. 設定 FTD

本程式碼研究室中另外使用的兩個執行緒節點是標準晶片系統 (SoC) 設計中的完整執行緒裝置 (FTD)。在「正式版」設定中,使用者可能會使用 wpantund (實際工作環境等級的網路介面驅動程式) 控制 OpenThread NCP 執行個體,但在這個程式碼研究室中,我們使用 ot-ctl、OpenThread 。

每部裝置都屬於「佣金」功能,能夠安全地對裝置進行驗證及委託裝置。其他裝置則可用來執行「參與者」驗證,確保專員能夠向 Thread 網路進行驗證。

建立和閃光燈

為 nRF52840 平台建構 OpenThread FTD 範例,並啟用 Commissioner 和 Joiner 角色:

$ 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 傳輸線插入 nRF52840 電路上外部電源插頭旁的 Micro-USB 連接埠,然後插入 Linux 電腦。如果 RCP 仍連接至 Linux 電腦,這個新板會顯示為序列埠 /dev/ttyACM1 (所有 nRF52840 主機會透過 ttyACM 做為序列埠 ID)。

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

如上所述,請注意 FTD 使用的 nRF52840 電路序號:

c00d519ebec7e5f0.jpeg

前往 nRFx 指令列工具的位置,接著使用 Openboard CLI FTD 十六進位檔案,在 nRF52840 主機上將這個檔案加密 (使用主機序號的編號):

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

將標籤標示為「委員會」。

連線至原生 USB

由於 OpenThread FTD 版本允許使用原生 USB CDC ACM 做為序列傳輸,因此必須使用 nRF52840 主機上的 nRF USB 通訊埠與 RCP 主機 (Linux 電腦) 通訊。

將 USB 傳輸線的 Micro-USB 端從快閃的 nRF52840 電路板的偵錯連接埠拔除,然後再插回 RESET 按鈕旁邊的 Micro-USB nRF USB 連接埠的 Google Ads 新帳戶重新申請驗證。將「nRF 電源」開關設為 [USB]

46e7b670d2464842.png

驗證版本

在終端機視窗中使用 GNU 螢幕存取 OpenThread CLI 以驗證建構成功。nRF52840 主機的波特率為 115200。

$ screen /dev/ttyACM1 115200

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

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

使用 Ctrl + A →

d 從 FTD 委員會 CLI 卸離並返回 Linux 終端機,以便閃爍下一個 Jamboard。您隨時可以在指令列中使用 screen -r 來重新輸入 CLI, 如要查看可用畫面清單,請使用 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 連接埠將電路板重新連接至電腦,並將 nRF 電源開關設為 VDD

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

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

將留言板標示為「參與者」。

使用螢幕進行驗證時,與其透過指令列建立新的螢幕執行個體,而是重新連結現有的執行個體,並在其中建立新視窗 (用於您用於 FTD 專員的帳戶):

$ screen -r

使用 Ctrl + A 鍵在畫面中建立新視窗 → c的 Google Ads 新帳戶重新申請驗證。

新的指令列提示會隨即顯示。存取 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. 終端機視窗設定

未來你會在各部裝置之間來回切換,因此請確認所有裝置均已上線,而且易於存取。現階段,我們使用螢幕存取兩個 FTD,這項工具同樣能讓您在同一個終端機視窗中使用分割畫面。藉此查看不同節點對另一個節點上發布的指令的反應。

理想情況下,畫面上應該有四個可用的視窗:

  1. ot-daemon 服務 / 記錄檔
  2. ot-ctlRCP 合併程式
  3. FTD 專員透過 OpenThread CLI
  4. 透過 OpenThread CLI 存取 FTD 彙整

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

使用螢幕

為方便使用,請改為啟動一個 Screen 工作階段。設定兩個 FTD 時,請確認您已有 PIN 碼。

「螢幕畫面」下方的所有指令都是以 Ctrl + A 鍵開頭。

基本螢幕指令:

透過指令列重新連結至螢幕工作階段

screen -r

離開螢幕工作階段

Ctrl + A 鍵 d

在畫面工作階段中建立新視窗

Ctrl + A 鍵 c

在同一個畫面中切換視窗

Ctrl + A → n (快轉) Ctrl + A (p) (返回)

關閉目前畫面的視窗

Ctrl + A 鍵 k

分割畫面

透過「螢幕」功能,您可以將終端機分成多個視窗:

f1cbf1258cf0a5a.png

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

如果您一直按照程式碼研究室的指示使用同一個視窗,您應該在同一個 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,這些服務必須在相同的 Screen 執行個體內啟動。方法是停止 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. 建立執行緒網路

現在你已完成所有終端機視窗和畫面設定,接下來,讓我們建立討論串資料庫。在 FTD 委員會上建立新的作業資料集,並將其視為有效資料集。「作業資料集」是您要建立的執行緒網路設定。

## 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 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)

現在起,只要掃描其他討論串裝置,「程式碼研究室」網路就會出現。

請在 RCP 合併提供的 ot-ctl 上執行下列操作:

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

> scan
| J | Network Name     | Extended PAN     | PAN  | MAC Address      | Ch | dBm | LQI |
+---+------------------+------------------+------+------------------+----+-----+-----+
| 0 | OpenThread-c0de  | c0de7ab5c0de7ab5 | c0de | 1ed687a9cb9d4b1d | 11 | -36 | 232 |

FTD 聯集上的 OpenThread CLI:

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

> scan
| J | Network Name     | Extended PAN     | PAN  | MAC Address      | Ch | dBm | LQI |
+---+------------------+------------------+------+------------------+----+-----+-----+
| 0 | OpenThread-c0de  | c0de7ab5c0de7ab5 | c0de | 1ed687a9cb9d4b1d | 11 | -38 | 229 |

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

您可能會注意到,在兩次掃描中,該網路似乎無法加入會議 (RCP Joiner 和 FTD Joiner 中的 J 欄)。這意味著這個會話串並未在網路上啟用。不過,你還是可以透過手動加入網路機碼輸入網路金鑰,來移出架構。

8.新增 RCP 合併字元

將 RCP 合併程式新增至我們剛才建立的執行緒網路,使用架構外程序。掃描 RCP 彙整程式中的網路:

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

> scan
| J | Network Name     | Extended PAN     | PAN  | MAC Address      | Ch | dBm | LQI |
+---+------------------+------------------+------+------------------+----+-----+-----+
| 0 | OpenThread-c0de  | c0de7ab5c0de7ab5 | c0de | 1ed687a9cb9d4b1d | 11 | -38 | 229 |

如要加入,請在使用中的資料集中在 RCP Joiner 上設定網路金鑰 (我們剛從 FTD 代理程式取得)。

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

> dataset networkkey 1234c0de7ab51234c0de7ab51234c0de
Done
> dataset commit active
Done

檢查資料集,確認資料集設定正確。

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

> dataset
Network Key: 1234c0de7ab51234c0de7ab51234c0de

顯示執行緒,讓 RCP 彙整程式加入「程式碼研究室」網路。稍等片刻,請檢查狀態、RLOC16 及其 IPv6 位址:

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

> 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 輸出內容取得的網格本機位址) 連線偵測 (ping) 來驗證連線:

## 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

現在,我們有一個由兩個節點組成的 Thread 網路,這個拓撲圖如下:

otcodelab_top01C_2nodes.png

拓撲圖

在您程式碼研究室的其餘部分進行處理時,只要網路狀態改變,系統就會顯示新的討論串拓撲圖。節點角色會以下列方式表示:

b75a527be4563215.png

路由器一律是五角形,「裝置」則是圓形。每個節點的號碼代表 CLI 輸出內容中顯示的 Router ID 或子項 ID,視各節點目前的角色和狀態而定。

9. 委託 FTD 合併

現在,請將第三個討論串式裝置新增到「程式碼研究室」網路。我們之後會採取更安全的工作階段中處理程序。在「FTD 彙整」上掃描網路:

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

> scan
| J | Network Name     | Extended PAN     | PAN  | MAC Address      | Ch | dBm | LQI |
+---+------------------+------------------+------+------------------+----+-----+-----+
| 0 | OpenThread-c0de  | c0de7ab5c0de7ab5 | c0de | f65ae2853ff0c4e4 | 11 | -36 |  57 |

J 欄中的 0 代表裝置上沒有討論串佣金。

具體來說,當您在下一個裝置上進行佣金時,就必須讓 FTD 人員加入。目前仍在 FTD 註冊者上,取得 eui64,因此 FTD 公司可以辨識出這個身分:

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

> eui64
2f57d222545271f1
Done

FTD 委員會上啟動代理程式,並指定可加入的裝置 eui64 和加入參與者憑證 (例如 J01NME)。加入 er 是所有大寫英數字元 (0-9 和 AY,排除 I、O、Q 和 Z,但為了方便閱讀) 的裝置專屬字串,長度介於 6 到 32 個字元之間。

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

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

切換至 FTD 合併器,然後重新掃描:

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

> scan
| J | Network Name     | Extended PAN     | PAN  | MAC Address      | Ch | dBm | LQI |
+---+------------------+------------------+------+------------------+----+-----+-----+
| 1 | OpenThread-c0de  | c0de7ab5c0de7ab5 | c0de | 1ed687a9cb9d4b1d | 11 | -45 | 196 |

如同 J 欄的 1 所示,目前網路討論串式啟用功能現已啟用。使用您在 FTD 委員會中設定的加入者憑證啟動聯盟角色:

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

> ifconfig up
Done
> joiner start J01NME
Done

你會在一分鐘內收到成功驗證的確認:

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

>
Join success

顯示執行緒,讓 FTD 聯集加入「程式碼研究室」網路,並立即檢查狀態和 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)。也就是說,這類路由器可以做為路由器或「裝置」使用,也可以從「裝置」升級為「路由器」。

執行緒最多可以支援 32 個路由器,但會試著將路由器的數量控制在 16 到 23 之間。如果 REED 以終端裝置 (子項) 的身分連接,且路由器數量低於 16,則隨機工作階段時間在 2 分鐘內將會自動提升至路由器。

如果您在 FTD 聯網新增了 2 個網路網路端點,請等待至少兩分鐘,然後再次檢查 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 委員會上關閉 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 網路集中在一起,我們已將 Routes 路由器從 FTD 專員變更為 FTD 聯集人。This RR er 接器 in 行了新的 RLOC16 (因 its 其路由器 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 專員

有兩個節點的執行緒網路並不有趣。現在,我們重新啟用 FTD 總裁。

在「FTD 委員會」上重新啟動 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

我們的討論串網路由三個節點組成,

11. 疑難排解

透過不同終端機或螢幕視窗管理多部裝置的 Thread 網路可能相當複雜。如果遇到問題,請參考這些提示「重設」網路或工作區的狀態。

螢幕

如果在設定過程中遺失了視窗 (太多畫面視窗或畫面中的畫面),請同時按下 Ctrl + A 鍵 (k) 來關閉螢幕screen -ls使用指令列輸出內容No Sockets found的 Google Ads 新帳戶重新申請驗證。然後為每部裝置重新建立視窗。即使裝置受損,系統仍會保留裝置狀態。

執行緒節點

如果這個 Thread 網路拓撲未如本程式碼研究室所描述,或因故導致節點斷線 (可能是 Linux 機器在休眠狀態而關閉),最好關閉 Thread、清除網路憑證,然後從 建立執行緒網路步驟。

如何重設 FTD:

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

> thread stop
Done
> ifconfig down
Done
> factoryreset
Done

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

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

> thread stop
Done
> ifconfig down
Done
> factoryreset
Done

12. 使用多播功能

多播功能可一次將資訊傳送給一組裝置。在討論串網路中,視範圍而定,只有特定群組才能用於多點傳送。

IPv6 位址

範圍

收件者

ff02::1

本地連結

所有 FTD 和 MED

ff02::2

本地連結

所有 FTD 和邊界路由器

ff03::1

網狀本機

所有 FTD 和 MED

ff03::2

網狀本機

所有 FTD 和邊界路由器

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

Link-Local 範圍包含可透過單一無線電傳輸或單一「躍點」存取的所有執行緒介面。 網路拓撲會決定哪些裝置會回應 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 位址時,我們可以看到第一個清單 (結尾是 4b1d),就是 FTD 委員會的 LLA,第二個則是 943b (RCP) 的 LLA。

otcodelab_top02C_02_LL02.png

這代表 FTD 連接器直接與 FTD 論壇和 RCP 合併器直接連線,用於驗證我們的拓撲。

網狀本機

網格本機範圍包含同一 Thread 網路中可連接的所有 Thread 介面。讓我們來看看連線偵測 (ping) 對 ff03::1 多播地址的回應。

透過 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),以及 RR 加入會議的 Mes-Local EID (ML-EID,結尾為 d55f)。這是因為網狀本地範圍涵蓋整個執行緒網路。無論裝置位於何處,系統都會訂閱 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

請注意,RCP 合併程式在這兩種連線偵測 (ping) 輸出中的回應時間。抵達 FTD 連接器 (68 毫秒) 所需的時間,則是抵達 FTD 連接器 (23 毫秒) 所需的時間。這是因為與 FTD 專員合作,必須來回兩跳。

您可能也會注意到,網路本機多點傳送連線偵測 (ping) 只會對 RFC 發出,只有 RF 宣告會對 RF 構成, 這是因為 FTD 是網路中的路由器,而 RCP 是終端裝置。

請檢查 RCP 合併器的狀態:

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

> state
child

13. 使用 UDP 傳送訊息

OpenThread 提供的其中一項應用程式服務是 User Datagram Protocol (UDP),即傳輸層通訊協定。建構在 OpenThread 上的應用程式可以使用 UDP API,在 Thread 網路中的節點之間傳送訊息,或傳送至外部網路中的其他裝置 (例如 Thread 網路)。

UDP 通訊端是透過 OpenThread CLI 公開。可用來傳送兩個 FTD 之間的訊息。

取得 FTD 彙整的 Mesh-Local 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

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

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

> udp open
Done
> udp bind :: 1212

切換至「FTD 委員會」,啟動 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

你現在知道:

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

後續步驟

以本程式碼研究室為基礎,您可以嘗試下列做法:

  • 使用 ot-cli-mtd 二進位檔將 FTD 聯集板重新載入為 MTD,並發現它永遠不會升級為路由器,或試圖成為領導人
  • 將更多裝置 (嘗試其他平台!) 新增到網路,並使用路由器和子資料表來繪製拓撲,以及執行連線偵測 (ping) 至多點傳送地址
  • 使用間諜軟體控制 NCP
  • 使用 OpenThread 邊界路由器,將 NCP 轉換為邊界路由器

延伸閱讀

歡迎前往 openthread.ioGitHub,查看各種 OpenThread 資源,包括:

  • 支援平台:探索支援 OpenThread 的所有平台
  • 建立 OpenThread:進一步瞭解如何建構和設定 OpenThread
  • Thread Primer (執行緒 Primer) — 介紹這個程式碼研究室中的所有執行緒概念

參考資料: