openocdでSEGGER RTTを使う

使えないかと思っていたらパッチが投稿されていた。まだマージされていないが、使うことができる。

$ git clone git://repo.or.cz/openocd.git
$ git fetch http://openocd.zylin.com/openocd refs/changes/55/4055/8 && git checkout FETCH_HEAD
$ cd openocd/
$ ./bootstrap
$ ./configure --enable-sysfsgpio --enable-bcm2835gpio --prefix=$HOME/openocd-rtt
$ make -j4
$ make install

上記のコマンドを実行すればopenocdのバイナリができる。configureの際にprefixオプションを付けて、最初からに入っているopenocdと被らないようにしたが、必要がなければprefixは消してもらいたい。

さて、バイナリがインストールされたら、普段通りにopenocdを実行する。localhost:4444のコンソールから操作するが、以下のようなコマンドを実行する。0x2000321cは環境によって異なるので変える必要がある。

> rtt setup 0x2000321c 512 "SEGGER RTT" 
> rtt start
> rtt channels
> rttserver start 5555 0

そうすると、localhost:5555にtelnetで接続できるようなる。あとは出力を眺めるだけ。

コントロールブロックの探し方

さて、0x2000321cは環境によって異なると書いたが、見つけ方はいくつかある。

.mapを見る

nRF5 SDKでコンパイラはarmgccを使った。_build\nrf51422_xxac.mapを開く。

_build\nrf51422_xxac.mapを開く。

COMMON         0x2000321c       0x78 _build/nrf51422_xxac_SEGGER_RTT.c.o
0x2000321c _SEGGER_RTT

すると、上記のような部分が見つかる。ここにある0x2000321cが入力するアドレスになる。

GDBを使う(推奨)

eval "monitor rtt setup %p 512 SEGGER\\ RTT", &_SEGGER_RTT
monitor rtt start
monitor rtt channels
monitor rttserver start 5555 0

上記のコマンドをGDBで実行してもRTTのコントロールブロックのアドレスを与えることができる。こちらの方が楽だ。

これでUARTつないでいなくても出力を眺めることができるので非常に便利なる。デバッグがはかどりそうだ。数千円かけてJ-Linkを買わないといけないのか…と思っていたが、手元にあるRasPi Zero Wでも同じことができた。

RyzenでHyper-Vを使うとシャットダウンが遅くなっていた

Ryzen 7 1700のCPUを積んだPCでHyper-Vを有効にすると、シャットダウンがたまに遅れて、再起動したらイベントログにBugCheck 0x00000133とか残っていてブルースクリーンで落ちているという不具合が起きていた。電源を切りたいのに時間がかかるし、次回の起動も再起動扱いなので遅くなる。ダメもとでBIOSを最新に更新したら不具合がなくなった。

gatttoolでnotifyを受け取る

どのハンドルに0100を書き込めばいいのかわからずに困っていた。こちらのサイトが参考になった

[E6:BF:6D:43:62:BE][LE]> primary
attr handle: 0x0001, end grp handle: 0x0007 uuid: 00001800-0000-1000-8000-00805f9b34fb
attr handle: 0x0008, end grp handle: 0x0008 uuid: 00001801-0000-1000-8000-00805f9b34fb
attr handle: 0x0009, end grp handle: 0xffff uuid: eeddffff-ccbb-aa99-8877-665544332211
[E6:BF:6D:43:62:BE][LE]> char-read-uuid 0x2902 0x09
handle: 0x000e value: 00 00
[E6:BF:6D:43:62:BE][LE]> char-write-req 0x0e 0100 --listen
Characteristic value was written successfully
Notification handle = 0x000d value: ff 86 13 61 3a 00 00 00 cc
Notification handle = 0x000d value: ff 86 13 61 3a 00 00 00 cc
  1. primaryでハンドルを見つける。
  2. char-read-uuid 0x2902 見つけたハンドル
  3. char-write-req char-read-uuidで見つかったハンドル 0100 –listen

net-radio-archiveが動かなくなっていた

