nRF52840 DKで遊ぼう⑤~DFU over Mesh~
はじめに
nRF5 SDK for MeshののDevice Firmware Update (DFU) サンプルを動かしてみます。 このサンプルでは、Mesh経由でfirmwareを更新します。
IoT時代の組込みデバイスでは、firmware更新はできて当然ですからね!
動作確認
実際の手順は次のページにあります。この手順に沿って、firmwareの更新を試します。
Mesh DFUには2つのモードがあります。
- side-by-side DFU
- bootloader DFU
違いは、アプリケーションがDFUの工程に介入するかどうかです。 side-by-sideでは、firmwareを送り終わったら、アプリケーションが新しいfirmwareを書き込みます。
一方、bootloader DFUでは、bootloaderがfirmwareの転送を取り扱います。 こちらの場合では、アプリケーションが機能していない場合でも、firmware更新が可能です。
今回動かすサンプルは、side-by-side DFUです。
このサンプルでは、カスタマイズされたnrfutil
が必要です。カスタマイズされたnrfutilを使って、シリアルからDFUパケットをデバイスに送ります。
DFUパケットを受け取ったデバイスは、DFUパケットをMeshネットワークに転送します。
10手ステップもあって大変ですが、1つずつやっていきます。今回はOptionalな項目もやります。
- Optional: nrfutilで署名鍵を生成する
- Optional: nrfutilから公開鍵をデバイスに追加する
- nrfutilでDFUアーカイブを作成する
- tools/dfuで16進数版のデバイスページを作成する
- 全てのデバイスのメモリを消去する
- SoftDeviceを全てのデバイスのFlashに書き込む
- 全てのデバイスにbootloaderを書き込む
- 全てのデバイスの最初のアプリケーションを書き込む
- 全てのデバイスにデバイスページを書き込む
- nrfutilでDFUアーカイブを転送する
1. Optional: nrfutilで署名鍵を生成する
セキュリティを向上するために、署名検証の機能を使うことができます。 nrfutilを使って、署名鍵を生成できます。まずは、秘密鍵を生成します。
nrfutil keys --gen-key private_key.txt
$ head -n 2 private_key.txt -----BEGIN EC PRIVATE KEY----- MHcCAQEEIO+ejE5y96dSbg9MrRRAdFRgPaiDRVPFcfAyV0h05hgpoAoGCCqGSM49
この署名鍵を紛失すると、DFUの権限を失います。その場合、全てのデバイスを手動でリフレッシュする必要があります。恐ろしい!
2. Optional: nrfutilから公開鍵をデバイスに追加する
秘密鍵から、公開鍵を取得します。
$ nrfutil keys --show-vk hex private_key.txt Verification key Qx: 5078c0e4031642416f0b3c355f2f3cf1aae189a1a76bc086833422afb5be48d8 Verification key Qy: 0efed2ebf936e5d8b9330f035b2862139201da00a137833fb1b59923fd0434bd
DFU可能なMeshデバイスは、デバイスとfirmware情報を含んだデバイスページが必要です。
デバイスページは、tools/dfu
のdevice_page_generator.py
で生成できます。スクリプトに入力する設定は、JSONで書きます。
{ "bootloader_config": { "bootloader_id": 1, "bootloader_version": 1, "company_id": 89, "application_id": 1, "application_version": 1, "public_key": "5078c0e4031642416f0b3c355f2f3cf1aae189a1a76bc086833422afb5be48d80efed2ebf936e5d8b9330f035b2862139201da00a137833fb1b59923fd0434bd" } }
public_keyのフィールドは、nrfutilで取得した公開鍵を繋げたものを記述します。
これで、転送されたfirmwareが秘密鍵で署名されているか、検証することが可能です。
3. nrfutilでDFUアーカイブを作成する
DFUアーカイブはzipファイルです。このzipファイルはアプリケーションバイナリとメタデータを含みます。
アプリケーションバイナリは16進数ファイルです。nRF5 SDK for Meshのbin/blinky
にある16進数ファイルを使います。
nrfutilを使って、DFUアーカイブを作成します。
nrfutil dfu genpkg --application bin/blinky/blinky_nrf52840_xxAA_s140_6.1.0.hex \ --company-id 0x00000059 \ --application-id 1 \ --application-version 2 \ --key-file private_key.txt \ --sd-req 0xAE \ --mesh dfu_test.zip
application-idは、デバイスページで記述したものと一致しなければなりません。application-versionは、以前のイメージより大きいバージョン番号にします。
SoftDeviceのバージョンs140_nrf52_6.1.0
に対応する--sd-req
は0xAEです (nrfutilを参照)。
4. tools/dfuで16進数版のデバイスページを作成する
device_page_generator.py
を使ってデバイスページを作成します。
# tools/dfu $ python device_page_generator.py -d nrf52840_xxAA -sd "s140_6.1.0" Wrote device page for nrf52840_xxAA with the s140_6.1.0 SoftDevice to bin/device_page_nrf52840_xxAA_s140_6.1.0.hex. $ cat bin/device_page_nrf52840_xxAA_s140_6.1.0.hex :02000004000FEB :10F0000004010808110001005078C0E403164241D1 :10F010006F0B3C355F2F3CF1AAE189A1A76BC0863D :10F02000833422AFB5BE48D80EFED2EBF936E5D810 :10F03000B9330F035B2862139201DA00A137833FD3 :10F04000B1B59923FD0434BD030012000060020035 :10F0500000100D000300100000100000006002000E :10F060000300110000800F00006000000500020096 :10F07000AE00010159000000010001000000FFFF87 :0CF0800002000400FFFFFFFFFFFFFF7F06 :00000001FF
このファイルは手順9で使います。
5. 全てのデバイスのメモリを消去する
nrfjprog --eraseall
6. SoftDeviceを全てのデバイスのFlashに書き込む
nrfjprog --program bin/softdevice/s140_nrf52_6.1.0_softdevice.hex --chiperase
7. 全てのデバイスにbootloaderを書き込む
precompiledのbootloaderを書き込みます。
nrfjprog --program bin/bootloader/gccarmemb/mesh_bootloader_serial_gccarmemb_nrf52840_xxAA.hex
8. 全てのデバイスの最初のアプリケーションを書き込む
nrfjprog --program build/examples/dfu/dfu_nrf52840_xxAA_s140_6.1.0.hex
9. 全てのデバイスにデバイスページを書き込む
手順4で作ったデバイスページを書き込みます。
nrfjprog --program tools/dfu/bin/device_page_nrf52840_xxAA_s140_6.1.0.hex nrfjprog --reset
この時点では、LEDが全てOFFになります。
10. nrfutilでDFUアーカイブを転送する
$ nrfutil dfu serial -pkg dfu_test.zip -p /dev/ttyACM0 -b 115200 -fc --mesh Upgrading target on /dev/ttyACM0 with DFU package /home/tomoyuki/work/05.nrf52840/02.SDK/nRF5-SDK-for-Mesh/dfu_test.zip. Flow control is enabled. [####################################] 100% Device programmed.
けっこう時間かかります。1分強くらい待ちました。DFU中は、LED1とLED3が点灯します。
DFUが完了すると、LED2が点滅します。