hiro99ma blog

何か技術的なこと

ncs: USBでのDFU (7)

2024/12/07

引き続き DFU についての調査を行う。

DFU したいのかどうか

DFU したいのかどうかを整理しておこう。

BLE 機器を作って、それと対になるスマホアプリを作るなら、DFU も BLE での FOTA しか使わないだろう。
USB での更新をするなら何か PC 向けのアプリを作らないといけない。 mcumgr-cli や Programmer アプリを使ってもらうのもありだろうが、そういうのは開発者だけだろう。 それなら FOTA でやってスマホアプリ(Android と iOS)を作る方が楽である。

そういうわけで DFU over UART は開発中以外に需要がないように思う。
DFU over USB はありかもしれないが、これも開発者向けだろう。 Mbed みたいに USB につなぐだけで使えるならありだろうが、別途ツールがいるとなるとちょっと悩む。
J-Link も安いものじゃないので、持っていない人向けによいかもしれない。
購入するなら J-Link よりも nRF5340DK みたいな J-Link OB が載った開発ボードの方が安上がりになりそうだ。
(J-Link はハードウェアバージョンによって対応できる CPU が違うのでよく確認しよう!)

載せるなら FOTA over BLE だけでよいかな。 USB の方が FOTA よりも通信が安定していそうなところがメリットかな?

用語の整理

適当に用語を使っていたので、Nordic で使っている用語を調べ直した。
用語というか DevAcademy で使われている言葉だ。
“from MCUboot” は載ってないのだが “from the application”

the application は app、Bluetooth Low Energy は BLE と略していく。

DFU over USB from the app

いきなり FOTA over BLE は大変そうなので、アプリ機能でイメージをダウンロードして MCUboot でアップデートする DFU over USB from app を実装する。
DevAcademy Intermediate Lesson 8 Exercise 1 の Step 5 が参考になる。

DFUモードにならずに mcumgr-cli が使えるようになる。
なるのだが、起動に時間がかかるのか初回の mcumgr -c XXX image list ではタイムアウトしてしまう。 以降は成功するようになる。
コマンドを実行して、すぐ Ctrl+C で止めてコマンドを実行しても動作するので、時間がかかるというよりは 1回目のコマンドを受け付けたら起き上がるみたいな感じか。

J-Link で Flashing した後に mcumgr image list を確認すると Images が 1つだけ出てくる。
これは DFU over USB from MCUboot と同じだ。

$ mcumgr -c ssciacm image list
Images:
 image=0 slot=0
    version: 0.0.0
    bootable: true
    flags: active confirmed
    hash: 51313bcb36a2d3bba7c8ae8830e978f3976915ad979afb52e27d2ad93dcbfdd8
Split status: N/A (0)

mcumgr image upload した後は slot=1 が増えている。
勝手にリスタートなどはしていないと思うし、リスタートさせても自動でイメージが更新されない。

$ mcumgr -c ssciacm image list
Images:
 image=0 slot=0
    version: 0.0.0
    bootable: true
    flags: active confirmed
    hash: 51313bcb36a2d3bba7c8ae8830e978f3976915ad979afb52e27d2ad93dcbfdd8
 image=0 slot=1
    version: 0.0.0
    bootable: true
    flags:
    hash: 12f3717c56660de5e287cdabca80419735a89ba84d74bb625a8d3356f8e685b7
Split status: N/A (0)

Exercise 1 Step 5.4 の通りにやると更新された。
mcumgr image test は確認だけかと思ったが flags が “pending” になったので意味があるようだ。
(Verifying and testing the image)

$ mcumgr -c ssciacm image test 12f3717c56660de5e287cdabca80419735a89ba84d74bb625a8d3356f8e685b7
Images:
 image=0 slot=0
    version: 0.0.0
    bootable: true
    flags: active confirmed
    hash: 51313bcb36a2d3bba7c8ae8830e978f3976915ad979afb52e27d2ad93dcbfdd8
 image=0 slot=1
    version: 0.0.0
    bootable: true
    flags: pending
    hash: 12f3717c56660de5e287cdabca80419735a89ba84d74bb625a8d3356f8e685b7
Split status: N/A (0)
$ mcumgr -c ssciacm reset
Done

更新された後で mcumgr image list を見るとハッシュ値が入れ替わっていることが分かる。

$ mcumgr -c ssciacm image list
Images:
 image=0 slot=0
    version: 0.0.0
    bootable: true
    flags: active
    hash: 12f3717c56660de5e287cdabca80419735a89ba84d74bb625a8d3356f8e685b7
 image=0 slot=1
    version: 0.0.0
    bootable: true
    flags: confirmed
    hash: 51313bcb36a2d3bba7c8ae8830e978f3976915ad979afb52e27d2ad93dcbfdd8
Split status: N/A (0)

ちゃんと置き換わった。

DFU over UART/USB from MCUbootの削除

アプリから DFU できるなら MCUboot はいるにしても Serial Recovery 機能はいらないのではなかろうか?
いや、そこは製品をどうするかになるから一概には言えないだろう。
削除できるのかどうかは確認したい。

削除しても DFU over USB from app は機能した。

おわりに

DFU over USB from app が動かせた。
次はようやく FOTA over BLE か。

おまけ

MCUboot で USB CDC-ACM を有効にして WSL2 の USBIPD でアタッチすると ttyUSB0 だったのだが アプリで CDC-ACM を有効にしてアタッチすると ttyACM1 だった(ttyACM0 は J-Link が使っているので)。
同じドライバを使っていそうだけど違うのかな?

< Top page