hiro99ma blog

何か技術的なこと

ncs: USBでのDFU (4)

2024/12/05

引き続き DFU についての調査を行う。
MCUboot で DFUモード(Bootloader モードや Serial Recovery モードなどいろいろ呼び名がありそうだがこのページではこの用語にしておく)になることはできたが、DFU 自体に成功していない件の調査を進めている。

今頃気付いたけど、DFU over UART からやり始めているからタイトルとちょっと合わないな。
まあ、終わったら USB CDC-ACM 経由でやるから見逃しておくれ。

DevAcademy

USB CDC-ACM での DFU は Exercise 2 で行われていてそちらだけ試していたのだが、うまくいかないので Exercise 1 をちゃんとやることにした。

ひとことで DFU over UART といっても 2つあり、両方とも有効にすることもできる。
ステップを実行すると両方とも有効にしたアプリになる。

uart0 は PC と接続すると VCOM ポートとして見えるそうだ。
これは DKシリーズの OnBoard タイプ J-Link だからだろうか?
私は外付けの J-Link Plus を所有しているのだが、これはこれで USB シリアルのポートとして見えている。

image

J-Link の UART は使ったことが無い。

nRF から使えるのかと思ったが、1.27mm のコネクタだとそういうピンがなかった。
残念だが普通に nRF の UART を使う。

image

mcumgr-cli

DFU over UART のために mcumgr-cli というコマンドラインツールをダウンロードする。
go install で行うので $GOPATH/bin にダウンロードされる。$GOPATH が未設定なら $HOME/go になるので $HOME/go/bin/ にダウンロードされるだろう。
最近の golang は、ソースコードについては GOPATH に依存しなくても良いようになってきたが bin/pkg/ には使われている。
npmvenv みたいに各アプリごとに GOPATH を分けて運用した方がよいかと思って分けていたが、まあ場合によりけりですな。
go install すると上書きになるので、特定のバージョンの実行ファイルが使いたい場合に困ったりするので。

そういう事情はさておき mcumgr-cli をインストールして使えるようにしておく。
go install するリポジトリが “apache/mynewt-mcumgr-cli” になっていて、これは Nordic のアプリではない。
Apache Mynewt という組み込み OS のプロジェクトだそうだ。
MCUboot 自体が Apache Mynewt を Zephyr プロジェクトが fork したと書いてあった

本家はいろいろ書いてあるので概要の把握なら wikipedia の方が向いているか。
使う mcumgr-cli 自体はリモートデバイスで動いている mcumgr server と通信するクライアントアプリらしい。
Nordic のページには SMP Protocol がどうのこうの書いてあるし、サーバ側には Zepher での設定 もあり、MCUbootのZephyrページ にも MCUmgr という言葉が出てくるので、nRF 側でサーバが動くのだろう。

MCUboot で MCUmgr が出てくるところに CONFIG_BOOT_SERIAL_WAIT_FOR_DFU=y にするとこのモード(MCUmgrのコマンドを受け取るモード?)が使えると書いてある。
DevAcademy の Lesson では出てこなかったが、いらないのだろうか?
Nordic AI に聞くと、ハードウェアボタン無しで DFUモードに入る場合に特に有効とのことだ。
DFU モードに入るときだけならボタンがあればいらないのか。

MCUboot のページ に書いてあって関係しそうな設定はこの辺か。
後半は関係なさそう。

あとは Exercise 1 をやりながら見ていこう。

DFU over UART from MCUboot

DK のデバッガは Mass Storage が有効になっているそうだ。Mbed みたいなやつかな?
邪魔になるかもしれないので JLinkExe などで無効化するそうだ。
使っている開発ボード は DK ではないし Mass Storage にもなっていないが、一応やっておこう。
MSDDisable は “Mass Storage Device Disable” の略か。

$ JLinkExe -device NRF5340_XXAA -if SWD -speed 4000 -autoconnect 1 -SelectEmuBySN <シリアル番号>
SEGGER J-Link Commander V7.94i (Compiled Feb  7 2024 17:10:11)
DLL version V7.94i, compiled Feb  7 2024 17:09:47

Connecting to J-Link via USB...O.K.
...
Connecting to target via SWD
...
Memory zones:
  Zone: "Default" Description: Default access mode
Cortex-M33 identified.

J-Link>MSDDisable
Probe configured successfully.
J-Link>exit
$

Step 3 までやったが、やはりつながらない。。。

$ mcumgr conn add ssci type="serial" connstring="dev=/dev/ttyUSB0,baud=115200,mtu=512"
Connection profile ssci successfully added
$ mcumgr -c ssci image list
Error: NMP timeout

他に何かなかったか考えていて、そういえば先月に UART 周りについて何かしていたことを思い出した。

そうだ、nRF の UART RX に HI 入力があると勝手に電源が入ってしまって困るので、ログ出力専用なら取り外してしまえ、と配線ごと抜いたんだった・・・。
つなぎ直してコマンドを実行するとあっさり動いた。
なんということか。。。

$ mcumgr -c ssci image list
Images:
 image=0 slot=0
    version: 0.0.0
    bootable: false
    flags:
    hash: Unavailable
Split status: N/A (0)

では DFU しようとしたのだが app_update.bin というファイルがない。
署名チェックをするようだから zephyr.signed.bin だろうか?

$ find ./build -name "*.bin"
./build/l8_e1/zephyr/zephyr.bin
./build/l8_e1/zephyr/zephyr.signed.bin
./build/mcuboot/zephyr/zephyr.bin

LED の点滅速度を変更してビルドだけ実施し zephyr.signed.bin をアップロード!

$ mcumgr -c ssci image upload build/l8_e1/zephyr/zephyr.signed.bin
 22.99 KiB / 22.99 KiB [=================================] 100.00% 2.98 KiB/s 7s
Done

アップロード成功。
自動で再起動はされなかったが、手動で再起動させると LED 点滅周期が変わっている。
成功だ!

おわりに

結局のところ、DFU over UART がうまくいってなかったのは配線の問題だけだった。
しかし USB 経由の場合は配線とは関係が無いので、やはりまだ問題が残っているのか。

CDC-ACM でのアップロードは次回にする。

おまけ

DevAcademy Intermediate のリポジトリを見たら 20時間前に Lesson 8 が削除されてるーーー。

他にもいろいろ削除されているが、これはきっと更新中だからに違いない。。。
私は信じてるぞ!

< Top page