WSLにRustを入れる。普通にWSLに入れても途中でエラーになるので、逃げの手として、VMware上のUbuntuにRustを入れて、Rustが入ったディレクトリをtarで固めてWSL上のUbuntuにコピーする。
以下のコマンドは問題なく実行完了
rustup target add thumbv7em-none-eabi rustup target add thumbv7m-none-eabi cargo install cargo-binutils rustup component add llvm-tools-preview
cargo-generateを入れる際にopensslがないと怒られるので対応(WSLで経験済み)。
$ cargo install cargo-generate Compiling regex-syntax v0.5.6 Compiling miniz_oxide v0.3.6 error: failed to compile `cargo-generate v0.5.0`, intermediate artifacts can be found at `/tmp/cargo-install58HEg8` Caused by: failed to run custom build command for `openssl-sys v0.9.55` Caused by: process didn't exit successfully: `/tmp/cargo-install58HEg8/release/build/openssl-sys-f3f76be6d73ab789/build-script-main` (exit code: 101) --- stdout cargo:rustc-cfg=const_fn cargo:rerun-if-env-changed=X86_64_UNKNOWN_LINUX_GNU_OPENSSL_LIB_DIR X86_64_UNKNOWN_LINUX_GNU_OPENSSL_LIB_DIR unset cargo:rerun-if-env-changed=OPENSSL_LIB_DIR OPENSSL_LIB_DIR unset cargo:rerun-if-env-changed=X86_64_UNKNOWN_LINUX_GNU_OPENSSL_INCLUDE_DIR X86_64_UNKNOWN_LINUX_GNU_OPENSSL_INCLUDE_DIR unset cargo:rerun-if-env-changed=OPENSSL_INCLUDE_DIR OPENSSL_INCLUDE_DIR unset cargo:rerun-if-env-changed=X86_64_UNKNOWN_LINUX_GNU_OPENSSL_DIR X86_64_UNKNOWN_LINUX_GNU_OPENSSL_DIR unset cargo:rerun-if-env-changed=OPENSSL_DIR OPENSSL_DIR unset run pkg_config fail: "Failed to run `\"pkg-config\" \"--libs\" \"--cflags\" \"openssl\"`: No such file or directory (os error 2)" --- stderr thread 'main' panicked at ' Could not find directory of OpenSSL installation, and this `-sys` crate cannot proceed without this knowledge. If OpenSSL is installed and this crate had trouble finding it, you can set the `OPENSSL_DIR` environment variable for the compilation process. Make sure you also have the development packages of openssl installed. For example, `libssl-dev` on Ubuntu or `openssl-devel` on Fedora. If you're in a situation where you think the directory *should* be found automatically, please open a bug at https://github.com/sfackler/rust-openssl and include information about your system as well as this message. $HOST = x86_64-unknown-linux-gnu $TARGET = x86_64-unknown-linux-gnu openssl-sys = 0.9.55 It looks like you're compiling on Linux and also targeting Linux. Currently this requires the `pkg-config` utility to find OpenSSL but unfortunately `pkg-config` could not be found. If you have OpenSSL installed you can likely fix this by installing `pkg-config`. ', /home/xxxx/.cargo/registry/src/github.com-1ecc6299db9ec823/openssl-sys-0.9.55/build/find_normal.rs:155:5 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
$ pkg-config Command 'pkg-config' not found, but can be installed with: sudo apt install pkg-config sudo apt install pkgconf $ sudo apt install pkg-config $ pkg-config --libs --cflags openssl Package openssl was not found in the pkg-config search path. Perhaps you should add the directory containing `openssl.pc' to the PKG_CONFIG_PATH environment variable No package 'openssl' found
opensslが見つからないと言ってるので、libssl-devをインストール
$ sudo apt-get install libssl-dev $ pkg-config --libs --cflags openssl -lssl -lcrypto
再度、cargo-generateをインストール、ビルドが正常に終了
cargo install cargo-generate
cortex-m-quickstartを落としてRustでビルドしてみる。。正常に終了
cd ~/lang/rust cargo generate --git https://github.com/rust-embedded/cortex-m-quickstart.git cd cortex-m-quickstart/ cargo build --example hello
Rust版のBluePill用LチカをGitHubから落としてビルドしてみる
git clone https://github.com/lupyuen/stm32-blue-pill-rust.git cd stm32-blue-pill-rust.git cargo build
panic関連でビルドエラー(これはWindows版でも出ていた)
$ cargo build Updating crates.io index Updating git repository `https://github.com/japaric/stm32f103xx` Updating git repository `https://github.com/japaric/stm32f103xx-hal` Downloaded void v1.0.2 Downloaded embedded-hal v0.2.3 Downloaded nb v0.1.2 *略* Compiling cortex-m-rt v0.5.7 Compiling panic-semihosting v0.3.0 error[E0557]: feature has been removed --> /home/<UserName>/.cargo/registry/src/github.com-1ecc6299db9ec823/panic-semihosting-0.3.0/src/lib.rs:59:12 | 59 | #![feature(panic_implementation)] | ^^^^^^^^^^^^^^^^^^^^ feature has been removed | = note: subsumed by `#[panic_handler]` error: cannot find attribute `panic_implementation` in this scope --> /home/<UserName>/.cargo/registry/src/github.com-1ecc6299db9ec823/panic-semihosting-0.3.0/src/lib.rs:71:3 | 71 | #[panic_implementation] | ^^^^^^^^^^^^^^^^^^^^ error[E0554]: `#![feature]` may not be used on the stable release channel --> /home/<UserName>/.cargo/registry/src/github.com-1ecc6299db9ec823/panic-semihosting-0.3.0/src/lib.rs:59:1 | 59 | #![feature(panic_implementation)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 3 previous errors Some errors have detailed explanations: E0554, E0557. For more information about an error, try `rustc --explain E0554`. error: could not compile `panic-semihosting`. To learn more, run the command again with --verbose.
エラーメッセージから解釈すると、なくなったfeatureを使い続けているためのエラーのようだ。
error[E0557]: feature has been removed
パッケージ?のビルドでエラーが出ているが、Rustのコマンド類は正常に動いていると判断して、、VMware環境のUbuntuで作ったRust用ツール一式をtarで固めて、Ubuntu on WSLにコピーした。
tar cvfz rust.tgz .rustup .cargo
VMWareからコピーしてきたRust環境(on WSL)でbulePill用サンプルをビルドしてみる
GitHub - lupyuen/stm32-blue-pill-rust: Rust for STM32 Blue Pill with Visual Studio Code
cargo clean cargo check --release cargo build --release
先日前に遭遇した、panic_implementationのエラーが発生(VMware版Ubuntu上のRustでも発生)
Checking panic-semihosting v0.3.0 error[E0557]: feature has been removed --> /home/<UserName>/.cargo/registry/src/github.com-1ecc6299db9ec823/panic-semihosting-0.3.0/src/lib.rs:59:12 | 59 | #![feature(panic_implementation)] | ^^^^^^^^^^^^^^^^^^^^ feature has been removed | = note: subsumed by `#[panic_handler]` error: cannot find attribute `panic_implementation` in this scope --> /home/<UserName>/.cargo/registry/src/github.com-1ecc6299db9ec823/panic-semihosting-0.3.0/src/lib.rs:71:3 | 71 | #[panic_implementation] | ^^^^^^^^^^^^^^^^^^^^ error[E0554]: `#![feature]` may not be used on the stable release channel --> /home/<UserName>/.cargo/registry/src/github.com-1ecc6299db9ec823/panic-semihosting-0.3.0/src/lib.rs:59:1 | 59 | #![feature(panic_implementation)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 3 previous errors Some errors have detailed explanations: E0554, E0557. For more information about an error, try `rustc --explain E0554`. error: could not compile `panic-semihosting`. To learn more, run the command again with --verbose. warning: build failed, waiting for other jobs to finish... error: build failed
噴飯モノ回避策:
file:/home/<UserName>/.cargo/registry/src/github.com-1ecc6299db9ec823/panic-semihosting-0.3.0/src/lib.rs
の内容を、
https://github.com/rust-embedded/panic-semihosting/blob/master/src/lib.rs
で置き換え
ちなみに、、panic semihostingってのは、バイナリ実行時にpanicが発生した場合、panic要因をデバッグ環境に出力する機能らしい。開発向けの補助機能なんが。。手こずる。
やっと本体のコンパイルに入り、過去に遭遇した、deprecatedが出る(過去、Rust on Windows環境と同じ症状、ワークアラウンドで回避ずみ)
error: use of deprecated item 'bluepill_hal::prelude::_embedded_hal_digital_OutputPin::set_high': Deprecated because the methods cannot return errors. Users should use the traits in digital::v2. --> src/main.rs:52:13 | 52 | led.set_high(); | ^^^^^^^^ | note: the lint level is defined here --> src/main.rs:4:9 | 4 | #![deny(warnings)] // If the Rust compiler generates a warning, stop the compilation with an error. | ^^^^^^^^ = note: `#[deny(deprecated)]` implied by `#[deny(warnings)]` error: use of deprecated item 'bluepill_hal::prelude::_embedded_hal_digital_OutputPin::set_low': Deprecated because the methods cannot return errors. Users should use the traits in digital::v2. --> src/main.rs:59:13 | 59 | led.set_low(); | ^^^^^^^ error: aborting due to 2 previous errors error: could not compile `stm32-blue-pill-rust`. To learn more, run the command again with --verbose.
src/main.rsの設定を変更(逃げの一手。。言語仕様に詳しければ正しい回避策を取るけど、仕様詳細わからないので、コンパイルを通すのを優先)
//#![deny(warnings)] // If the Rust compiler generates a warning, stop the compilation with an error.
再度ビルドをやり直すが、次のエラーに遭遇
cargo build --release *略* = note: rust-lld: error: unknown argument '-nostartfiles' rust-lld: error: unknown argument '-Wl,-Tlink.x' error: aborting due to previous error error: could not compile `stm32-blue-pill-rust`.
このエラーもWindows版Rustで経験済み、file: .cargo/config の定義を修正
"-C", "link-arg=-Tlink.x", # CHANGED
最終的にBulePill版Lチカサンプルがビルドできた
$ ls -l target/thumbv7m-none-eabi/release/stm32-blue-pill-rust -rwxrwxrwx 2 xxx xxx 173704 Apr 30 11:34 target/thumbv7m-none-eabi/release/stm32-blue-pill-rust* $ file target/thumbv7m-none-eabi/release/stm32-blue-pill-rust target/thumbv7m-none-eabi/release/stm32-blue-pill-rust: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, with debug_info, not stripped
これまでRustの開発環境は以下の3種類作った
Windows環境でRust開発環境を作った際も、素のUbuntuで作った際も同じようなエラーに出くわした。結果、Linuxだからといってパッケージの整合性が高いというわけではないと思った。(確かに、パッケージは非OS依存だから、当然といえば当然なのかも)
今後の取り組み・・
WSL環境でRustを構築するとすんなりビルドできるかと思ったが、Windows環境での構築とほとんど同じであった。ゆえにWSL環境ではRust使わず、普通のWindows10環境のRustを使うことにする。
これまで動かすことが最優先で、出くわす問題に対して場当たり的に対策を講じてきた。仕様のこととか、パッケージ?の管理とか、全く理解できていない。理解のためできるだけスクラッチで動かす。Interface誌でスタートアップ、リンカスクリプトもスクラッチで書く方法が解説されているので、それを打ち込みながら、自力でStartUp->ハード初期化->LEDチカのプログラムを組む予定。
memo
linker.ld抜粋
MEMORY { FLASH : ORIGIN = 0x08000000, LENGTH = 64K RAM : ORIGIN = 0x20000000, LENGTH = 20K }
逆アセンブルした結果
cargo objdump --bin bluepill_blink --target thumbv7m-none-eabi -- -d --no-show-raw-insn -print-imm-hex Finished dev [unoptimized + debuginfo] target(s) in 0.02s bluepill_blink: file format ELF32-arm-little Disassembly of section .text: 08000008 reset: 8000008: sub sp, #0xc 800000a: mov.w r0, #0x518 800000e: str r0, [sp, #0x8] 8000010: movs r1, #0x8 8000012: str r1, [sp] 8000014: movs r1, #0x0 8000016: strb.w r1, [sp, #0x4] 800001a: ldr r1, [sp] 800001c: str r1, [r0] 800001e: b #-0x2 <reset+0x18> 8000020: b #-0x4 <reset+0x18>
ビルドしたバイナリを逆アセンブル
$ /usr/local/GNUToolsARMEmbedded/4.8_2013q4/bin/arm-none-eabi-objdump.exe -d bluepill_blink bluepill_blink: file format elf32-littlearm Disassembly of section .text: 08000008 <reset>: 8000008: f44f 60a3 mov.w r0, #1304 ; 0x518 800000c: 2108 movs r1, #8 800000e: 6001 str r1, [r0, #0] 8000010: e7fe b.n 8000010 <reset+0x8> $ /usr/local/GNUToolsARMEmbedded/4.8_2013q4/bin/arm-none-eabi-objcopy.exe -O binary bluepill_blink bluepill_blink.bin $ od -t x1 bluepill_blink.bin 0000000 00 50 00 20 09 00 00 08 4f f4 a3 60 08 21 01 60 0000020 fe e7 stack:2000 5000 Vector:0800 0009 .text f44f 60a3 2108 6001 e7fe
リセットベクターが08000008ではなくて、08000009と奇数になっているのだが、、これはこれでいいのか!?
OpenOCD + gdbでデバッグしてみる
(cd /usr/local/openocd-0.10.0/; ./bin-x64/openocd -f ./scripts/interface/stlink-v2.cfg -f ./scripts/target/stm32f1x.cfg) /usr/local/GNUToolsARMEmbedded/4.8_2013q4/bin/arm-none-eabi-gdb.exe target/thumbv7m-none-eabi/debug/bluepill_blink (gdb) target extended-remote:3333 (gdb) mon reset halt (gdb) b reset (gdb) load (gdb) run
BluePill用のLチカプログラム(gdbで動かす分にはOKだが)
#![no_std] #![no_main] const GPIOC : usize = 0x40011000; const GPIO_BSRR_OFFSET : usize = 0x10; const GPIO_BRR_OFFSET : usize = 0x14; const GPIOC_8: u32 = 8; const GPIOC_13: u32 = 13; const RCC_BASE : usize = 0x40021000; const RCC_OFFSET: usize = 0x18; const OUT10MH: u32 = 0x01 ; const CNF13_GENPP: u32 = 0x00000000; const MODE13_OUT10MH :u32 = OUT10MH << ((GPIOC_13 - GPIOC_8) *4); #[link_section = ".vector_table.reset_vector"] #[no_mangle] pub static RESET_VECTOR: extern "C" fn() ->! = reset; #[no_mangle] pub extern "C" fn reset() -> ! { // Enable Clock let mut reg_ptr = (RCC_BASE + RCC_OFFSET) as *mut u32; unsafe { *reg_ptr = 0x01 << 4 } // set GPIOC_13 as OUTPUT reg_ptr = (GPIOC + 0x04) as *mut u32; unsafe { *reg_ptr = CNF13_GENPP | MODE13_OUT10MH; } loop { reg_ptr = (GPIOC + GPIO_BRR_OFFSET) as *mut u32; unsafe { *reg_ptr = 1 << GPIOC_13; } wait(); reg_ptr = (GPIOC + GPIO_BSRR_OFFSET) as *mut u32; unsafe { *reg_ptr = 1 << GPIOC_13; } wait(); } } fn wait(){ let mut counter = 0; let mut i; while counter < 100 { counter += 1; i = 0; while i < 1000 { i += 1; } } } use core::panic::PanicInfo; #[panic_handler] fn panic(_info: &PanicInfo) -> ! { loop {} }
linker.ldの内容(Interfaceより引用)
MEMORY { FLASH : ORIGIN = 0x08000000, LENGTH = 64K RAM : ORIGIN = 0x20000000, LENGTH = 20K } ENTRY(reset); EXTERN(RESET_VECTOR); SECTIONS { .vector_table ORIGIN(FLASH) : { LONG(ORIGIN(RAM) + LENGTH(RAM)); KEEP(*(.vector_table.reset_vector)); } > FLASH .text : { *(.text .text.*); } > FLASH .rodata : { *(.rodata .rodata.*); *(.data.rel.ro); } > FLASH /DISCARD/ : { *(.ARM.exidx .ARM.exidx.*); } }
release版をBulePillのFlashに焼いてみた
/usr/local/GNUToolsARMEmbedded/4.8_2013q4/bin/arm-none-eabi-objcopy.exe -O binary bluepill_blink bluepill_blink.bin cd ./target/thumbv7m-none-eabi/release $ od -t x1 bluepill_blink.bin 0000000 00 50 00 20 09 00 00 08 41 f2 18 00 10 21 c4 f2 0000020 02 00 01 60 41 f2 04 00 c4 f2 01 00 4f f4 80 11 0000040 01 60 4f f4 00 51 c0 e9 03 11 fc e7 $ pwd ~/tech/arm/stm32/stlink $ ./st-flash.exe write ~/lang/rust/bluepill_blink/target/thumbv7m-none-eabi/release/bluepill_blink.bin 0x08000000 st-flash 1.3.1 2020-04-30T19:28:39 INFO src/common.c: Loading device parameters.... 2020-04-30T19:28:39 INFO src/common.c: Device connected is: F1 Medium-density device, id 0x20036410 2020-04-30T19:28:39 INFO src/common.c: SRAM size: 0x5000 bytes (20 KiB), Flash: 0x10000 bytes (64 KiB) in pages of 1024 bytes 2020-04-30T19:28:39 INFO src/common.c: Attempting to write 44 (0x2c) bytes to stm32 address: 134217728 (0x8000000) Flash page at addr: 0x08000000 erased 2020-04-30T19:28:39 INFO src/common.c: Finished erasing 1 pages of 1024 (0x400) bytes 2020-04-30T19:28:39 INFO src/common.c: Starting Flash write for VL/F0/F3 core id 2020-04-30T19:28:39 INFO src/flash_loader.c: Successfully loaded flash loader in sram 0/0 pages written 2020-04-30T19:28:39 INFO src/common.c: Starting verification of write complete 2020-04-30T19:28:39 INFO src/common.c: Flash written and verified! jolly good!
LEDが点灯はするが点滅はしない。。なぜか? 待ちループが最適化により削除された??
debug版を入れると点滅した。最適化の影響か、それとも、作り間違っているか。。
Release版のバイナリを逆アセンブルすると以下となっており、ウエイトの2重ループが無いような。。
$ /usr/local/GNUToolsARMEmbedded/4.8_2013q4/bin/arm-none-eabi-objdump.exe -d bluepill_blink bluepill_blink: file format elf32-littlearm Disassembly of section .text: 08000008 <reset>: 8000008: f241 0018 movw r0, #4120 ; 0x1018 800000c: 2110 movs r1, #16 800000e: f2c4 0002 movt r0, #16386 ; 0x4002 8000012: 6001 str r1, [r0, #0] 8000014: f241 0004 movw r0, #4100 ; 0x1004 8000018: f2c4 0001 movt r0, #16385 ; 0x4001 800001c: f44f 1180 mov.w r1, #1048576 ; 0x100000 8000020: 6001 str r1, [r0, #0] 8000022: f44f 5100 mov.w r1, #8192 ; 0x2000 8000026: e9c0 1103 strd r1, r1, [r0, #12] 800002a: e7fc b.n 8000026 <reset+0x1e>
■ご参考URL
RustでBluepillのLEDを点滅記事
Rust on STM32: Blinking an LED - Stackenbloggen
Home | Rustの日本語ドキュメント/Japanese Docs for Rust
まえがき - The Rust Programming Language
導入 - The Embedded Rust Book
ARM Cortex-M 32ビットマイコンでベアメタル "Safe" Rust - Qiita
rust で組み込み(Cortex-M3) – GitHub 出張所 – プログラム関係のブログはここに
ようこそ Japaric Park へ – GitHub 出張所 – プログラム関係のブログはここに