これまでに何度もやったのだが、、再度WSLに組み込みRustを入れる。今回はno-std開発用
もう時間もなく、じっくり資料読みながら作業する余裕もないので、RustBookをちらちらと呼んで必要そうなコマンドを実行
rustup toolchain install nightly --component rust-src rustup target add riscv32imc-unknown-none-elf # For ESP32-C2 and ESP32-C3 sudo apt install pkg-config cargo install cargo-generate cargo install cargo-espflash
cargo run でビルド、書き込みまで行おうとするが、最後の書き込みのところで、esplfashが無いと怒られる
espflash flash --monitor target/riscv3(elfバイナリ)
さっき入ったのは、cargo-espflashなのであった。さらに、WSLの場合、Windows環境のUSBが手当てしないと見えない。WSLからWindows環境のUSBが扱えるように設定する
usbipd-win をWindows環境にインストールする
DLサイトは以下
Releases · dorssel/usbipd-win · GitHub
Ubuntuで以下を実行
sudo apt install linux-tools-generic hwdata sudo update-alternatives --install /usr/local/bin/usbip usbip /usr/lib/linux-tools/*-generic/usbip 20
PowerShell で usbipd wsl list を実行
PS C:\Windows\system32> usbipd wsl list BUSID VID:PID DEVICE STATE 2-2 303a:1001 USB シリアル デバイス (COM17), USB JTAG/serial debug unit Not attached 2-3 046d:c058 USB 入力デバイス Not attached 2-5 1199:90b1 Sierra Wireless EM7431 Qualcomm® Snapdragon™ X16 LTE-A, S... Not attached 2-7 5986:118f USB FHD Camera, IR Camera, Camera DFU Device Not attached 2-8 06cb:00c6 Synaptics UWP WBDI Not attached 2-10 8087:0033 インテル(R) ワイヤレス Bluetooth(R) Not attached
PowerShellで以下を実行
usbipd wsl attach --busid <busid>
今回の場合、USBシリアルデバイスは、2-2なので、以下となる
PS C:\Windows\system32> usbipd wsl attach --busid 2-2
Ubuntuで確認
$ lsusb Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub Bus 001 Device 002: ID 303a:1001 Espressif USB JTAG/serial debug unit Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub $ ls /dev/ttyACM0 /dev/ttyACM0
ボードとは通信できているようなのだが・・
$ cargo espflash board-info [2023-11-05T08:18:59Z INFO ] Serial port: '/dev/ttyACM0' [2023-11-05T08:18:59Z INFO ] Connecting... [2023-11-05T08:18:59Z INFO ] Using flash stub Chip type: esp32c3 (revision v0.4) Crystal frequency: 40MHz Flash size: 4MB Features: WiFi, BLE MAC address: 34:85:18:00:FF:FF
念のためFlashを消去
$ cargo espflash erase-flash [2023-11-05T08:20:38Z INFO ] Serial port: '/dev/ttyACM0' [2023-11-05T08:20:38Z INFO ] Connecting... [2023-11-05T08:20:38Z INFO ] Using flash stub [2023-11-05T08:20:38Z INFO ] Erasing Flash...
焼いてみる。成功した(Flash削除せずにやったら失敗したのだが)
$ cargo espflash flash [2023-11-05T08:25:26Z INFO ] Serial port: '/dev/ttyACM0' [2023-11-05T08:25:26Z INFO ] Connecting... [2023-11-05T08:25:26Z INFO ] Using flash stub Finished dev [unoptimized + debuginfo] target(s) in 3.82s Chip type: esp32c3 (revision v0.4) Crystal frequency: 40MHz Flash size: 4MB Features: WiFi, BLE MAC address: 34:85:18:00:b3:ac App/part. size: 225,472/4,128,768 bytes, 5.46% [00:00:00] [========================================] 13/13 0x0 [00:00:00] [========================================] 1/1 0x8000 [00:00:02] [========================================] 73/73 0x10000 [2023-11-05T08:25:33Z INFO ] Flashing has completed!
espflashのmonitor機能でUSBから出力されているはずの文字列を読もうとするが読めない・・なぜだろうか。暴走している?
$ cargo espflash monitor [2023-11-05T08:40:30Z INFO ] Serial port: '/dev/ttyACM0' [2023-11-05T08:40:30Z INFO ] Connecting... [2023-11-05T08:40:30Z INFO ] Using flash stub Commands: CTRL+R Reset chip CTRL+C Exit
no_std版でLチカさせてみるがチカっとしない。やっぱり暴走しているのかstartupがうまくいっていないのか・・ open-ocdでデバッグ必要か!?
#![no_std] #![no_main] use esp_backtrace as _; use esp_println::println; use hal::{clock::ClockControl, gpio::IO, peripherals::Peripherals, prelude::*, Delay}; #[entry] fn main() -> ! { let peripherals = Peripherals::take(); let system = peripherals.SYSTEM.split(); let clocks = ClockControl::max(system.clock_control).freeze(); let mut delay = Delay::new(&clocks); let io = IO::new(peripherals.GPIO, peripherals.IO_MUX); //let mut led = io.pins.gpio8.into_push_pull_output(); // for xiao //let mut led = io.pins.gpio7.into_push_pull_output(); // for Eva Board let mut monitor = io.pins.gpio0.into_push_pull_output(); // GPIO0 println!("Hello world!"); loop { println!("Loop..."); monitor.toggle().unwrap(); delay.delay_ms(500u32); } }
Rustのno-std bookがあるのでこれを読んで復習
Introduction - Embedded Rust (no_std) on Espressif
espflashツールは以下の通り2つ入れるべし
cargo install cargo-espflash espflash
各種ライブラリが必要(すでに入れたのもあるし、新たに入ったのもある)
sudo apt install llvm-dev libclang-dev clang
no_std版のトレーニング資料一式を落とす
git clone "https://github.com/esp-rs/no_std-training.git" cd no_std-training
HelloWorldのビルドサンプルがあるので、チュートリアルに従ってビルドしてみる。
Hello World - Embedded Rust (no_std) on Espressif
ビルド自体はすんなり動いてモニタのところまでは進んだ。するとどうも内部でリセットが発生しているようであった。
Running `espflash flash --monitor target/riscv32imc-unknown-none-elf/debug/hello_world` [2023-11-05T09:15:35Z INFO ] Serial port: '/dev/ttyACM0' [2023-11-05T09:15:35Z INFO ] Connecting... [2023-11-05T09:15:36Z INFO ] Using flash stub Chip type: esp32c3 (revision v0.4) Crystal frequency: 40MHz Flash size: 4MB Features: WiFi, BLE MAC address: 34:85:18:00:FF:FF App/part. size: 194,304/4,128,768 bytes, 4.71% [00:00:00] [========================================] 13/13 0x0 [00:00:00] [========================================] 1/1 0x8000 [00:00:01] [========================================] 61/61 0x10000 [2023-11-05T09:15:38Z INFO ] Flashing has completed! Commands: CTRL+R Reset chip CTRL+C Exit ESP-ROM:esp32c3-api1-20210207 Build:Feb 7 2021 rst:0x15 (USB_UART_CHIP_RESET),boot:0x4 (DOWNLOAD(USB/UART0/1)) Saved PC:0x40380836 0x40380836 - esp_hal_common::interrupt::riscv::vectored::handle_interrupts at /home/<user_id>/.cargo/registry/src/index.crates.io-6f17d22bba15001f/esp-hal-common-0.12.0/src/interrupt/riscv.rs:214 waiting for download
起動のためのソフトリセットなのか、それとも何か問題が発生してExceptionが発生しているのか。。
該当ソースは以下の様であるが、、多分Exceptionが発生して飛んできたということだと推測
207 unsafe fn handle_interrupts(cpu_intr: CpuInterrupt, context: &mut TrapFrame) { 208 let status = get_status(crate::get_core()); 209 210 // this has no effect on level interrupts, but the interrupt may be an edge one 211 // so we clear it anyway 212 clear(crate::get_core(), cpu_intr); 213 214 let configured_interrupts = get_configured_interrupts(crate::get_core(), status);
メッセージは異なるが、waiting for download でおかしくなるという書き込みがあったので内容を確認
ESP32-C3 Stuck waiting for download - ESP32 Forum
相談している人は起動モードを管理する、GPIO9 のレベルがおかしいのでは?という回答であった。
細かい理由は分からないが、一旦ボードをUSBケーブルから抜いて再度接続するとLEDが点滅した。だから、、起動オプションがダウンロードモードのままで固定されていたためと考える。USBで接続する時これまではBootボタンを押して接続していたのだがそれが原因だろうか。今だとダウンロードモードではなく、普通の実行モードなので、この状態でFlashに書き込めるか試してみる。
何がどういう理由でこういうことになるのか、詳細が分からないのだが、、普通に走っている状態で、WSLからUSBがアクセスできるようにする。その後、espflash monitorを実行すると、LEDの点滅が止まる。なぜ止まるのか? ダウンロードモードに遷移するからなのか?
ここで、Ctrl+Rでリセットを送信?すると、ボードは再起動されて、シリアル出力がなされた。
[2023-11-05T10:06:00Z INFO ] Using flash stub Commands: CTRL+R Reset chip CTRL+C Exit ESP-ROM:esp32c3-api1-20210207 Build:Feb 7 2021 rst:0x15 (USB_UART_CHIP_RESET),boot:0xc (SPI_FAST_FLASH_BOOT) Saved PC:0x40380836 SPIWP:0xee mode:DIO, clock div:2 load:0x3fcd5820,len:0x171c load:0x403cc710,len:0x968 load:0x403ce710,len:0x2f68 SHA-256 comparison failed: Calculated: 1d06b938c0222bf626e0bdf46178b1b37ab24d03f0360fc8fcf7153c2571deaf Expected: 68d7bdf643ba446b8ed7ae8423241d442fd052b2bc77091100ba06fd65dcf8d5 Attempting to boot anyway... entry 0x403cc710 I (43) boot: ESP-IDF v5.1-beta1-378-gea5e0ff298-dirt 2nd stage bootloader I (43) boot: compile time Jun 7 2023 07:59:10 I (44) boot: chip revision: v0.4 I (48) boot.esp32c3: SPI Speed : 40MHz I (53) boot.esp32c3: SPI Mode : DIO I (57) boot.esp32c3: SPI Flash Size : 4MB I (62) boot: Enabling RNG early entropy source... I (68) boot: Partition Table: I (71) boot: ## Label Usage Type ST Offset Length I (78) boot: 0 nvs WiFi data 01 02 00009000 00006000 I (86) boot: 1 phy_init RF data 01 01 0000f000 00001000 I (93) boot: 2 factory factory app 00 00 00010000 003f0000 I (101) boot: End of partition table I (105) esp_image: segment 0: paddr=00010020 vaddr=3c030020 size=05cb4h ( 23732) map I (119) esp_image: segment 1: paddr=00015cdc vaddr=40380000 size=00fa0h ( 4000) load I (123) esp_image: segment 2: paddr=00016c84 vaddr=00000000 size=09394h ( 37780) I (138) esp_image: segment 3: paddr=00020020 vaddr=42000020 size=21128h (135464) map I (169) boot: Loaded app from partition at offset 0x10000 I (169) boot: Disabling RNG early entropy source... Hello world!
ソースを微修正して走らせると、今回はいったん割り込みが発生したものの、どうにかしてリブートしたようである
cargo run --example blinky *略* [2023-11-05T10:10:42Z INFO ] Using flash stub Chip type: esp32c3 (revision v0.4) Crystal frequency: 40MHz Flash size: 4MB Features: WiFi, BLE MAC address: 34:85:18:00:b3:ac App/part. size: 201,120/4,128,768 bytes, 4.87% [00:00:00] [========================================] 13/13 0x0 [00:00:00] [========================================] 1/1 0x8000 [00:00:01] [========================================] 64/64 0x10000 [2023-11-05T10:10:45Z INFO ] Flashing has completed! Commands: CTRL+R Reset chip CTRL+C Exit ESP-ROM:esp32c3-api1-20210207 Build:Feb 7 2021 rst:0x15 (USB_UART_CHIP_RESET),boot:0xc (SPI_FAST_FLASH_BOOT) Saved PC:0x40380836 0x40380836 - esp_hal_common::interrupt::riscv::vectored::handle_interrupts at /home/sumi/.cargo/registry/src/index.crates.io-6f17d22bba15001f/esp-hal-common-0.12.0/src/interrupt/riscv.rs:214 SPIWP:0xee mode:DIO, clock div:2 load:0x3fcd5820,len:0x171c 0x3fcd5820 - _stack_start at ??:?? load:0x403cc710,len:0x968 0x403cc710 - at ??:?? load:0x403ce710,len:0x2f68 0x403ce710 - at ??:?? SHA-256 comparison failed: Calculated: 1d06b938c0222bf626e0bdf46178b1b37ab24d03f0360fc8fcf7153c2571deaf Expected: 68d7bdf643ba446b8ed7ae8423241d442fd052b2bc77091100ba06fd65dcf8d5 Attempting to boot anyway... entry 0x403cc710 0x403cc710 - at ??:?? I (43) boot: ESP-IDF v5.1-beta1-378-gea5e0ff298-dirt 2nd stage bootloader I (43) boot: compile time Jun 7 2023 07:59:10 I (44) boot: chip revision: v0.4 I (48) boot.esp32c3: SPI Speed : 40MHz I (53) boot.esp32c3: SPI Mode : DIO I (57) boot.esp32c3: SPI Flash Size : 4MB I (62) boot: Enabling RNG early entropy source... I (68) boot: Partition Table: I (71) boot: ## Label Usage Type ST Offset Length I (78) boot: 0 nvs WiFi data 01 02 00009000 00006000 I (86) boot: 1 phy_init RF data 01 01 0000f000 00001000 I (93) boot: 2 factory factory app 00 00 00010000 003f0000 I (101) boot: End of partition table I (105) esp_image: segment 0: paddr=00010020 vaddr=3c030020 size=05cc4h ( 23748) map I (119) esp_image: segment 1: paddr=00015cec vaddr=40380000 size=00fa0h ( 4000) load I (123) esp_image: segment 2: paddr=00016c94 vaddr=00000000 size=09384h ( 37764) I (138) esp_image: segment 3: paddr=00020020 vaddr=42000020 size=2115ch (135516) map I (169) boot: Loaded app from partition at offset 0x10000 I (169) boot: Disabling RNG early entropy source... Hello world! z.. z.. z.. z.. z.. z..
GPIOのL/Hが動いたということで、waitを外してどれぐらいの性能が出るのかを試した。結果、L/Hをループするのに9.2usで周波数で言うと、108.7KHz。これはさすがに遅すぎないか?システムクロックが落とされているから?
SystemClockが何MHzなのか知りたいところだが、、指定できるのはデフォルト40MHz固定らしい(ここから逓倍しているのか?)。ちょっとよく分からず。SystemClockは仕様通りと期待して、最適化オプションを期待してビルドしてみる。以下でビルド
cargo build --release
target/riscv32imc-unknown-none-elf/release配下にblinkのバイナリが生成されるのでこれを焼いてみる。ループの周期を計測すると、580nsで周波数で言うと、1.72MHzであった。40MHzで動いていたとしたら1/40なのでまぁそんなものですか・・・という感じだが、最高速の120MHzで動いていたらかなり遅い。オーバーヘッドがでかすぎる。まぁそんなに速度を求めるならハードでLHしろよとか、周辺I/Oレジスタを直接叩いたらええやんと言われそうですが・・ コンパイル型言語ならではの速度が出ていて欲しかったという希望なのでした。
元々は、MEMS マイクのPDMの出力を取りこぼさずに全部受け取るというためだったので、、1.72MHzでも仕様範囲内ではある。
■参考URL
USB デバイスを接続する | Microsoft Learn
ClockControl in esp32h2_hal::clock - Rust