reTerminalのSTM32を吹っ飛ばした話
https://gyazo.com/5e351b67187d707ea48f566efd643795
はじめに
この時、理由は定かではないのですが、ファームウェアを飛ばしてしまい、reTerminalでディスプレイが表示されない悲しい状態になってしまいました。
この状態でも起動はするため、外部ディスプレイをHDMI接続すれば使えることは使えます。
しかし、せっかくディスプレイが付いているのにそれが使えないって悲しすぎませんか?
というわけで、このお話は、ファームウェアの復旧を行なった記録です。
基本的な情報収集の方法
はじめに、STM32のファームウェア基本的な情報を取得するための方法について見ていきます。
情報取得のためには、STM32が使われていない状態である必要があるため、/boot/config.txtを編集して、dtoverlay=reTerminalが書かれたエントリをコメントアウトする必要があります。
例えば、以下のようなどちらかのエントリが記述されていると思いますのでコメントアウトしてください。
code:/boot/config.txt
# dtoverlay=reTerminal
# dtoverlay=reTerminal,tp_rotate=1
STM32のファームウエアバージョンを確認するためには、i2ctransferを使います。
STM32が動作モードで動いている時は、I2Cアドレスは0x45となっているはずなので、ここにアクセスします。
バージョンは2バイトで帰ってきて、1番目がメジャーバージョン、次がマイナーバージョンで、以下の場合v.1.8となります。
code:firmware_version.sh
$ sudo i2ctransfer -y 1 w1@0x45 0x97 r2
0x01 0x08
I2Cのどのアドレスが使われているかを調べるためには、i2cdetectコマンドを使用します。
以下の一覧の中で、0x45がディスプレイドライバー(STM32)になります。
code:i2cdetect.sh
$ i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- 19 -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- 29 -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- 38 -- -- -- -- -- -- --
40: -- -- -- -- -- 45 -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
STM32がブートモードになっている場合、以下のように0x45ではなく0x56が現れます。
code:i2cdetect_boot.sh
$ i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- 19 -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- 29 -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- 38 -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- 56 -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
ファームウエアのアップデート方法
これによると、ファームウェアの更新には、以下の2パターンの方法があります。
v.1.7以上: stm32flashを使ったアップデートを行う。
それ以前: OpenOCDを使ったアップデートを行う。
ジャンパーを使って専用モードに入る必要がある。
今回は、もともと入っていたファームウェアバージョンがv.1.8であり最新版は1.9であったため、stm32flashを使った方法を試みましたが失敗しました。
というXのpostをしたところ、Seeedの松岡さんから復旧方法に関して返信をいただきました。
失敗:OpenOCDでの復旧手順
OpenOCDでのフラッシュ更新作業には、所定のジャンパーが必要なため、まずは分解をしました。
https://gyazo.com/8fcc8174ddb1a1845d0362670992327f
ジャンパー用のパッドは裏側にあります。
以下の写真のようにreTerminalを分解してジャンパーをはんだ付けしました。
パッドが小さく、その距離も短いため、はんだ付けするしかないと思います。
https://gyazo.com/d01a5624f05665f29dc98292e3758722
https://files.seeedstudio.com/wiki/ReTerminal/FAQ/pinout-stm32.png
Copyright (c) Seeed Development Limited (CC BY-SA)
2. - 10: OpenOCDのインストール手順で、コマンドとしては以下のとおりです。
code:shell
$ sudo apt install git autoconf libtool make pkg-config libusb-1.0-0 libusb-1.0-0-dev
$ cd openocd
$ ./bootstrap
$ ./configure --enable-sysfsgpio --enable-bcm2835gpio
$ make
$ sudo make install
11. 既に記述したようにジャンパーのはんだづけを行います。
12. ファームウエアの書き込み手順は以下のようになります。一見Errorが出ているように見えますが、最後のようにProgrammingとVerifyができていれば大丈夫です。
code:write_firmware.sh
$ /usr/local/bin/openocd -f /usr/local/share/openocd/scripts/interface/sysfsgpio-raspberrypi.cfg -c "transport select swd" -f /usr/local/share/openocd/scripts/target/stm32g0x.cfg -c "program STM32G030F6_R2.bin verify 0x08000000;shutdown"
Open On-Chip Debugger 0.12.0+dev-00422-g119a53386 (2023-12-05-11:51)
Licensed under GNU GPL v2
For bug reports, read
SysfsGPIO nums: swclk = 11, swdio = 25
swd
Info : SysfsGPIO JTAG/SWD bitbang driver
Info : Note: The adapter "sysfsgpio" doesn't support configurable speed
Info : SWD DPIDR 0x0bc11477
Info : starting gdb server for stm32g0x.cpu on 3333
Info : Listening on port 3333 for gdb connections
Error: Translation from khz to adapter speed not implemented
Error executing event reset-start on target stm32g0x.cpu:
embedded:startup.tcl:1225: Error:
in procedure 'program'
in procedure 'ocd_process_reset'
in procedure 'ocd_process_reset_inner' called at file "embedded:startup.tcl", line 1225
stm32g0x.cpu halted due to debug-request, current mode: Thread xPSR: 0xf1000000 pc: 0x1fff19a4 msp: 0x20000e60
Error: Translation from khz to adapter speed not implemented
Error executing event reset-init on target stm32g0x.cpu:
embedded:startup.tcl:1225: Error:
in procedure 'program'
in procedure 'ocd_process_reset'
in procedure 'ocd_process_reset_inner' called at file "embedded:startup.tcl", line 1225
** Programming Started **
Info : device idcode = 0x10016466 (STM32G03x/G04xx - Rev Z : 0x1001)
Info : RDP level 0 (0xAA)
Info : flash size = 32 KiB
Info : flash mode : single-bank
Warn : Adding extra erase range, 0x08004268 .. 0x080047ff
** Programming Finished **
** Verify Started **
** Verified OK **
shutdown command invoked
4.
code:check_firmware_version.sh
$ sudo i2ctransfer -y 1 w1@0x45 0x97 r2
Error: Sending messages failed: Input/output error
code:test.sh
$ i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- 19 -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- 29 -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- 38 -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- 56 -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
本来は、Linux上でディスプレイドライバを組み込んでいないときにはSTM32は0x45として見えるはずですが、ここではブートモードの0x56になったままです。
この状態では、ディスプレイは動作していません。
stm32flashを使ったファームウェアの再書き込み
この状態では、ディスプレイが利用できない状態のため、もう一度、今度はstm32flashを使ってファームウェアを書き込んでみました。
ここでは、必要なコマンドラインのみ記述します。
9. 現在のファームウェアを消去します。
code:shell
$ ./stm32flash -a 0x56 -o /dev/i2c-1
stm32flash 0.7
Warning: Not a tty: /dev/i2c-1
Error: Failed to apply settings
Error probing interface "serial_posix"
Interface i2c: addr 0x56
Version : 0x12
Device ID : 0x0466 (STM32G03xxx/04xxx)
- RAM : Up to 8KiB (4096b reserved by bootloader)
- Flash : Up to 64KiB (size first sector: 1x2048)
- Option RAM : 128b
- System RAM : 8KiB
Erasing flash
10. STM32に新たにファームウェアを書き込みます。
code:shell
$ ./stm32flash -a 0x56 -w ../STM32G030F6_R2.bin -v -g 0x0 /dev/i2c-1
stm32flash 0.7
Using Parser : Raw BINARY
Size : 17000
Warning: Not a tty: /dev/i2c-1
Error: Failed to apply settings
Error probing interface "serial_posix"
Interface i2c: addr 0x56
Version : 0x12
Device ID : 0x0466 (STM32G03xxx/04xxx)
- RAM : Up to 8KiB (4096b reserved by bootloader)
- Flash : Up to 64KiB (size first sector: 1x2048)
- Option RAM : 128b
- System RAM : 8KiB
Write to memory
Erasing memory
Wrote and verified address 0x08004268 (100.00%) Done.
Starting execution at address 0x08000000... done.
これで、ディスプレイドライバを組み込んでいないときには、ブートモードではなく動作モードで起動するようになりました。
code:.sh
$ i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- 19 -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- 29 -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- 38 -- -- -- -- -- -- --
40: -- -- -- -- -- 45 -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
11. 念のためファームウェアのバージョンを確認すると、以下のようにバージョン1.8になっています。実際にはバージョン1.9を書き込んだのですが、この時点ではバージョン番号が間違っていたようです。
code:firmware_version.sh
$ sudo i2ctransfer -y 1 w1@0x45 0x97 r2
0x01 0x08
ディスプレイの動作確認
動作を確認するために、ファクトリーデフォルトのイメージを焼いて試してみました。
これは、bookwormだと状況によってはディスプレイドライバがうまく入らないことがあるという情報をいただいたためです。
以下の図のように、問題なく動作しました!!
https://gyazo.com/f0e734ce55a5e890e73d0c95d2821e2f
おわりに
今回、reTerminalのディスプレイドライバーであるSTM32のファームウェアをなぜか壊してしまったため、このような作業が必要になりました。
ここでお礼を申し上げたいと思います。
RaspberryPiの中でも特殊な環境であるreTerminalの情報はあんまり参考になる人はいないと思いますが、万が一困った人があったら参考にしていただければと思います。