NanoVNA (stm32f07) に対しての書きこみで、どの方法が早いのだろうか?と気になったので試した。対象は 95764bytes の ch.bin

結論からいうと SWD 経由の書きこみが早い。

USB 経由で dfu-util を使い書きこむ場合 → 18.7秒

(前もって DFU モードでブートする必要あり)

$ time dfu-util -d 0483:df11 -a 0 -s 0x08000000:leave -D build/ch.bin
dfu-util 0.9

Copyright 2005-2009 Weston Schmidt, Harald Welte and OpenMoko Inc.
Copyright 2010-2016 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/

dfu-util: Invalid DFU suffix signature
dfu-util: A valid DFU suffix will be required in a future dfu-util release!!!
Opening DFU capable USB device...
ID 0483:df11
Run-time device DFU version 011a
Claiming USB DFU Interface...
Setting Alternate Setting #0 ...
Determining device status: state = dfuERROR, status = 10
dfuERROR, clearing status
Determining device status: state = dfuIDLE, status = 0
dfuIDLE, continuing
DFU mode device DFU version 011a
Device returned transfer size 2048
DfuSe interface name: "Internal Flash  "
Downloading to address = 0x08000000, size = 95764
Download        [=========================] 100%        95764 bytes
Download done.
File downloaded successfully
Transitioning to dfuMANIFEST state
dfu-util -d 0483:df11 -a 0 -s 0x08000000:leave -D build/ch.bin  0.02s user 0.06s system 0% cpu 18.737 total

OpenOCD で書きこむ場合

OpenOCD からデバッグではなくプログラムを書きこむ場合

http://openocd.org/doc/html/Flash-Programming.html#Flash-Programming これの通りだけど、基本的に program コマンドを使えばよい。

program の実装は https://github.com/ntfreak/openocd/blob/master/src/flash/startup.tcl で、いくつかのコマンドを呼びだすラッパーになっている。

stm32f0x だと stm32f0x.cfg で reset 直後に 48MHz クロックを起動して JTAG の最高速度を 8MHz まで上げている。

OpenOCD 経由の ST-Link2 → 4.3秒

USB 経由と違って、いきなりコマンドを実行すれば書きこめる。

$ time openocd -f interface/stlink.cfg -f target/stm32f0x.cfg  -c "program ./build/ch.bin 0x08000000 verify reset exit"
Open On-Chip Debugger 0.10.0+dev-00930-g09eb941c (2019-09-14-00:35)
Licensed under GNU GPL v2
For bug reports, read
        http://openocd.org/doc/doxygen/bugs.html
Info : auto-selecting first available session transport "hla_swd". To override use 'transport select <transport>'.
Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD
Info : clock speed 1000 kHz
Info : STLINK V2J34S7 (API v2) VID:PID 0483:3748
Info : Target voltage: 3.261130
Info : stm32f0x.cpu: hardware has 4 breakpoints, 2 watchpoints
Info : Listening on port 3333 for gdb connections
Info : Unable to match requested speed 1000 kHz, using 950 kHz
Info : Unable to match requested speed 1000 kHz, using 950 kHz
target halted due to debug-request, current mode: Thread 
xPSR: 0xc1000000 pc: 0x080000c0 msp: 0x20000200
Info : Unable to match requested speed 8000 kHz, using 4000 kHz
Info : Unable to match requested speed 8000 kHz, using 4000 kHz
** Programming Started **
Info : device id = 0x20016448
Info : flash size = 128kbytes
** Programming Finished **
** Verify Started **
** Verified OK **
** Resetting Target **
Info : Unable to match requested speed 1000 kHz, using 950 kHz
Info : Unable to match requested speed 1000 kHz, using 950 kHz
shutdown command invoked
openocd -f interface/stlink.cfg -f target/stm32f0x.cfg -c   0.37s user 0.83s system 27% cpu 4.365 total

