nRF52840 ボードと OpenThread で Thread ネットワークを構築

この Codelab について
schedule88 分
subject最終更新: 2025年4月24日
account_circle作成者: Jeff Bumgardner

1. はじめに

26b7f4f6b3ea0700.png

Google がリリースした OpenThread は、Thread® ネットワーク プロトコルのオープンソース実装です。Google Nest は、Google Nest 製品で使用されている技術をデベロッパーが広く利用できるようにし、コネクテッド ホーム向け製品の開発を加速するために、OpenThread をリリースしました。

Thread 仕様では、家庭用アプリケーション向けの IPv6 ベースの信頼性の高い、安全で低電力のワイヤレス デバイス間通信プロトコルが定義されています。OpenThread は、IPv6、6LoWPAN、MAC セキュリティを備えた IEEE 802.15.4、メッシュリンクの確立、メッシュ ルーティングなど、すべての Thread ネットワーキング レイヤを実装しています。

この Codelab では、実際のハードウェアで OpenThread をプログラムし、Thread ネットワークを作成して管理し、ノード間でメッセージを渡します。

4806d16a8c137c6d.jpeg

学習内容

  • OpenThread CLI バイナリをビルドしてデベロッパー ボードに書き込む
  • Linux マシンとデバイス ボードで構成される RCP の構築
  • OpenThread デーモンと ot-ctl を使用して RCP と通信する
  • GNU Screen と OpenThread CLI を使用して Thread ノードを手動で管理する
  • Thread ネットワークへのデバイスの安全な設定
  • IPv6 マルチキャストの仕組み
  • UDP を使用して Thread ノード間でメッセージを渡す

必要なもの

ハードウェア:

  • 3 個の Nordic Semiconductor nRF52840 開発ボード
  • ボードを接続するための 3 本の USB - マイクロ USB ケーブル
  • USB ポートが 3 つ以上ある Linux マシン

ソフトウェア:

  • GNU ツールチェーン
  • Nordic nRF5x コマンドライン ツール
  • Segger J-Link ソフトウェア
  • OpenThread
  • Git

2. 開始するには

OpenThread シミュレーション

始める前に、OpenThread シミュレーション Codelab を実施して、Thread の基本コンセプトと OpenThread CLI を理解しておくことをおすすめします。

シリアルポート ターミナル

ターミナルを通じてシリアルポートに接続する方法に精通している必要があります。この Codelab では GNU Screen を使用して説明しますが、その他のターミナル ソフトウェアも使用できます。

Linux マシン

この Codelab は、i386 ベースまたは x86 ベースの Linux マシンを使用して無線コプロセッサ(RCP)Thread デバイスのホストとして機能し、すべての Thread 開発ボードをフラッシュすることを前提として設計されています。すべての手順は Ubuntu 14.04.5 LTS(Trusty Tahr)でテストしました。

Nordic Semiconductor nRF52840 ボード

この Codelab では、3 つの nRF52840 PDK ボードを使用します。

a6693da3ce213856.png

オンボードの JTAG モジュールを備えた nRF52840 ボードをプログラムするには、SEGGER J-Link を使用します。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 ファイルの手順に沿って操作します。

取り付け画面(省略可)

Screen は、シリアルポートで接続されたデバイスにアクセスするためのシンプルなツールです。この Codelab では Screen を使用しますが、任意のシリアルポート ターミナル アプリケーションを使用できます。

$ 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 デーモンをビルドします。

$ script/cmake-build posix -DOT_DAEMON=ON

これで、OpenThread をビルドして nRF52840 ボードにフラッシュする準備が整いました。

4. RCP ジョイナーを設定する

ビルドしてフラッシュする

Joiner とネイティブ USB 機能を備えた OpenThread nRF52840 の例をビルドします。デバイスは、参加者のロールを使用して、Thread ネットワークで安全に認証され、構成されます。ネイティブ USB を使用すると、nRF52840 とホスト間のシリアル トランスポートとして USB CDC ACM を使用できます。

必ず、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 バイナリがあるディレクトリに移動し、バイナリを 16 進数形式に変換します。

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

