課題
もう課題に挑む準備は万端です!この章の冒頭でお見せしたアプリケーションを、 今度は自分で実装するのがあなたの課題です。
もう一度 GIF を載せておきます:
また、これも参考になるかもしれません:
これはタイミング図です。任意の時点でどの LED が点灯しているか、また各 LED がどれくらいの時間
点灯しているべきかを示しています。X 軸はミリ秒単位の時間です。このタイミング図が示しているのは
1 周期分です。このパターンは 800 ms ごとに繰り返されます。Y 軸では各 LED が方位でラベル付け
されています。North、East などです。課題の一環として、Leds 配列の各要素がこれらの方位の
どれに対応しているかを突き止める必要があります(ヒント: cargo doc --open ;-))。
この課題に取り組む前に、追加でもう 1 つヒントを挙げておきます。GDB セッションでは、最初に毎回
同じコマンドを入力することになります。GDB の起動直後にいくつかのコマンドを実行するために .gdb
ファイルを使えます。こうしておけば、GDB セッションのたびにそれらを手作業で入力する手間を
省けます。
実は、../openocd.gdb はすでに作成済みで、前のセクションで行ったことに加えて
いくつかのコマンドも実行しているのがわかります。詳しくは、
コメントを見てください:
$ cat ../openocd.gdb
# gdb リモートサーバーに接続する
target remote :3333
# load でコードを書き込む
load
# 逆アセンブル時に asm 名のデマングリングを有効にする
set print asm-demangle on
# pretty printing を有効にする
set print pretty on
# デフォルトの色は読みにくいことがあるので、sources のスタイルを無効にする
set style sources off
# モニタリングを初期化し、iprintln! マクロの出力が
# itm ポートから itm.txt に送られるようにする
monitor tpiu config internal itm.txt uart off 8000000
# itm ポートを有効にする
monitor itm port 0 on
# main(つまり entry)にブレークポイントを設定する
break main
# DefaultHandler にブレークポイントを設定する
break DefaultHandler
# HardFault にブレークポイントを設定する
break HardFault
# 実行を継続し、main のブレークポイントに到達するまで進める
continue
# entry のトランポリンコードから main へステップ実行する
step
次に、../.cargo/config.toml ファイルを変更して ../openocd.gdb を実行するようにします
nano ../.cargo/config.toml
runner コマンドに -x ../openocd.gdb を追加してください。
arm-none-eabi-gdb を使っているとすると、差分は次のようになります:
~/embedded-discovery/src/05-led-roulette
$ git diff ../.cargo/config.toml
diff --git a/src/.cargo/config.toml b/src/.cargo/config.toml
index ddff17f..02ac952 100644
--- a/src/.cargo/config.toml
+++ b/src/.cargo/config.toml
@@ -1,5 +1,5 @@
[target.thumbv7em-none-eabihf]
-runner = "arm-none-eabi-gdb -q"
+runner = "arm-none-eabi-gdb -q -x ../openocd.gdb"
# runner = "gdb-multiarch -q"
# runner = "gdb -q"
rustflags = [
また、arm-none-eabi-gdb を使っている前提での ../.cargo/config.toml の内容全体は、
次のとおりです:
[target.thumbv7em-none-eabihf]
runner = "arm-none-eabi-gdb -q -x ../openocd.gdb"
# runner = "gdb-multiarch -q"
# runner = "gdb -q"
rustflags = [
"-C", "link-arg=-Tlink.x",
]
[build]
target = "thumbv7em-none-eabihf"
これで、シンプルに cargo run コマンドを使うだけで、ARM 向けのコードをビルドして
gdb セッションを実行できるようになります。gdb セッションはプログラムを自動的に
フラッシュし、entry のトランポリンを step でたどりながら
main の先頭へジャンプします:
cargo run
~/embedded-discovery/src/05-led-roulette (Update-05-led-roulette-WIP)
$ cargo run
Finished dev [unoptimized + debuginfo] target(s) in 0.01s
Running `arm-none-eabi-gdb -q -x openocd.gdb ~/embedded-discovery/target/thumbv7em-none-eabihf/debug/led-roulette`
Reading symbols from ~/embedded-discovery/target/thumbv7em-none-eabihf/debug/led-roulette...
led_roulette::__cortex_m_rt_main_trampoline () at ~/embedded-discovery/src/05-led-roulette/src/main.rs:7
7 #[entry]
Loading section .vector_table, size 0x194 lma 0x8000000
Loading section .text, size 0x52c0 lma 0x8000194
Loading section .rodata, size 0xb50 lma 0x8005454
Start address 0x08000194, load size 24484
Transfer rate: 21 KB/sec, 6121 bytes/write.
Breakpoint 1 at 0x8000202: file ~/embedded-discovery/src/05-led-roulette/src/main.rs, line 7.
Note: automatically using hardware breakpoints for read-only addresses.
Breakpoint 1, led_roulette::__cortex_m_rt_main_trampoline ()
at ~/embedded-discovery/src/05-led-roulette/src/main.rs:7
7 #[entry]
led_roulette::__cortex_m_rt_main () at ~/embedded-discovery/src/05-led-roulette/src/main.rs:9
9 let (mut delay, mut leds): (Delay, LedArray) = aux5::init();
discovery book をフォークする
まだであれば、変更を自分の fork 上の自分のブランチに保存できるように、
embedded discovery book をフォークしておくのがよいでしょう。
自分用のブランチを作成し、master ブランチはそのままにしておくことをおすすめします。
そうすれば、fork 側の master ブランチを upstream リポジトリと同期したままに
できます。また、PR をより簡単に作成してこの本を改善しやすくなります。よろしくお願いします!