STM32F411CE (3)

Date: 2022/03/06 (initial publish), 2022/09/10 (last update)

Source: jp/note-00046.md

Previous Post Top Next Post

TOC

dfu-utilは、最近、Debianででも最新の 0.11-1 が使えるようになりました。dfu-suffix等もちゃんとmanpageが付いてます。

プログラムの導入はDFUでできるめどが立ったのですが、DFUベースで動くシステムもう少しで遊んでみます。(STLINKは興味はあるけど後回しにします。)

DFUのこつ

「DFUに入りにくい」などと言うことをNETで散見します。(チップを温めるなどという「おまじない」も日本語のどこかで見ました。)

確かに、無頓着にBOOT0とNRSTのPUSHスイッチを同時押し・同時離しでDFUに入ろうとすると上手くいかないことがありました。

でも、以下の手順をとれば、確実にDFUに入れます。

  1. まず、BOOT0を押す(1sこの状態を保つ)
  2. 併せて、NRSTも押す(1sこの状態を保つ)
  3. NRSTを離す(この時もBOOT0は押したまま)
  4. 3ステップの1s後、BOOT0を離す

In short:

DFUデバイスのrealtimeの確認は、今風にjournalctl -fコマンドです。(昔はsudo dmsg -w)。

繋がったDFUデバイスの詳細状況は、dfu-util -lで確認します。

電源投入後すぐだと、一度以下のようなエラーでDFUに入れないことがありました。

usb 4-2: new full-speed USB device number 4 using xhci_hcd
usb 4-2: device descriptor read/64, error -71
usb 4-2: device descriptor read/64, error -71
usb 4-2: new full-speed USB device number 5 using xhci_hcd
usb 4-2: device descriptor read/64, error -71
usb 4-2: device descriptor read/64, error -71
usb usb4-port2: attempt power cycle
usb 4-2: new full-speed USB device number 6 using xhci_hcd
usb 4-2: Device not responding to setup address.
usb 4-2: Device not responding to setup address.
usb 4-2: device not accepting address 6, error -71
usb 4-2: new full-speed USB device number 7 using xhci_hcd
usb 4-2: Device not responding to setup address.
usb 4-2: Device not responding to setup address.
usb 4-2: device not accepting address 7, error -71
...

ただ2回目以降は、スイッチの手順さえ守れば確実にDFUには入れます。

今見直すと、A9-A12ピン問題が在ったボードで、同時押しで時際にはRESETだけを押したので上記エラーが出た気もしないでも在りません。

どうも電源投入後すぐという意味の「cold start」では上手くいかないので電源投入後安定化したという意味の「warm」後の時点という話が、チップを温めると温度の話になった感じもなきにしもあらずです。(この差が、本当に温度か、ハイインピーダンス回路での浮遊容量への電荷蓄積の差かはよくわかりません。)

DFUファイル経由での導入例 (CircuitPython導入によるDFUの練習)

MicroPythonのForkにCircuitPythonがあり、STM32F411CE Black Pillを明示的にサポートしています。

WeActのVENDERのサイト: https://github.com/WeActTC には、https://github.com/WeActTC/WeAct_F411CE-MicroPython レポがあり、そこには、ソースから下手にコンパイルせずコンパイル済みを使うようにとあります。確実に動くはずのこのファームウエアをDFUファイルから導入する、DFUの使い方を確認します。さてここで使うコンパイル済みDFUファイルですが、どうも以下のようです。

まず如何にもDFUで導入しなさいという.dfuという拡張子が付いたファイルの中で私の持っている外部ROM無しボード用と見られるfirmware_internal_rom_stm32f411_v1.14-7.dfuを導入を試みます。(本気でMicroPythonを使うなら、どうも外部ROM付きのボードとすべきようです。)

実際にはちょと手間取りましたが、どうもDFUの使い方の正解は以下のようです。

 $ dfu-util -l
dfu-util 0.11

Copyright 2005-2009 Weston Schmidt, Harald Welte and OpenMoko Inc.
Copyright 2010-2021 Tormod Volden and Stefan Schmidt
This program is Free Software and has ABSOLUTELY NO WARRANTY
Please report bugs to http://sourceforge.net/p/dfu-util/tickets/