USB ケーブルを nRF52840 ボードの外部電源ピンの横にあるマイクロ USB デバッグポートに接続し、Linux マシンに差し込みます。nRF52840 ボードの nRF 電源スイッチを VDD に設定します。正しく接続されている場合、LED5 が点灯します。

20a3b4b480356447.png

Linux マシンに接続する最初のボードの場合は、シリアルポート /dev/ttyACM0 として表示されます(すべての nRF52840 ボードは、シリアルポート ID に ttyACM を使用します)。

$ ls /dev/ttyACM*
/dev/ttyACM0

RCP に使用されている nRF52840 ボードのシリアル番号をメモします。

c00d519ebec7e5f0.jpeg

nRFx コマンドライン ツールの場所に移動し、ボードのシリアル番号を使用して、OpenThread RCP ヘックス ファイルを nRF52840 ボードにフラッシュします。--verify フラグを省略すると、エラーが発生しなくてもフラッシュ プロセスが失敗する可能性があることを示す警告メッセージが表示されます。

$ 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.

後でボードのロールと混同しないように、ボードに「RCP」というラベルを付けます。

ネイティブ USB に接続する

OpenThread RCP ビルドでは、シリアル トランスポートとしてネイティブ USB CDC ACM を使用できるため、RCP ホスト(Linux マシン)と通信するには、nRF52840 ボードの nRF USB ポートを使用する必要があります。

書き込みが完了した nRF52840 ボードのデバッグポートから USB ケーブルのマイクロ USB 端子を取り外し、RESET ボタンの横にあるマイクロ USB nRF USB ポートに再び接続します。[nRF 電源] スイッチを [USB] に設定します。

46e7b670d2464842.png

OpenThread デーモンを起動する

RCP 設計では、OpenThread デーモンを使用して Thread デバイスと通信し、管理します。-v 詳細フラグを指定して ot-daemon を開始し、ログ出力を確認して実行されていることを確認します。

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

正常に完了すると、詳細モードの 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 を使用します。したがって、ot-daemon ノードを他のシミュレートされた Thread デバイスと同じ方法で制御できます。

2 番目のターミナル ウィンドウで、ot-ctl を起動します。

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

ot-daemon で起動したノード 2(RCP ノード)の state を確認します。

> state
disabled
Done

5. FTD を設定する

この Codelab で使用する他の 2 つの Thread ノードは、標準のシステム オン チップ(SoC)設計のフル Thread デバイス(FTD)です。本番環境では、本番環境向けのネットワーク インターフェース ドライバである wpantund を使用して OpenThread NCP インスタンスを制御できますが、この Codelab では OpenThread CLI である ot-ctl を使用します。

1 つのデバイスがコミッショナーとして機能し、そのネットワークにデバイスを安全に認証してコミッショニングします。もう一方のデバイスは、管理者が Thread ネットワークに対して認証できる参加者として機能します。

ビルドしてフラッシュする

コミッショナーと参加者のロールを有効にして、nRF52840 プラットフォーム用の OpenThread FTD の例をビルドします。

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

OpenThread Full Thread Device(FTD)CLI バイナリがあるディレクトリに移動し、バイナリを 16 進数形式に変換します。

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

USB ケーブルを nRF52840 ボードの外部電源ピンの横にあるマイクロ USB ポートに接続し、Linux マシンに差し込みます。RCP がまだ Linux マシンに接続されている場合、この新しいボードはシリアルポート /dev/ttyACM1 として表示されます(すべての nRF52840 ボードは、シリアルポート ID に ttyACM を使用します)。

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

前回と同様に、FTD に使用している nRF52840 ボードのシリアル番号をメモします。

c00d519ebec7e5f0.jpeg

nRFx コマンドライン ツールの場所に移動し、ボードのシリアル番号を使用して、OpenThread CLI FTD ヘックスファイルを nRF52840 ボードにフラッシュします。

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

ボードに「Commissioner」というラベルを付けます。

ネイティブ USB に接続する

OpenThread FTD ビルドでは、シリアル トランスポートとしてネイティブ USB CDC ACM を使用できるため、RCP ホスト(Linux マシン)と通信するには、nRF52840 ボードの nRF USB ポートを使用する必要があります。

