Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

課題

もう課題に挑む準備は万端です!この章の冒頭でお見せしたアプリケーションを、 今度は自分で実装するのがあなたの課題です。

もう一度 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 をより簡単に作成してこの本を改善しやすくなります。よろしくお願いします