Found DFU: [0483:df11] ver=2200, devnum=10, cfg=1, intf=0, path="4-2", alt=3, name="@Device Feature/0xFFFF0000/01*004 e", serial="************"
Found DFU: [0483:df11] ver=2200, devnum=10, cfg=1, intf=0, path="4-2", alt=2, name="@OTP Memory /0x1FFF7800/01*512 e,01*016 e", serial="************"
Found DFU: [0483:df11] ver=2200, devnum=10, cfg=1, intf=0, path="4-2", alt=1, name="@Option Bytes  /0x1FFFC000/01*016 e", serial="************"
Found DFU: [0483:df11] ver=2200, devnum=10, cfg=1, intf=0, path="4-2", alt=0, name="@Internal Flash  /0x08000000/04*016Kg,01*064Kg,03*128Kg", serial="************"

 $ dfu-util -d 0483:df11 -a 0  -D firmware_internal_rom_stm32f401ce_v30+_v1.14-7.dfu
dfu-util 0.11

Copyright 2005-2009 Weston Schmidt, Harald Welte and OpenMoko Inc.
Copyright 2010-2021 Tormod Volden and Stefan Schmidt
This program is Free Software and has ABSOLUTELY NO WARRANTY
Please report bugs to http://sourceforge.net/p/dfu-util/tickets/

Multiple alternate interfaces for DfuSe file
Opening DFU capable USB device...
Device ID 0483:df11
Device DFU version 011a
Claiming USB DFU Interface...
Setting Alternate Interface #0 ...
Determining device status...
DFU state(2) = dfuIDLE, status(0) = No error condition is present
DFU mode device DFU version 011a
Device returned transfer size 2048
DfuSe interface name: "Internal Flash  "
File contains 1 DFU images
Parsing DFU image 1
Target name: ST...
Image for alternate setting 0, (2 elements, total size = 340216)
Setting Alternate Interface #0 ...
Parsing element 1, address = 0x08000000, size = 14800
Erase   	[=========================] 100%        14800 bytes
Erase    done.
Download	[=========================] 100%        14800 bytes
Download done.
Parsing element 2, address = 0x08020000, size = 325400
Erase   	[=========================] 100%       325400 bytes
Erase    done.
Download	[=========================] 100%       325400 bytes
Download done.
Done parsing DfuSe file

この後、MASS STORAGE DEVICEが現れました。

$ pwd
/media/osamu/WEACTF401CE
osamu@goofy:/media/osamu/WEACTF401CE
$ ls -la
total 21
drwxr-xr-x  2 osamu osamu 16384 Jan  1  1970 .
drwxr-x---+ 1 root  root     22 Mar  9 19:30 ..
-rw-r--r--  1 osamu osamu   366 Jan  1  2015 boot.py
-rw-r--r--  1 osamu osamu    34 Jan  1  2015 main.py
-rw-r--r--  1 osamu osamu  2999 Jan  1  2015 pybcdc.inf
-rw-r--r--  1 osamu osamu   528 Jan  1  2015 README.txt

うまくCircuitPythonのファームウエアをinstallした後のUSB接続後ですが、現れたストレージは以下でした。

 $ df
Filesystem      1K-blocks      Used  Available Use% Mounted on
 ...
/dev/sda1              47         5         42  11% /media/osamu/WEACTF401CE

意外とまだメモリーに余裕があるようにも見えます。512KからCircutPythonが占拠した分を引いているので小さくはなっていますが、遊ぶには充分ですね。

CircuitPython導入でのDFUの失敗例

上記の正解に至までの失敗例は以下です。

BINファイルを使ったHID Bootloaderの時と同様に、--dfuse-address 0x08000000:leaveをDFUファイルに対してつけると、うまくいきません。

$ dfu-util -d 0483:df11 -a 0 --dfuse-address 0x08000000:leave -D firmware_internal_rom_stm32f401ce_v30+_v1.14-7.dfu
dfu-util 0.11

Copyright 2005-2009 Weston Schmidt, Harald Welte and OpenMoko Inc.
Copyright 2010-2021 Tormod Volden and Stefan Schmidt
This program is Free Software and has ABSOLUTELY NO WARRANTY
Please report bugs to http://sourceforge.net/p/dfu-util/tickets/

Multiple alternate interfaces for DfuSe file
Opening DFU capable USB device...
Device ID 0483:df11
Device DFU version 011a
Claiming USB DFU Interface...
Setting Alternate Interface #0 ...
Determining device status...
DFU state(10) = dfuERROR, status(10) = Device's firmware is corrupt. It cannot return to run-time (non-DFU) operations
Clearing status
Determining device status...
DFU state(2) = dfuIDLE, status(0) = No error condition is present
DFU mode device DFU version 011a
Device returned transfer size 2048
DfuSe interface name: "Internal Flash  "
dfu-util: This is a DfuSe file, not meant for raw download

