Semihosting
Semihosting is a feature which allows targets without I/O support to use the I/O of the host.
When the special BKPT
instruction is reached, the host reads the characters directly from the micro:bit's memory.
Semihosting is slow
The most important thing to remember about semihosting is that it is slow. The processor halts entirely for each operation, making each operation take 107 milliseconds. This means that if you are doing any time sensitive work, you should not use it for logging. Check out this blog post for more information.
GDB
The first thing to do is to enable semihosting in GDB.
As before, we will add this to .gdbinit
to avoid typing it every time.
.gdbinit
target remote :3333
monitor arm semihosting enable
load
OpenOCD
You may have incorrectly assumed at this point that the outpust would appear in GDB. Remember that GDB simply connects to OpenOCD to interface with the micro:bit. OpenOCD is very loud currently, so it will be quite hard to see the output of our micro:bit in the noise. Fix this by stopping and restarting it with logging dumped to a file.
openocd -f interface/cmsis-dap.cfg -f target/nrf51.cfg -l /tmp/openocd.log
Panic
The easiest way to use semihosting is to use it for the panic!
macro.
Cargo.toml
panic-semihosting = ""
You can then see what happens if you add a panic!
to your code:
fn main() -> ! { panic!("test-panic"); }
Open On-Chip Debugger 0.10.0
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
panicked at 'test-panic', src/hello-world/src/main.rs:27:5
stdout
Finally, this is how to write to stdout.
# #![allow(unused_variables)] #fn main() { extern crate cortex_m_semihosting as sh; use core::fmt::Write; use sh::hio; // -- snip -- let mut stdout = hio::hstdout().unwrap(); stdout.write_str("semitest\n\r").unwrap(); // or writeln!(hio::hstdout().unwrap(), "Init").unwrap(); #}
Writing to stderr is just as easy.