OpenOCD 経由の中華 J-Link OB → 4.6秒

nRF51 で一回試したっきり使っていない怪しい J-Link OB

USB 経由と違って、いきなりコマンドを実行すれば書きこめる。デフォルト JTAG なので、ちゃんと SWD を指定しないとダメです。

$ time openocd -f interface/jlink.cfg -c "transport select swd" -f target/stm32f0x.cfg   -c "program ./build/ch.bin 0x08000000 verify reset exit"
Open On-Chip Debugger 0.10.0+dev-00930-g09eb941c (2019-09-14-00:35)
Licensed under GNU GPL v2
For bug reports, read
        http://openocd.org/doc/doxygen/bugs.html
swd
Info : J-Link ARM-OB STM32 compiled Aug 22 2012 19:52:04
Info : Hardware version: 7.00
Info : VTarget = 3.300 V
Info : clock speed 1000 kHz
Info : SWD DPIDR 0x0bb11477
Info : stm32f0x.cpu: hardware has 4 breakpoints, 2 watchpoints
Info : stm32f0x.cpu: external reset detected
Info : Listening on port 3333 for gdb connections
target halted due to debug-request, current mode: Thread 
xPSR: 0xc1000000 pc: 0x080000c0 msp: 0x20000200
** Programming Started **
Info : device id = 0x20016448
Info : flash size = 128kbytes
** Programming Finished **
** Verify Started **
** Verified OK **
** Resetting Target **
shutdown command invoked
openocd -f interface/jlink.cfg -c "transport select swd" -f  -c   0.25s user 0.52s system 16% cpu 4.628 total
  1. トップ
  2. tech
  3. stm32f0x 書きこみ速度大会

chromium Issue 884928: Web Serial API が該当する。(Chrome 系以外では実装されていない。予定もない)

実は Chrome Stable 77 でも、既に chrome://flags/#enable-experimental-web-platform-features を有効にしていると navigator.serial が生えてくるようになっている。

が、Android では(まだ)使えないみたいだ。上記イシューも Android がスコープに入っていない。

簡単に試せるページもある GitHub - GoogleChromeLabs/serial-terminal: Demo application for the Serial API.

ちなみに WebUSB での polyfill があったりする(これも google のレポジトリに入っている…) https://github.com/google/web-serial-polyfill けど、USB CDCはだいたいはOS側でインターフェイスを握られてしまうので、ドライバを無効にしたりしないといけないことに注意がいる。

現行では worker コンテキスト内で使うことができない。API 自体は有効なのだが、requestPort() してペアリングしたシリアルポートを、worker 内の getPorts で取得することができない。Issue 1005079: Serial Mojo interface not provided to Workers 報告したらイシューが立った。

また、上記に関連するのかもしれないが、そこそこ高速で通信を行うと容易にバッファが溢れてしまい、データの欠落が起こる。なので非常に大きなバッファを指定する必要がある。複数同時に read してもダメ。

  1. トップ
  2. tech
  3. Web Serial API

しばらく放っておいてどうセットアップしたか忘れたので、https://www.armbian.com/nanopi-neo-2/ armbian を改めて入れてみる。

FriendlyARM のイメージも結構更新されていそうだけど、どっちがいいか不明。しかし FriendlyARM のイメージはいまいちデキが良い感じがしなかったので、armbian Bionic server (Ubuntu系) を入れてみる。

SDカード書きこみ

Etcher で焼くだけ

初回起動

ping 192.168.0.255 とかして arp -a して 02:01:a9 からはじまる Mac アドレスがそれ。

https://docs.armbian.com によると、デフォルトで ssh が起動しており、root 、 1234 で入れるらしい。

ssh root@192.168.0.xx

すると、初回設定としてパスワード変更とユーザ追加をさせられる。やったら一回 logout して、作ったユーザーでログインしなおす。

前後して

 ssh-copy-id  cho45@192.168.0.17

とかやっておく。