以上の様に、「DFUファイルじゃない」といって拒否されていました。

ちゃんとDFUの規格を読むべきなんでしょうが、どうも分割され飛び飛びといったデーター記述ができる書き込み先アドレスを内包するバイナリーファイルがDFUファイルでのようです。一方、BINファイルは特定アドレスからベタに書き込むためのバイナリーデーターの印象です。ある意味、形式は違うがHEXと同じような機能があるようです。

また、dfu-utilは、--dfuse-address 0x08000000:leaveというオプションをつけると、バイナリーのサフィックスをつけてデーター内容見栄えを整えると、ファイル拡張子の如何によらずBINファイルとしてバイナリーデーターを解釈する印象です。

サンプルCircuitPythonコードの導入と実行

ストレージデバイス上にあるboot.py を一部アンコメントしました。

# boot.py -- run on boot-up
# can run arbitrary Python, but best to keep it minimal

import machine
import pyb
pyb.country('US') # ISO 3166-1 Alpha-2 code, eg US, GB, DE, AU
pyb.main('main.py') # main script to run after this one
#pyb.usb_mode('VCP+MSC') # act as a serial and a storage device
#pyb.usb_mode('VCP+HID') # act as a serial device and a mouse

そして、WeActのサイトのSDK/MicroPython_ExampleにあったBlink.pyを、main.pyに上書きしました。

USBを繋ぐと、青いLEDがピカピカしています。いい感じです。

DfuSeとdfuse-pack

以上の経験からDFUファイルとBINファイルが単なるサフィックスの有無等ではないことや、dfu-utilコマンドラインの違いによる動作の違いが見えてきました。

実際どうしてDFUファイルを作るのかなとGOOGLE検索していたら、dfu-utilのアップストリームのgit sourceに含まれる情報で、現在WEB上で読めるUsing dfu-util with DfuSe devicesに情報があり、そこにSTM32F4のようなDfuSeデバイスの使い方の説明の中にありました。(残念ながら、Tarされたソースや、Debianのパッケージにはこの情報は現在(2022-03)含まれていません。)

これによると、DfuSeは"DFU with ST Microsystems extensions"ですので、STMが拡張したDFUです。STM32F411のようなDfuSe デバイスは DFU バージョンを “1.1a"とレポートするそうです。正式のDFU標準(バージョン “1.1”)との互換性は無いそうです。「これを最初に読んでたら。。。」と思いました。

DfuSeデバイス用のファイルフォーマットが.dfu拡張子が付いたファイルで、dfuse-pack.pyを用いて作成でき、いくつかのメモリーブロックが組み合わさったファイルだそうです。dfuse-pack.pyはDebianではdfuse-packで、manpageはまだ無かったです。

$ dfuse-pack
Usage:
dfuse-pack [-d|--dump] infile.dfu
dfuse-pack {-b|--build} address:file.bin [-b address:file.bin ...] [{-D|--device}=vendor:device] outfile.dfu
dfuse-pack {-s|--build-s19} file.s19 [{-D|--device}=vendor:device] outfile.dfu
dfuse-pack {-i|--build-ihex} file.hex [-i file.hex ...] [{-D|--device}=vendor:device] outfile.dfu

Options:
  -h, --help            show this help message and exit
  -b BINFILES, --build=BINFILES
                        Include a raw binary file, to be loaded at the
                        specified address. The BINFILES argument is of the
                        form address:path-to-file. The address can have @X
                        appended where X is the alternate interface number for
                        this binary file. Note that the binary files must not
                        have any DFU suffix!
  -i HEXFILES, --build-ihex=HEXFILES
                        build a DFU file from given Intel HEX HEXFILES
  -s S19FILE, --build-s19=S19FILE
                        build a DFU file from given S19 S-record S19FILE
  -D DEVICE, --device=DEVICE
                        build for DEVICE, defaults to 0x0483:0xdf11
  -a ALTINTF, --alt-intf=ALTINTF
                        build for alternate interface number ALTINTF, defaults
                        to 0
  -d, --dump            dump contained images to current directory

メモリーダンプのBINと違い、DFUファイルは飛び飛びのメモリーアドレスへの書き込みができるようです。

上記でHEXFILESを使うにはpython3-intelhexをインストールしないといけません。

Previous Post Top Next Post