Rustでマイコンを理解したい

# OverView
Rustでのマイコンを学習してみたのでその記録。
「このロボット全部Rustで書きました」って言ってみたい...(治安悪化)
基本的には[公式Docs](https://docs.rust-embedded.org/book/)読んだだけです。

あと主はプログラム初心者だから間違えている可能性もある。（だめじゃん）

# Environment
|OS|board|
|:---:|:---:|
|ubuntu22.04|stm32 NUCLEO_F767ZI|

## Rust install
もちろんRustの[準備](https://www.rust-lang.org/ja/learn/get-started)が必要である。

## tools
どうやらボードに合わせた環境構築が必要ありそう。
なので[こちら](https://lipoyang.hatenablog.com/entry/20170909/p1)を参考にinstallしていく。

今回使用するボードは以下のような感じ
|コア|クロック|Flash|RAM|
|:---:|:---:|:---:|:---:|
|Cortex-M7|216MHz|2048kB|512kB|

```
rustup target add thumbv7em-none-eabi
```


```
cargo install cargo-binutils
```
```
rustup component add llvm-tools-preview
```



今回はcargo generateするので
```
cargo install cargo-generate
```

他色々
```
sudo apt install gdb-multiarch openocd qemu-system-arm
```

## device ready
```
lsusb
```
boardをPCに接続し確認すると以下のように出た
```
(...)
Bus 001 Device 004: ID 0483:374b STMicroelectronics ST-LINK/V2.1
(...)
```

getfaclでアクセス可能か確認しといた
```
getfacl /dev/bus/usb/001/004 | grep user
```
するとこのような表示がでるはず
```
user::rw-
user:you:rw-
```

# debug GDB and OpenOCD
## Cargo generate
まず以下のコマンドでテンプレを作成＆appという名前にした
```
cargo generate --git https://github.com/rust-embedded/cortex-m-quickstart
```


## Hello, world!
今回は先程generateしたappに含まれているexampleを使用する。

boardに合わせて設定する
```.cargo/config.toml
[build]
# Pick ONE of these default compilation targets
# target = "thumbv6m-none-eabi"        # Cortex-M0 and Cortex-M0+
# target = "thumbv7m-none-eabi"        # Cortex-M3
target = "thumbv7em-none-eabi"       # Cortex-M4 and Cortex-M7 (no FPU)
# target = "thumbv7em-none-eabihf"     # Cortex-M4F and Cortex-M7F (with FPU)
# target = "thumbv8m.base-none-eabi"   # Cortex-M23
# target = "thumbv8m.main-none-eabi"   # Cortex-M33 (no FPU)
# target = "thumbv8m.main-none-eabihf" # Cortex-M33 (with FPU)

```
```openocd.cfg
# Sample OpenOCD configuration for the STM32F3DISCOVERY development board

source [find interface/stlink.cfg]

source [find target/stm32f7x.cfg]
```

openocdを実行
```
user@user-raptop:~/app$ openocd
Open On-Chip Debugger 0.11.0
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 : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
Info : clock speed 2000 kHz
Info : STLINK V2J39M27 (API v2) VID:PID 0483:374B
Info : Target voltage: 3.227803
Info : stm32f7x.cpu: hardware has 8 breakpoints, 4 watchpoints
Info : starting gdb server for stm32f7x.cpu on 3333
Info : Listening on port 3333 for gdb connections
```

別のターミナルを開いてgdb起動
```
gdb-multiarch -q target/thumbv7em-none-eabi/debug/examples/hello
```
先程openocdを実行したとき
「Listening on port 3333 for gdb connections」と出ていたので
```
(gdb) target remote:3333
Remote debugging using :3333
0x0800db18 in ?? ()
```
マイコンに書き込む
```
(gdb) load
Loading section .vector_table, size 0x400 lma 0x0
Loading section .text, size 0xe64 lma 0x400
Loading section .rodata, size 0x418 lma 0x1264
Start address 0x00000400, load size 5756
Transfer rate: 117 KB/sec, 1918 bytes/write.
```

次にセミホスティング（アプリケーション・コードから発行される入出力要求実行されているホスト・コンピューター伝達するメカニズム）を有効にします。

セミホスティングには[公式のDocs](https://tomoyuki-nakabayashi.github.io/book/start/semihosting.html)がありました。
このページの冒頭に書いてあることが正しいはず()
```
(gdb) monitor arm semihosting enable
semihosting is enabled
```

以下のようにdebugしていく
```
(gdb) break main
Breakpoint 1 at 0x4b8: file examples/hello.rs, line 11.
(gdb) continue
Continuing.

Breakpoint 1, hello::__cortex_m_rt_main_trampoline () at examples/hello.rs:11
warning: Source file is more recent than executable.
11	#[entry]
(gdb) step
halted: PC: 0x000004be
hello::__cortex_m_rt_main () at examples/hello.rs:13
13	    hprintln!("Hello, world!").unwrap();
(gdb) next
halted: PC: 0x000004c6
halted: PC: 0x000004ca
halted: PC: 0x000004cc
halted: PC: 0x000004e6
halted: PC: 0x000004d4
halted: PC: 0x000004d8
halted: PC: 0x00000472
halted: PC: 0x000004de
17	    debug::exit(debug::EXIT_SUCCESS);
```

するとopenocd側では以下の結果が得られるはず
```
Info : halted: PC: 0x000004be
Info : halted: PC: 0x000004c6
Info : halted: PC: 0x000004ca
Info : halted: PC: 0x000004cc
Info : halted: PC: 0x000004e6
Hello, world!
Info : halted: PC: 0x000004d4
Info : halted: PC: 0x000004d8
Info : halted: PC: 0x00000472
Info : halted: PC: 0x000004de

```

# 終わりに
今回はとりあえずのdebug。
どうやらCargo runからもマイコンへの書き込みができそう
随時更新していきます。