結論:
- WSL環境でArm用バイナリのビルドは可能(ここまでは予想通り)
- gdbでデバッグする際、OpenOCDとST-Linkに接続するのはデバイス仮想化の影響によるのか正常に動作しない。ワークアラウンドとして、Windows環境でOpenOCDを走らせて、WSLからはポートで接続する
- st-link tool (st-flash等)も正常に動作しない。ファームを焼くのはOpenOCDのtelnetで行う
詳細:
これまではWindows上にArm開発環境を構築してどうにかこうにかビルドしていたが、、実際はCygwinから使っており、どうも場当たり的でたまたま動いている観が強い。標準インストール手順はLinuxで紹介されていることも多いのだが、VMWare等の仮想環境にUbuntuを入れて作業するのも結構手間だった。幸い、Windows環境にはWSL(Windows Subsystem for Linux)が提供されていて、WIndows環境で下位レイヤーが仮想化されており、軽くUbuntu等を走らせてLinuxのパッケージも使えるとのことで、WSL上にUbuntuを走らせてArm環境をいれてみることにした。
Arm用ビルド環境
developer.arm.comから Arm用クロスコンパイラをDL
https://developer.arm.com/tools-and-software/open-source-software
https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads
Arm用コンパイルはいけそうだが、、WSL環境でOpenOCDはエラーになる
$ openocd -f stlink-v2.cfg -f ./stm32f1x.cfg Open On-Chip Debugger 0.10.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 adapter speed: 1000 kHz adapter_nsrst_delay: 100 none separate Info : Unable to match requested speed 1000 kHz, using 950 kHz Info : Unable to match requested speed 1000 kHz, using 950 kHz Info : clock speed 950 kHz Error: open failed in procedure 'init' in procedure 'ocd_bouncer'
st-linkツール類も動作しない。USB経由でst-linkが見えない。デバイス仮想化と、usblibあたりがうまくいっていないのかも。
本来はWSL上のUbuntuで完結させたいけど、デバイスレイヤー仮想化の影響をどう回避したらいいのか詳細わかっておらず。。逃げの手として、物理デバイスを操作するアプリ(OpenOCD)はWIndows環境で走らせて、gdbはWSL上で走らせる手がある。
gdbを起動するとライブラリ(libcurses)がないと言われる
$ /usr/local/gcc-arm-none-eabi-9-2019-q4-major/bin/arm-none-eabi-gdb /usr/local/gcc-arm-none-eabi-9-2019-q4-major/bin/arm-none-eabi-gdb: error while loading shared libraries: libncurses.so.5: cannot open shared object file: No such file or directory
libcursesを入れる
$ apt-cache search libncurses libncurses-dev - developer's libraries for ncurses libncurses5-dev - transitional package for libncurses-dev libncurses6 - shared libraries for terminal handling libncursesw5-dev - transitional package for libncurses-dev libncursesw6 - shared libraries for terminal handling (wide character support) libtinfo-dev - transitional package for libncurses-dev libncurses-gst - Ncurses bindings for GNU Smalltalk libncurses5 - shared libraries for terminal handling (legacy version) libncursesada-doc - Ada binding to the ncurses text interface library: documentation libncursesada6.2.20180127.1 - Ada binding to the ncurses text interface library: shared library libncursesada7-dev - Ada binding to the ncurses text interface library: development libncursesw5 - shared libraries $ sudo apt-get install libncurses5
デバッグ環境を動かしてみる。まず、Windows側でOpenOCDを走らせる
(cd /usr/local/openocd-0.10.0/; ./bin-x64/openocd -f ./scripts/interface/stlink-v2.cfg -f ./scripts/target/stm32f1x.cfg)
WSLでgdbを走らせる。以下はWSLのUbuntu上でgdbを起動した例。動いた。
$ /usr/local/gcc-arm-none-eabi-9-2019-q4-major/bin/arm-none-eabi-gdb miniblink.elf GNU gdb (GNU Tools for Arm Embedded Processors 9-2019-q4-major) 8.3.0.20190709-git Copyright (C) 2019 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "--host=x86_64-linux-gnu --target=arm-none-eabi". Type "show configuration" for configuration details. For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>. Find the GDB manual and other documentation resources online at: <http://www.gnu.org/software/gdb/documentation/>. For help, type "help". Type "apropos word" to search for commands related to "word"... Reading symbols from miniblink.elf... (gdb) target extended-remote:3333 Remote debugging using :3333 reset_handler () at ../../cm3/vector.c:67 67 for (src = &_data_loadaddr, dest = &_data; (gdb) mon reset halt target halted due to debug-request, current mode: Thread xPSR: 0x01000000 pc: 0x08000224 msp: 0x20005000, semihosting (gdb) load Loading section .text, size 0x2b0 lma 0x8000000 Start address 0x8000224, load size 688 Transfer rate: 3 KB/sec, 688 bytes/write. (gdb) b main Breakpoint 1 at 0x8000150: file miniblink.c, line 37. (gdb) run The program being debugged has been started already. Start it from the beginning? (y or n) y Starting program: /home/xxxx/stm32/miniblink/miniblink.elf Note: automatically using hardware breakpoints for read-only addresses. Breakpoint 1, main () at miniblink.c:37 37 gpio_setup(); (gdb) l 32 33 int 34 main(void) { 35 int i; 36 37 gpio_setup(); 38 39 for (;;) { 40 gpio_clear(GPIOC,GPIO13); /* LED on */ 41 for (i = 0; i < 1500000; i++) /* Wait a bit. */ (gdb)
OpenOCDではファームを焼く機能もある。OpenOCDにターミナルソフトから接続すると以下の手順でファームが焼ける
$ telnet localhost 4444 > reset halt > flash write_image erase ${elf_file_absolute_path}
WSLからでも、telnet localhost 4444でOpenOCDに接続できるので、バッチで操作できればファームを焼くのも可能。
■参考URL
以下のブログのように、wslでopneocdを走らせた人もいるので、、usblibを適切にコンパイルするとうまくいくのかも
OpenOCDをwslでWindows用にクロスコンパイルする - Qiita
st-link support ( usb problem ) · Issue #3803 · microsoft/WSL · GitHub
Programming STM32 on Linux - Olayiwola Ayinde - Medium
■追記
workaroundながらビルドまではOKということで、WSL環境にRustを入れてみる。WSL用のスクリプトが提示されていて、それを実行
https://www.rust-lang.org/tools/install
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
するとcurgoのビルドでpanicで中断
info: installing component 'cargo' thread 'main' panicked at 'assertion failed: `(left == right)` left: `22`,
https://github.com/rust-lang/rustup/issues/2293
他の人も同じようで、sleep関連で問題が出ているとか?
どこまでやれるかわからないけど、、WSL環境は実際のLinuxとほぼ同じとのことで、、VMware上のUbuntuでrust環境を構築して、出来上がったバイナリ一式をtarで固めてWSLにコピーした。
cd ~ tar cvfz rust.tgz .rustup/ .cargo/
結果、WSLでcargo等は動くようになった。VMware上のUbuntuとWSL上のUbuntuではバージョンが少し違うのでライブラリの整合性とか、かなり怪しい。
cargo install cargo-generate
ビルド途中でエラー発生
Compiling miniz_oxide v0.3.6 error: failed to run custom build command for `openssl-sys v0.9.55` 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.
openssl自体はインストールされている。もう少し読むと、pkg-configでエラーが出ていると判断して追加。
sudo apt install pkg-config
やはりopenssl関連のエラーであった
error: failed to run custom build command for `openssl-sys v0.9.55` Caused by: process didn't exit successfully: `/tmp/cargo-installx4ZcZL/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: `"pkg-config" "--libs" "--cflags" "openssl"` did not exit successfully: exit code: 1 --- stderr 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" --- 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 ', /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 warning: build failed, waiting for other jobs to finish... error: failed to compile `cargo-generate v0.5.0`, intermediate artifacts can be found at `/tmp/cargo-installx4ZcZL` Caused by: build failed
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
sudo apt-get install libssl-dev
pkg-configコマンドはエラー解消された
$ pkg-config --libs --cflags openssl -lssl -lcrypto
再度 cargo-generateをインストール、インストールできた。
cargo install cargo-generate
RustでArm用バイナリをビルドできるように手当実施
rustup target add thumbv7em-none-eabi rustup target add thumbv7m-none-eabi cargo install cargo-binutils rustup component add llvm-tools-preview
$ rustup target list | grep thumbv7 thumbv7em-none-eabi thumbv7em-none-eabihf thumbv7m-none-eabi thumbv7neon-linux-androideabi thumbv7neon-unknown-linux-gnueabihf
ビルドしてみると、coreのcrateがない??
$ cargo build --example hello Compiling stable_deref_trait v1.1.1 Compiling vcell v0.1.2 Compiling r0 v0.2.2 Compiling panic-halt v0.2.0 error[E0463]: can't find crate for `core` | = note: the `thumbv7m-none-eabi` target may not be installed error[E0463]: can't find crate for `core` | = note: the `thumbv7m-none-eabi` target may not be installed error: aborting due to previous error
再確認すると、target addがエラーを起こしていた
$ rustup target add thumbv7m-none-eabi info: downloading component 'rust-std' for 'thumbv7m-none-eabi' info: installing component 'rust-std' for 'thumbv7m-none-eabi' thread 'main' panicked at 'assertion failed: `(left == right)` left: `22`, right: `4`', src/libstd/sys/unix/thread.rs:166:21 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace. info: rolling back changes
エラー発生までのバックトレースを表示させる
$ export RUST_BACKTRACE=full $ rustup target add thumbv7m-none-eabi info: downloading component 'rust-std' for 'thumbv7m-none-eabi' info: installing component 'rust-std' for 'thumbv7m-none-eabi' thread 'main' panicked at 'assertion failed: `(left == right)` left: `22`, right: `4`', src/libstd/sys/unix/thread.rs:166:21 stack backtrace: 0: 0x7f1c836dbc9c - backtrace::backtrace::libunwind::trace::h65597d255cb1398b at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.40/src/backtrace/libunwind.rs:88 1: 0x7f1c836dbc9c - backtrace::backtrace::trace_unsynchronized::hd4f479d7150ec4a0 at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.40/src/backtrace/mod.rs:66 2: 0x7f1c836dbc9c - std::sys_common::backtrace::_print_fmt::h015072984a2b172c at src/libstd/sys_common/backtrace.rs:77 3: 0x7f1c836dbc9c - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::h6df05d3335f32194 at src/libstd/sys_common/backtrace.rs:61 4: 0x7f1c833ba81c - core::fmt::write::h1f444f4312eb6c27 at src/libcore/fmt/mod.rs:1028 5: 0x7f1c836db526 - std::io::Write::write_fmt::h8d147888220078ef at src/libstd/io/mod.rs:1412 6: 0x7f1c836db19e - std::sys_common::backtrace::_print::h8a6df0fa81d6af62 at src/libstd/sys_common/backtrace.rs:65 7: 0x7f1c836db19e - std::sys_common::backtrace::print::h6f05b4733407e509 at src/libstd/sys_common/backtrace.rs:50 8: 0x7f1c836db19e - std::panicking::default_hook::{{closure}}::h0d0a23bd02315dd8 at src/libstd/panicking.rs:188 9: 0x7f1c836da943 - std::panicking::default_hook::h8d15a9aecb4efac6 at src/libstd/panicking.rs:205 10: 0x7f1c836da943 - std::panicking::rust_panic_with_hook::hbe174577402a475d at src/libstd/panicking.rs:464 11: 0x7f1c836da4be - std::panicking::continue_panic_fmt::h4d855dad868accf3 at src/libstd/panicking.rs:373 12: 0x7f1c836da450 - std::panicking::begin_panic_fmt::ha0f013e3301a9528 at src/libstd/panicking.rs:328 13: 0x7f1c836aae86 - <rustup::diskio::threaded::Threaded as rustup::diskio::Executor>::join::hf33124263a81d2a4 14: 0x7f1c8369cd40 - rustup::dist::component::package::unpack_without_first_dir::h352b57d236248e9a 15: 0x7f1c836762f6 - rustup::dist::manifestation::Manifestation::update::h8c800deec8167b5b 16: 0x7f1c836cc138 - rustup::toolchain::Toolchain::add_component::h9456367278c4c593 17: 0x7f1c832e7454 - rustup_init::rustup_mode::main::h2c97a39c05d9bf7c 18: 0x7f1c83323b1c - rustup_init::run_rustup_inner::ha545371fd2dc19a6 19: 0x7f1c83322d64 - rustup_init::main::hba9a23e308c96901 20: 0x7f1c832b7a03 - std::rt::lang_start::{{closure}}::h1778d9ce6385bef5 21: 0x7f1c8332c458 - main 22: 0x7f1c82d970b3 - __libc_start_main 23: 0x7f1c832b4029 - <unknown> info: rolling back changes