セミホスティング
セミホスティングは、組込みデバイスがホスト上でI/Oを行う仕組みです。主に、ホストのコンソールにログ出力するために使われます。 セミホスティングには、デバッグセッションが必要ですが、他には何も必要としません(追加の配線は不要です)。そのため、非常に便利です。 欠点は、非常に低速であることです。ハードウェアデバッガ(例えば、ST-Link)によっては、書き込み操作が数ミリ秒かかります。
cortex-m-semihostingクレートは、Cortex-Mデバイス上でセミホスティング操作をするためのAPIを提供します。 下のプログラムは、セミホスティングバージョンの「Hello, world!」です。
#![no_main]
#![no_std]
use panic_halt as _;
use cortex_m_rt::entry;
use cortex_m_semihosting::hprintln;
#[entry]
fn main() -> ! {
hprintln!("Hello, world!").unwrap();
loop {}
}このプログラムをハードウェア上で実行すると、OpenOCDのログに、「Hello world!」のメッセージが表示されます。
$ openocd
(..)
Hello, world!
(..)最初に、GDBからOpenOCDのセミホスティングを有効化する必要があります。
(gdb) monitor arm semihosting enable
semihosting is enabledQEMUはセミホスティング操作を理解しているため、上のプログラムは、デバッグセッションを開始していないqemu-system-armでも動作します。 セミホスティングサポートを有効化するため、QEMUに-semihosting-configフラグを渡す必要があることに注意して下さい。 これらのフラグは、テンプレートの.cargo/configファイルに既に含まれています。
$ # このプログラムは端末をブロックします
$ cargo run
Running `qemu-system-arm (..)
Hello, world!
exitセミホスティング操作もあり、QEMUプロセスを終了するために使われます。 重要:ハードウェア上でdebug::exitを使用しないで下さい。この関数は、OpenOCDセッションを破壊する可能性があり、 OpenOCDを再起動しない限り、それ以上のプログラムのデバッグができなくなります。
#![no_main]
#![no_std]
use panic_halt as _;
use cortex_m_rt::entry;
use cortex_m_semihosting::debug;
#[entry]
fn main() -> ! {
let roses = "blue";
if roses == "red" {
debug::exit(debug::EXIT_SUCCESS);
} else {
debug::exit(debug::EXIT_FAILURE);
}
loop {}
}$ cargo run
Running `qemu-system-arm (..)
$ echo $?
1最後のヒント:パニック時の挙動を、exit(EXIT_FAILURE)に設定することができます。 これで、QEMU上で実行できるno_stdランパステストを書くことができます。
利便性のために、panic-semihostingクレートは、「exit」フィーチャを持っています。 このフィーチャが有効化されていると、ホストの標準エラーにパニックメッセージをログ出力した後、exit(EXIT_FAILURE)を呼び出します。
#![no_main]
#![no_std]
use panic_semihosting as _; // features = ["exit"]
use cortex_m_rt::entry;
use cortex_m_semihosting::debug;
#[entry]
fn main() -> ! {
let roses = "blue";
assert_eq!(roses, "red");
loop {}
}$ cargo run
Running `qemu-system-arm (..)
panicked at 'assertion failed: `(left == right)`
left: `"blue"`,
right: `"red"`', examples/hello.rs:15:5
$ echo $?
1NOTE: To enable this feature on panic-semihosting, edit your Cargo.toml dependencies section where panic-semihosting is specified with:
panic-semihosting = { version = "VERSION", features = ["exit"] }where VERSION is the version desired. For more information on dependencies features check the specifying dependencies section of the Cargo book.