書き込みが完了した nRF52840 ボードのデバッグポートから USB ケーブルのマイクロ USB 端子を取り外し、RESET ボタンの横にあるマイクロ USB nRF USB ポートに再び接続します。[nRF 電源] スイッチを [USB] に設定します。

46e7b670d2464842.png

ビルドを確認する

ターミナル ウィンドウから GNU Screen を使用して OpenThread CLI にアクセスし、ビルドが正常に完了したことを確認します。

$ screen /dev/ttyACM1

新しいウィンドウでキーボードの Return キーを数回押して、OpenThread CLI > プロンプトを表示します。IPv6 インターフェースを起動して、アドレスを確認します。

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

Ctrl+A を使用する →

d FTD コミッショナー CLI から切断し、Linux ターミナルに戻って次のボードをフラッシュできるようにします。CLI をいつでも再入力するには、コマンドラインから 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 ビルドを使用して 3 つ目の nRF52840 ボードをフラッシュします。完了したら、nRF USB ポートを使用してボードを PC に再接続し、nRF 電源スイッチを VDD に設定します。

この 3 つ目のボードが接続されたときに、他の 2 つのノードが Linux マシンに接続されている場合、シリアルポート /dev/ttyACM2 として表示されます。

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

ボードに「Joiner」というラベルを付けます。

Screen を使用して確認する場合は、コマンドラインから Screen の新しいインスタンスを作成するのではなく、既存のインスタンスに再接続し、その中に新しいウィンドウ(FTD コミッショナーに使用したもの)を作成します。

$ screen -r

Ctrl+a → c キーを押して、Screen 内に新しいウィンドウを作成します。

新しいコマンドライン プロンプトが表示されます。FTD ジョイナーの OpenThread CLI にアクセスします。

$ screen /dev/ttyACM2

この新しいウィンドウで、キーボードの Return キーを数回押して、OpenThread CLI > プロンプトを表示します。IPv6 インターフェースを起動して、アドレスを確認します。

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

FTD 参加者 CLI が FTD コミッショナーと同じ Screen インスタンスにあるため、Ctrl+a → n を使用して切り替えることができます。

Ctrl+A を使用する →

d いつでもスクリーンを終了できます。

6. ターミナル ウィンドウの設定

今後、Thread デバイスを頻繁に切り替えることになりますので、すべてのデバイスが動作していて、簡単にアクセスできるようにしてください。これまでは、2 つの FTD にアクセスするために Screen を使用してきましたが、このツールを使用すると、同じターミナル ウィンドウで分割画面を使用することもできます。これを使用して、あるノードが別のノードで発行されたコマンドにどのように反応するかを確認します。

理想的には、次の 4 つのウィンドウをすぐに利用できるようにしておく必要があります。

  1. ot-daemon サービス / ログ
  2. ot-ctl を介した RCP ジョイナー
  3. OpenThread CLI を使用した FTD コミッショナー
  4. OpenThread CLI を介した FTD ジョイナー

独自のターミナル / シリアルポートの構成またはツールを使用する場合は、次のステップに進んでください。すべてのデバイスのターミナル ウィンドウを、自分に合った方法で構成します。

画面の使用

使いやすくするため、Screen セッションは 1 つだけ開始してください。両方の FTD を設定したときに作成したはずです。

Screen 内のすべてのコマンドは Ctrl+a で始まります。

基本的な画面コマンド:

Screen セッションに再接続する(コマンドラインから)

screen -r

Screen セッションを終了する

Ctrl+A → d

画面セッション内に新しいウィンドウを作成する

Ctrl+A → c

同じ画面セッション内のウィンドウを切り替える

Ctrl+a → n(次へ)Ctrl+a → p(戻る)

Screen セッションで現在のウィンドウを強制終了する

Ctrl+A → k

分割スクリーン

Screen を使用すると、ターミナルを複数のウィンドウに分割できます。

f1cbf1258cf0a5a.png

screen のコマンドには、Ctrl+a を使用してアクセスします。すべてのコマンドは、このアクセスキーの組み合わせで始める必要があります。

Codelab の手順に正確に沿って操作していれば、同じ Screen インスタンスに 2 つのウィンドウ(FTD 委員、FTD 参加者)が表示されているはずです。2 つの画面に分割するには、まず既存の Screen セッションに入ります。

