背景:LinuxのホストOSにRustビルド環境を入れたが、インストール手順が試行錯誤で、正しく入ったのかあやうい
取り組み:インストール手順をDockerファイルに定義してDocker内に組み込みRust開発環境を作る
進捗:イメージまではだいたいできた。コンテナ内で作業すればビルドはできる。一方、cargo build等、ホスト環境からコマンドを実行するようにDockerコンテナを起動してビルドするレベルまでは仕上がっていない。
詳細は以下:
前回はDockerを使ってコンテナ内に組み込みRust用ビルド環境を途中まで構築した
()
これからやるべきこと
The Rust on ESP Bookの、RISC-V targets only を参照
rustup toolchain install nightly --component rust-src // 前回はここまで終わっている
LLVMを入れる (apt install clang)
std用開発環境を入れる ( python, git , ldproxy (cargo install ldproxy))
前回途中まで作ったDockerfileに対して、残りの、cargo-generateやespflash等を追加
file: Dockerfile
FROM debian:bullseye-slim RUN apt-get update \ && apt-get install --yes curl \ && curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs > /tmp/rustup-init.sh \ && chmod +x /tmp/rustup-init.sh \ && /tmp/rustup-init.sh -y \ && . "$HOME/.cargo/env" \ && rm /tmp/rustup-init.sh RUN apt-get install --yes clang python3 python3-pip git pkg-config libudev-dev libssl-dev \ && python3 -m pip install pip --upgrade RUN . "$HOME/.cargo/env" \ && rustup toolchain install nightly-2023-02-28 --component rust-src \ && cargo install ldproxy \ && cargo install cargo-generate \ && cargo install espflash \ && cargo install cargo-espflash
イメージをビルドしてみる
sudo docker build -t rust_buld_rustup_cargogen:0.1 .
今回はイメージをビルドするのに20分近くかかった。
[+] Building 1177.1s (8/8) FINISHED
コンテナに入って何かするような使い方は想定していないが、テストのために入ってビルドしてみる
sudo docker run -it rust_buld_rustup_cargogen:0.1 /bin/bash
root@176a8cc24824:/app# cargo generate --git https://github.com/esp-rs/esp-idf-template cargo Error: could not determine the current user, please set $USER root@176a8cc24824:/app# export USER=root root@176a8cc24824:/app# cargo generate --git https://github.com/esp-rs/esp-idf-template cargo Project Name: hello Destination: /app/hello ... project-name: hello ... Generating template ... ✔ Which MCU to target? · esp32c3 ✔ Configure advanced template options? · false Moving generated files into: `/app/hello`... Initializing a fresh Git repository Done! New project created /app/hello root@176a8cc24824:/app# cd hello/ root@176a8cc24824:/app/hello# cargo build
これは何だったか忘れたがビルドはできた
Finished dev [optimized + debuginfo] target(s) in 6m 43s
root@176a8cc24824:/app/hello/target/riscv32imc-esp-espidf/debug# ls -ltrh total 18M drwxr-xr-x 2 root root 4.0K Jul 8 23:24 examples drwxr-xr-x 16 root root 4.0K Jul 8 23:24 build drwxr-xr-x 3 root root 4.0K Jul 8 23:31 incremental -rwxr-xr-x 2 root root 18M Jul 8 23:31 hello drwxr-xr-x 2 root root 12K Jul 8 23:31 deps -rw-r--r-- 1 root root 96 Jul 8 23:31 hello.d
素のhello worldであった
use esp_idf_sys as _; // If using the `binstart` feature of `esp-idf-sys`, always keep this module imported use log::*; fn main() { // It is necessary to call this function once. Otherwise some patches to the runtime // implemented by esp-idf-sys might not link properly. See https://github.com/esp-rs/esp-idf-template/issues/71 esp_idf_sys::link_patches(); // Bind the log crate to the ESP Logging facilities esp_idf_svc::log::EspLogger::initialize_default(); info!("Hello, world!"); }
espflashを使ってFlashに焼いてみる
root@176a8cc24824:/app/hello# cargo run Finished dev [optimized + debuginfo] target(s) in 0.14s Running `espflash flash --monitor target/riscv32imc-esp-espidf/debug/hello` ✔ Use serial port '/dev/ttyACM0'? · yes [2023-07-08T23:47:57Z INFO ] Serial port: '/dev/ttyACM0' [2023-07-08T23:47:57Z INFO ] Connecting... Error: espflash::connection_failed x Failed to open serial port /dev/ttyACM0 |-> Failed to open serial port /dev/ttyACM0 |-> Error while connecting to device `-> Serial port not found help: Ensure that the device is connected and your host recognizes the serial adapter
エラーになった。これは、コンテナ側から、/dev/ttyACM0が見えてないせいと思われる。
先人の記事より、docker起動時に以下を指定するらしい(感謝:XPT60様)
--device=/dev/<port_on_host>:/dev/<port_on_container>
だいたいこれで作ったイメージはビルドに使えそうだということで、、ストレージ外だし化に取り組む。
マウントポイント?用に/appを加える(これがDocker的に標準作法なのかどうかわからず)
FROM debian:bullseye-slim RUN apt-get update \ && apt-get install --yes curl \ && curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs > /tmp/rustup-init.sh \ && chmod +x /tmp/rustup-init.sh \ && /tmp/rustup-init.sh -y \ && . "$HOME/.cargo/env" \ && rm /tmp/rustup-init.sh RUN apt-get install --yes clang python3 python3-pip git pkg-config libudev-dev libssl-dev \ && python3 -m pip install pip --upgrade RUN . "$HOME/.cargo/env" \ && rustup toolchain install nightly-2023-02-28 --component rust-src \ && cargo install ldproxy \ && cargo install cargo-generate \ && cargo install espflash \ && cargo install cargo-espflash RUN mkdir /app
sudo docker run --volume /home/rustbld00/lang/rust:/app --device=/dev/ttyACM0:/dev/ttyACM0 -it rust_buld_rustup_cargogen_app:0.1 /bin/bash
まだ起動ー>自動でビルドまで到達できていないので(最終形態とは異なりながら)コンテナに入って作業してみる
cd /app export USER=root cargo generate --git https://github.com/esp-rs/esp-idf-template cargo cd hello-world/ cargo run
cargo runでは設定が足りないのか焼き終わる所まで自動で進まなかったので、flash writeを手で起動
root@6862ab193237:/app/hello-world# espflash flash target/riscv32imc-esp-espidf/debug/hello-world ✔ Use serial port '/dev/ttyACM0'? · yes [2023-07-09T00:18:40Z INFO ] Serial port: '/dev/ttyACM0' [2023-07-09T00:18:40Z INFO ] Connecting... [2023-07-09T00:18:40Z 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:xx App/part. size: 484,864/4,128,768 bytes, 11.74% [00:00:00] [========================================] 13/13 0x0 [00:00:00] [========================================] 1/1 0x8000 [00:00:04] [========================================] 241/241 0x10000 [2023-07-09T00:18:45Z INFO ] Flashing has completed!
root@6862ab193237:/app/hello-world# espflash monitor ✔ Use serial port '/dev/ttyACM0'? · yes [2023-07-09T00:20:35Z INFO ] Serial port: '/dev/ttyACM0' [2023-07-09T00:20:35Z INFO ] Connecting... [2023-07-09T00:20:35Z INFO ] Using flash stub Commands: CTRL+R Reset chip CTRL+C Exit
もうすでに起動が終わってるからメッセージもなし?
ストレージを外部に置いているので、コンテナが終了してもビルドしたファイル一式はホスト側に残っている。
rustbld00@MBP01:~/lang/rust/hello-world$ pwd /home/rustbld00/lang/rust/hello-world rustbld00@MBP01:~/lang/rust/hello-world$ ls build.rs Cargo.lock Cargo.toml rust-toolchain.toml sdkconfig.defaults src target
シリアル出力が取得できず、動ているのかどうかわからないのでLEDを点滅させてみた
root@6862ab193237:/app/hello-world# cat src/main.rs // If using the `binstart` feature of `esp-idf-sys`, always keep this module imported use esp_idf_sys as _; use log::*; use esp_idf_hal::delay::FreeRtos; use esp_idf_hal::gpio::*; use esp_idf_hal::peripherals::Peripherals; use anyhow::Result; fn main() -> Result<()> { esp_idf_sys::link_patches(); esp_idf_svc::log::EspLogger::initialize_default(); info!("Hello, world!"); println!("##### blink test ###"); let peripherals = Peripherals::take().unwrap(); let mut led = PinDriver::output(peripherals.pins.gpio7)?; let mut counter = 0; loop{ counter += 1; println!("zzz...\n"); FreeRtos::delay_ms(1000); info!("Hello, world!\n"); println!("blink...\n"); if counter %2 == 0 { led.set_high()?; } else { led.set_low()?; } } }
LED点滅はできたが、シリアルコンソールに確認文字列が表示されない
Windows上で動作するTereTermから接続すると以下と表示された。プログラムとボードは正常に動作していて、受信側の問題と分かった。デバイス指定等がおかしいのかも
I (26384) hello_world: Hello, world! blink... zzz... I (27384) hello_world: Hello, world! blink... zzz...
Ubuntu側で再度テスト、ホストOS側で、espflash serial-monitor を実行すると正しくシリアルデータを受信できた。
ただ、このバージョンは古くなってると思われる。(コマンドオプションも変わっているし・・)
rustbld00@MBP01:~$ espflash serial-monitor /dev/ttyACM0 New version of espflash is available: v2.0.0 Serial port: /dev/ttyACM0 Connecting... 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:0x4004c51e 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=3c060020 size=20708h (132872) map I (143) esp_image: segment 1: paddr=00030730 vaddr=3fc8a000 size=00d08h ( 3336) load I (144) esp_image: segment 2: paddr=00031440 vaddr=40380000 size=09ef0h ( 40688) load I (158) esp_image: segment 3: paddr=0003b338 vaddr=00000000 size=04ce0h ( 19680) I (163) esp_image: segment 4: paddr=00040020 vaddr=42000020 size=50048h (327752) map I (240) boot: Loaded app from partition at offset 0x10000 I (240) boot: Disabling RNG early entropy source... I (251) cpu_start: Pro cpu up. I (260) cpu_start: Pro cpu start user code I (261) cpu_start: cpu freq: 160000000 I (261) cpu_start: Application information: I (263) cpu_start: Project name: libespidf I (268) cpu_start: App version: 1 I (273) cpu_start: Compile time: Jul 9 2023 00:12:46 I (279) cpu_start: ELF file SHA256: 0000000000000000... I (285) cpu_start: ESP-IDF: 8b94183-dirty I (290) cpu_start: Min chip rev: v0.3 I (295) cpu_start: Max chip rev: v0.99 I (300) cpu_start: Chip rev: v0.4 I (305) heap_init: Initializing. RAM available for dynamic allocation: I (312) heap_init: At 3FC8BCC0 len 00050A50 (322 KiB): DRAM I (318) heap_init: At 3FCDC710 len 00002950 (10 KiB): STACK/DRAM I (325) heap_init: At 50000020 len 00001FE0 (7 KiB): RTCRAM I (332) spi_flash: detected chip: generic I (336) spi_flash: flash io: dio I (341) sleep: Configure to isolate all GPIO pins in sleep state I (346) sleep: Enable automatic switching of GPIO sleep configuration I (354) cpu_start: Starting scheduler. I (360) hello_world: Hello, world! ##### blink test ### I (360) gpio: GPIO[7]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 zzz... I (1370) hello_world: Hello, world! blink... zzz... I (2370) hello_world: Hello, world! blink... zzz...
ホスト側のバージョンは、1.7.0で最新は2.0.0と表示されている
rustbld00@MBP01:~$ espflash --version New version of espflash is available: v2.0.0 espflash 1.7.0
Setting Up a Development Environment - The Rust on ESP Book
Setting Up a Development Environment - The Rust on ESP Book
Rust開発環境 on Docker で Cargo new で "could not determine the current user, please set $USER" エラー - tyamaguc07's hatenablog
【docker】シリアルポートからデータを読む (u-blox 受信機) - Qiita