よくわからずにrootでbundle installしていた付けが回ってきた(今更

あと、更新スクリプトでbundle installしていないっぽいのもまずかったかも

ともかく、正月から録音が完全に止まっていたという大惨事になっていた。

$ bundle
Fetching gem metadata from https://rubygems.org/……….
Using rake 12.3.0
Using concurrent-ruby 1.0.5
Using i18n 0.9.1
Using minitest 5.10.3
Using thread_safe 0.3.6
Using tzinfo 1.2.4
Using activesupport 4.2.10
Using builder 3.2.3
Using erubis 2.7.0
Using mini_portile2 2.3.0
Using nokogiri 1.8.1
Using rails-deprecated_sanitizer 1.0.3
Using rails-dom-testing 1.0.8
Using crass 1.0.3
Using loofah 2.1.1
Using rails-html-sanitizer 1.0.3
Using actionview 4.2.10
Using rack 1.6.8
Using rack-test 0.6.3
Using actionpack 4.2.10
Using globalid 0.4.1
Using activejob 4.2.10
Using mini_mime 1.0.0
Using mail 2.7.0
Using actionmailer 4.2.10
Using activemodel 4.2.10
Using arel 6.0.4
Using activerecord 4.2.10
Using activerecord-import 0.21.0
Using bundler 1.16.1
Using chronic 0.10.2
Using coderay 1.1.2
Using coffee-script-source 1.12.2
Using execjs 2.7.0
Using coffee-script 2.4.1
Using thor 0.20.0
Using railties 4.2.10
Using coffee-rails 4.0.1
Using unf_ext 0.0.7.4
Using unf 0.1.4
Using domain_name 0.5.20170404
Using hike 1.2.3
Using http-cookie 1.0.3
Using multi_xml 0.6.0
Using httparty 0.15.6
Using multi_json 1.12.2
Using jbuilder 2.7.0
Using jquery-rails 4.3.1
Using json 1.8.6
Fetching m3u8 0.8.2
Bundler::GemspecError: Could not read gem at
/var/lib/gems/2.1.0/cache/m3u8-0.8.2.gem. It may be corrupted.
An error occurred while installing m3u8 (0.8.2), and Bundler cannot
continue.
Make sure that gem install m3u8 -v '0.8.2' succeeds before bundling.
In Gemfile:
m3u8

$ bundle –path vendor/bundle で解決した(参考

AE-TYBLE16でnRF5 SDKのサンプルを動かす

バイナリを生成する

12.3.0nRF5 SDKをダウンロードした。

pca10028/s130/config/sdk_config.hで CLOCK_CONFIG_XTAL_FREQ 255->0, CLOCK_CONFIG_LF_SRC 1 -> 0と書き換える(変えなくても動いていたが念のため)

各サンプルのmain.cのble_stack_init( )の冒頭にあるclock_lf_cfgを次のように書き換える。(これは書き換えないと全く動かなかった。)

nrf_clock_lf_cfg_t clock_lf_cfg;
clock_lf_cfg.rc_ctiv = 16;
clock_lf_cfg.rc_temp_ctiv = 2;
clock_lf_cfg.source = NRF_CLOCK_LF_SRC_RC;
clock_lf_cfg.xtal_accuracy = NRF_CLOCK_LF_XTAL_ACCURACY_250_PPM;

$(SDKROOT)/components/toolchain/{system_nrf51.c,system_nrf51422.c}の2つのファイルの冒頭 __SYSTEM_CLOCK (16000000UL) を (32000000UL) に書き換える。

これでコンパイルしてできたバイナリがAE-TYBLE16でで動くはず。

書き込む

書き込みはRaspberry Pi Zero W上で走らせたopenocdで行った。openocd.cfgは下記の通りだった。set WORKAREASIZE 0がないとエラーが出て書き込めなかった。swclk = 25, swdio = 24になるので適当に接続する。

source [find interface/raspberrypi-native.cfg]
transport select swd
bcm2835gpio_swd_nums 25 24
bcm2835gpio_trst_num 7
bcm2835gpio_srst_num 18
set WORKAREASIZE 0
source [find target/nrf51.cfg]

s130-201.hexは$(SDKROOT)\components\softdevice\s130\hex\s130_nrf51_2.0.1_softdevice.hexで、blinky.hexが先ほどコンパイルして生成されたhexになる。適当な方法でRasPiに転送する。今回はpscpを使った。

ケーブルが接続されていることを確認して、RasPiのlocalhost:4444に telnetで 接続した。下記のコマンドを入力する。

reset halt
halt; nrf51 mass_erase; flash write_image s130-201.hex 0; flash write_image blinky.hex
mww 0x4001e504 1 ; mww 0x10001000 0x0001C000; mww 0x10001008 0xffffff00; mww 0x4001e504 0;
reset run

ちなみに、openocdを実行するとシェルにはこんな出力が出る。

pi@raspberrypizero:~ $ sudo openocd
Open On-Chip Debugger 0.10.0+dev-00232-g6f5e9941 (2018-01-10-08:50)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
BCM2835 GPIO config: tck = 11, tms = 25, tdi = 10, tdo = 9
BCM2835 GPIO nums: swclk = 25, swdio = 24
BCM2835 GPIO config: trst = 7
BCM2835 GPIO config: srst = 18
cortex_m reset_config sysresetreq
adapter speed: 1000 kHz
Info : BCM2835 GPIO JTAG/SWD bitbang driver
Info : JTAG and SWD modes enabled
Info : clock speed 1006 kHz
Info : SWD DPIDR 0x0bb11477
Info : nrf51.cpu: hardware has 4 breakpoints, 2 watchpoints
Info : accepting ‘telnet’ connection on tcp/4444

port 4444にtelnetした方は次のような感じになる

Open On-Chip Debugger
> reset halt target halted due to debug-request, current mode: Thread
xPSR: 0xc1000000 pc: 0x000006d0 msp: 0x000007c0
> halt; nrf51 mass_erase; flash write_image s130-201.hex 0; flash write_image blinky.hex
nRF51822-CFAC(build code: A0) 256kB Flash
Padding image section 0 with 2112 bytes
not enough working area available(requested 32)
no working area available, falling back to slow memory writes
wrote 110560 bytes from file s130-201.hex in 7.748491s (13.934 KiB/s)
not enough working area available(requested 32)
no working area available, falling back to slow memory writes
wrote 48232 bytes from file blinky.hex in 3.481749s (13.528 KiB/s)
> mww 0x4001e504 1 ; mww 0x10001000 0x0001C000; mww 0x10001008 0xffffff00; mww 0x4001e504 0;
> reset run

1/7追記:

mww 0x10001000 0x0001C000;は間違っていた。mww 0x10001000 0x0001b000;だった( pca10028/s130/ble_app_template_gcc_nrf51.ld )とかを見るとFLASH (rx) : ORIGIN = 0x1b000, LENGTH = 0x25000とか書いてあるので、ORIGINを参考にして設定する。適切に設定すれば2回目以降はmass_eraseが不要になる。そうするとsoftdeviceを書き込みしなおさなくて済むので時間が節約できる。sudo openocd -f openocd.cfg -c ‘init; reset halt; flash write_image erase blinky.hex; reset run; exit’ でやっている。さらに言えば、openocd.cfgの一番最後にadapter_khz 4000を付けると速くなった。