$ screen -r

FTD デバイスのいずれかを使用している必要があります。Screen で次の手順を行います。

  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 を終了し、新しい Screen ウィンドウ内で再起動します(Ctrl+a → c)。

この設定は必須ではなく、ユーザーの演習として残されています。

次のコマンドを使用してウィンドウを分割し、ウィンドウ間を移動します。

新しいウィンドウを作成する

Ctrl+A → c

ウィンドウを縦に分割する

Ctrl+A →

ウィンドウを横に分割する

Ctrl+A → S

次に表示されるウィンドウに移動する

Ctrl+A → Tab

表示されているウィンドウを前後に切り替える

Ctrl+a → n または p

現在のウィンドウの名前を変更する

Ctrl+A → A

Ctrl+a → d を押すといつでも Screen を終了できます。コマンドラインから screen -r を押すと、再び接続できます。

Screen の詳細については、GNU Screen のクイック リファレンスをご覧ください。

7. Thread ネットワークを作成する

すべてのターミナル ウィンドウと画面が構成されたので、Thread ネットワークを作成しましょう。FTD コミッショナーで、新しいオペレーション データセットを作成し、アクティブなデータセットとして commit します。運用データセットは、作成する 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 をメモしておきます。

このデータセットをアクティブとして commit します。

> 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 デバイスからスキャンしたときに、「codelab」ネットワークが表示されるようになりました。

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 |

リストに「codelab」ネットワークが表示されない場合は、もう一度スキャンしてみてください。

8. RCP ジョイナーを追加

ネットワークで Thread コミッショニングがアクティブになっていません。つまり、アウトオブバンド コミッショニング プロセスを使用して、作成した Thread ネットワークに RCP ジョイナーを追加する必要があります。

FTD コミッショナーに、ネットワーク キー(1234c0de7ab51234c0de7ab51234c0de など)をメモしました。ネットワーク キーを再度検索する必要がある場合は、FTD コミッショナーで次のコマンドを実行します。

## FTD Commissioner ##

> dataset networkkey
1234c0de7ab51234c0de7ab51234c0de
Done

次に、RCP ジョイナーで、アクティブなデータセットのネットワーク キーを FTD コミッショナー ネットワーク キーに設定します。

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

> dataset networkkey 1234c0de7ab51234c0de7ab51234c0de
Done
> dataset commit active
Done

データセットが正しく設定されていることを確認します。

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

> dataset
Network Key: 1234c0de7ab51234c0de7ab51234c0de

スレッドを起動して、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 出力から取得したメッシュローカル アドレス)に 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

これで、2 つのノードからなる Thread ネットワークが作成されました。トポロジ図は次のとおりです。

otcodelab_top01C_2nodes.png

トポロジ図

Codelab の残りの部分では、ネットワークの状態が変化するたびに、新しい Thread トポロジ図が表示されます。ノードのロールは次のように表されます。

b75a527be4563215.png

ルータは常に五角形で、エンドデバイスは常に円です。各ノードに表示されている番号は、各ノードの現在のロールとその時点での状態に応じて、CLI の出力に表示されるルーター ID または子 ID を表します。

9. FTD の参加者を委任する

次に、3 つ目の Thread デバイスを「codelab」ネットワークに追加します。今回は、より安全なインバンド コミッショニング プロセスを使用し、FTD 参加者のみを参加させます。

FTD 参加者eui64 を取得して、FTD コミッショナーが識別できるようにします。

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

> eui64
2f57d222545271f1
Done

FTD コミッショナーでコミッショナーを起動し、参加できるデバイスの eui64 と参加者の認証情報(J01NME など)を指定します。参加者の認証情報は、デバイス固有の文字列で、すべて大文字の英数字(0 ~ 9、A ~ Y、読みやすさのため I、O、Q、Z は除く)で構成され、長さは 6 ~ 32 文字です。

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

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

FTD Joiner に切り替えます。FTD コミッショナーで設定した参加者認証情報を使用して、参加者ロールを開始します。

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

> ifconfig up
Done
> joiner start J01NME
Done

1 分ほどで、認証が成功したことを確認するメッセージが表示されます。