初回設定

sudo armbian-config

して Personal -> Timezone の設定と、 System -> Hardware -> i2c0 にチェックを入れて再起動。

NanoHat OLED

i2c

検出できるか確認しとく。

$ sudo apt install i2c-tools
$ sudo i2cdetect -y 0
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- 3c -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --  

i2c グループに自分を追加しておく

$ sudo usermod -a -G i2c
# 一回ログアウトすること
$ i2cdetect -y 0

gpio

armbian もデフォルトでは root にしか gpio へのアクセス権限がなく、gpio グループなども設定されていない。ので自分でやる必要がある.

sudo groupadd gpio
sudo usermod -aG gpio cho45
$ sudo vim /etc/udev/rules.d/80-gpio.rules
SUBSYSTEM=="gpio", PROGRAM="/bin/sh -c '/bin/chown -R root:gpio /sys/devices/platform/soc/*pinctrl/gpio*'"
SUBSYSTEM=="gpio", PROGRAM="/bin/sh -c '/bin/chmod -R ug+rw /sys/devices/platform/soc/*pinctrl/gpio*'"
SUBSYSTEM=="gpio", PROGRAM="/bin/sh -c '/bin/chown -R root:gpio /sys/class/gpio'"
SUBSYSTEM=="gpio", PROGRAM="/bin/sh -c '/bin/chmod -R ug+rw /sys/class/gpio'"
sudo udevadm control --reload-rules
sudo udevadm test --action=change /sys/devices/platform/soc/1c20800.pinctrl/gpiochip1/gpio/gpio0
$ ls -altr /sys/class/gpio/
total 0
-rw-rw----  1 root gpio 4096 Sep 15 15:45 export
drwxrwxr-x  2 root gpio    0 Sep 15 15:45 .
drwxr-xr-x 51 root root    0 Sep 15 15:45 ..
lrwxrwxrwx  1 root gpio    0 Sep 15 15:45 gpio0 -> ../../devices/platform/soc/1c20800.pinctrl/gpiochip1/gpio/gpio0
-rw-rw----  1 root gpio 4096 Sep 15 15:45 unexport
lrwxrwxrwx  1 root gpio    0 Sep 15 15:45 gpio3 -> ../../devices/platform/soc/1c20800.pinctrl/gpiochip1/gpio/gpio3
lrwxrwxrwx  1 root gpio    0 Sep 15 15:45 gpiochip352 -> ../../devices/platform/soc/1f02c00.pinctrl/gpio/gpiochip352
lrwxrwxrwx  1 root gpio    0 Sep 15 15:45 gpiochip0 -> ../../devices/platform/soc/1c20800.pinctrl/gpio/gpiochip0
lrwxrwxrwx  1 root gpio    0 Sep 15 15:45 gpio2 -> ../../devices/platform/soc/1c20800.pinctrl/gpiochip1/gpio/gpio2

node

nodejs をいれる。apt でいれると気持ちわるいことになるので公式パッケージをいれるほうがよい。

$ cd ~/
$ mkdir app
$ cd app
$ wget https://nodejs.org/dist/v10.16.3/node-v10.16.3-linux-arm64.tar.xz
$ tar xvf node-v10.16.3-linux-arm64.tar.xz
$ ln -s  node-v10.16.3-linux-arm64 node
$ cd ~/bin
$ ln -s ~/node/bin/* .
$ sudo apt install pkg-config libcairo2-dev
$ git clone git@github.com:cho45/nanohat-oled-nodejs.git
$ cd nanohat-oled-nodejs
$ npm install

動作確認

$ node index.js

systemd 化

$ ./install.sh

備考: ssh ログイン時のメッセージ

$ ls  /etc/update-motd.d

にある。/etc/update-motd.d/30-armbian-sysinfo が特に有用

  1. トップ
  2. tech
  3. NanoPi NEO2 + NanoHAT OLED に armbian