## 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 コミッショナーに切り替え、ルーターと子テーブルを確認して、「codelab」ネットワークに 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 |

> 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. スレッドの動作

この Codelab の Thread デバイスは、ルーター対応エンドデバイス(REED)と呼ばれる特定の種類のフル Thread デバイス(FTD)です。つまり、ルーターまたはエンドデバイスとして機能し、エンドデバイスからルーターへと昇格できます。

Thread は最大 32 台のルーターをサポートできますが、ルーターの数は 16 ~ 23 台に保たれます。REED がエンドデバイス(子)として接続し、ルーターの数が 16 未満の場合、2 分以内のランダムな時間後に、REED は自動的にルーターに昇格します。

FTD 参加者を追加した後、Thread ネットワークに 2 つの子デバイスがある場合は、少なくとも 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 ジョイナー(拡張 MAC = e6cdd2d93249a243)がルーターに昇格しました。RLOC16 は異なります(0c02 ではなく b800)。これは、RLOC16 がデバイスのルーター ID と子 ID に基づいているためです。エンドデバイスからルーターに変換されると、ルーター ID と子 ID の値が変更され、RLOC16 も変更されます。

otcodelab_top01C.png

FTD ジョイナーで新しい状態と RLOC16 を確認します。

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

> state
router
Done
> rloc16
b800
Done

FTD ジョイナーをダウングレードする

この動作をテストするには、FTD ジョイナーをルータからエンドデバイスに手動でダウングレードします。状態を child に変更し、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 の Router に切り替わります。

otcodelab_top01C.png

リーダーを削除する

リーダーは、すべてのスレッド ルータの中から自己選択されます。つまり、現在のリーダーが Thread ネットワークから削除されると、他のルーターのいずれかが新しいリーダーになります。

FTD コミッショナーで 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 があることに注意してください。これは、ID と拡張 MAC で示されているように、RCP 参加者です。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 コミッショナーを再接続する

2 つのノードがある Thread ネットワークは、あまり面白くありません。FTD コミッショナーをオンラインに戻しましょう。

FTD コミッショナーで Thread を再起動します。

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

> ifconfig up
Done
> thread start
Done

2 分以内に、エンドデバイスとして「codelab」ネットワークに自動的に再接続し、ルーターに昇格します。

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

> state
router
Done

FTD Joiner でルーター テーブルと子テーブルを確認して、次の点を確認します。

## 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 ネットワークは、再び 3 つのノードで構成されています。

11. トラブルシューティング

異なる端末または Screen ウィンドウで複数のデバイスを使用する Thread ネットワークの管理は複雑になる可能性があります。問題が発生した場合は、以下のヒントを参考にしてネットワークまたはワークスペースの状態を「リセット」してください。

画面

構成が複雑になりすぎた(Screen ウィンドウが多すぎる、Screen 内に Screen がある)場合は、Ctrl+a → k を押して Screen ウィンドウをすべて終了し、コマンドライン上の screen -lsNo Sockets found を出力するまで続けます。次に、デバイスごとに Screen ウィンドウを再作成します。画面が強制終了されても、デバイスの状態は保持されます。

スレッドノード

Thread ネットワーク トポロジがこの Codelab の説明と異なる場合や、なんらかの理由でノードが切断された場合(電源を供給している 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

Mesh-Local

すべての FTD と MED

ff03::2

Mesh-Local

すべての FTD とボーダー ルーター

この Codelab では境界ルーターを使用していないため、2 つの FTD と MED のマルチキャスト アドレスに注目します。

リンクローカル スコープは、1 回の無線送信(1 つの「ホップ」)で到達可能なすべての Thread インターフェースで構成されます。ネットワーク トポロジによって、ff02::1 マルチキャスト アドレスへの ping に応答するデバイスが決まります。

FTD コミッショナーから ff02::1 に ping します。

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

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

ネットワークには他にも 2 台のデバイス(FTD 参加者と RCP 参加者)がありますが、FTD コミッショナーは FTD 参加者のリンクローカル アドレス(LLA)からのみ 1 件の応答を受け取っています。つまり、FTD コミッショナーがシングルホップで到達できるデバイスは FTD 参加者のみです。

otcodelab_top02C_02_LL.png

次に、FTD Joiner から ff02::1 に ping を送信します。

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

2 つの回答があります。他のデバイスの IPv6 アドレスを確認すると、最初のアドレス(4b1d で終わる)は FTD コミッショナーの LLA で、2 番目のアドレス(943b で終わる)は RCP 参加者の LLA であることがわかります。

otcodelab_top02C_02_LL02.png

つまり、FTD ジョイナーが FTD コミッショナーと RCP ジョイナーの両方に直接接続されているため、トポロジが正しいことが確認できます。

Mesh-Local

メッシュローカル スコープには、同じ Thread ネットワーク内で到達可能なすべての Thread インターフェースが含まれます。ff03::1 マルチキャスト アドレスへの ping に対するレスポンスを確認しましょう。

FTD コミッショナーから ff03::1 に ping します。

## 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 コミッショナーは 2 つのレスポンスを受信します。1 つは FTD 参加者のルーティング ロケータ(RLOC、b800 で終わる)から、もう 1 つは RCP 参加者のメッシュローカル EID(ML-EID、d55f で終わる)からです。これは、メッシュローカル スコープが Thread ネットワーク全体を構成するためです。デバイスがネットワークのどこにあっても、ff03::1 アドレスにサブスクライブされます。

otcodelab_top02C_02_ML.png

FTD ジョイナーから ff03::1 に ping を実行して、同じ動作を確認します。

## 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 ジョイナーの応答時間をメモします。RCP 結合ツールが FTD コミッショナーに到達するまでに要した時間(68 ミリ秒)は、FTD 結合ツールが FTD コミッショナーに到達するまでに要した時間(23 ミリ秒)よりもはるかに長くなっています。これは、FTD 参加者は 1 つのホップで FTD コミッショナーに到達するのに対し、FTD コミッショナーに到達するには 2 つのホップを経由する必要があるためです。

また、メッシュローカル マルチキャスト ping が、RCP ジョイナーではなく、2 つの FTD の RLOC のみで応答したことに気づいたかもしれません。これは、FTD はネットワーク内のルーターであるのに対し、RCP はエンドデバイスであるためです。

RCP ジョイナーの状態を確認して、次のことを確認します。

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

> state
child

13. UDP でメッセージを送信する

OpenThread が提供するアプリケーション サービスの 1 つは、トランスポート レイヤ プロトコルである User Datagram Protocol(UDP)です。OpenThread で構築されたアプリケーションは、UDP API を使用して、Thread ネットワーク内のノード間、または外部ネットワーク(Thread ネットワークに境界ルータがある場合はインターネットなど)内の他のデバイスにメッセージを渡すことができます。

UDP ソケットは OpenThread CLI を介して公開されます。これを使用して、2 つの 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 を起動し、FTD ジョイナーで設定したソケットに ML-EID を使用して接続します。

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

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

2 つのノード間で UDP 接続が確立されている必要があります。FTD 委員からメッセージを送信します。

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

> udp send hellothere
Done

FTD Joiner で UDP メッセージが受信されました。

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

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

14. 完了

物理的な Thread ネットワークが作成されました。

b915c433e7027cc7.png

ここまでで、次のことを学びました。

  • Thread デバイスのタイプ、ロール、スコープの違い
  • Thread デバイスがネットワーク内で状態を管理する方法
  • UDP を使用してノード間で単純なメッセージを渡す方法

次のステップ

この Codelab で学んだことを活かして、以下の演習に挑戦してみましょう。

  • ot-cli-mtd バイナリを使用して FTD ジョイナー ボードを MTD として再フラッシュし、ルーターにアップグレードしたり、リーダーになろうとしたりしないことを確認します。
  • ネットワークにデバイスを追加し(別のプラットフォームを試してください)、ルーター テーブルと子テーブルを使用して、マルチキャスト アドレスへの ping とともにトポロジの概要を把握します。
  • pyspinel を使用して NCP を制御する
  • OpenThread Border Router を使用して NCP をボーダー ルーターに変更し、Thread ネットワークをインターネットに接続する

関連情報

openthread.ioGitHub で、次のようなさまざまな OpenThread リソースを確認してください。

関連資料: