Skip to content
Snippets Groups Projects
Commit 9f49f9eb authored by Per Lindgren's avatar Per Lindgren
Browse files

panic

parent 580c8552
No related branches found
No related tags found
No related merge requests found
......@@ -17,6 +17,7 @@ cortex-m-semihosting = "0.3.5"
cortex-m = "0.6.2"
aligned = "0.3.2"
ufmt = "0.1.0"
panic-itm = "0.4.1"
[dependencies.cortex-m-rt]
version = "0.6.12"
......
......@@ -127,15 +127,14 @@ In a separate terminal:
``` console
$ mkfifo /tmp/itm.fifo
$ itmdump -f /tmp/itm.fifo -F
$ itmdump -f /tmp/itm.fifo
Hello, again!
```
Now you can compile and run the `itm.rs` application using the same steps as the `hello` program. In the `itmdump` console you should now have the trace output.
``` console
$ mkfifo /tmp/itm.log
$ itmdump -f /tmp/itm.log -F
Hello, again!
$ cargo run --example itm
```
Under the hood there is much less overhead, the serial transfer rate is set to 2MBit in between the ITM (inside of the MCU) and `stlink` programmer (onboard the Nucleo devkit). So in theory we can transmit some 200kByte/s data over ITM. However, we are limited by the USB interconnection and `openocd` to receive and forward packages.
......@@ -146,7 +145,7 @@ The `stlink` programmer, buffers packages but has limited buffer space. Hence in
### Rust `panic` Handling
The `rust` compiler statically analyses your code, but in cases some errors cannot be detected at compile time (e.g., array indexing out of bounds, division by zore etc.). The `rust` compiler generates code checking such faults at run-time, instead of just crashing (or even worse, continuing with faulty/undefined values like a `C` program would) . A fault in Rust will render a `panic`, whith an associated error message (useful to debugging the application). We can choose how such `panic`s should be treated, e.g., transmitting the error message using `semihosting`, `ITM`, some other channel (e.g. a serial port), or simply aborting the program.
The `rust` compiler statically analyses your code, but in cases some errors cannot be detected at compile time (e.g., array indexing out of bounds, division by zero etc.). The `rust` compiler generates code checking such faults at run-time, instead of just crashing (or even worse, continuing with faulty/undefined values like a `C` program would) . A fault in Rust will render a `panic`, with an associated error message (useful to debugging the application). We can choose how such `panic`s should be treated, e.g., transmitting the error message using `semihosting`, `ITM`, some other channel (e.g. a serial port), or simply aborting the program.
The `panic` example demonstrates some possible use cases.
......@@ -169,7 +168,7 @@ Breakpoint 1, rust_begin_unwind (_info=0x20017fb4)
$1 = core::panic::PanicInfo {payload: core::any::&Any {pointer: 0x8000760 <.Lanon.21a036e607595cc96ffa1870690e4414.142> "\017\004\000", vtable: 0x8000760 <.Lanon.21a036e607595cc96ffa1870690e4414.142>}, message: core::option::Option<&core::fmt::Arguments>::Some(0x20017fd0), location: core::panic::Location {file: <error reading variable>, line: 27, col: 5}}
```
Here `p *_info` prints the arument to `rust_begin_unwind`, at the far end you will find `line: 27, col 5`, which correstponds to the source code calling `panic("Ooops")`. (`gdb` is not (yet) Rust aware enough to figure out how the `file` field should be interpreted, but at least we get some useful information).
Here `p *_info` prints the arument to `rust_begin_unwind`, at the far end you will find `line: 27, col 5`, which corresponds to the source code calling `panic("Ooops")`. (`gdb` is not (yet) Rust aware enough to figure out how the `file` field should be interpreted, but at least we get some useful information).
Alternatively we can trace the panic message over `semihosting` (comment out `extern crate panic_halt` and uncomment `extern crate panic_semihosting`).
......
......@@ -2,10 +2,9 @@
//!
//! ITM is much faster than semihosting. Like 4 orders of magnitude or so.
//!
//! You'll need [`itmdump`] to receive the message on the host plus you'll need to uncomment two
//! `monitor` commands in the `.gdbinit` file.
//! You'll need [`itmdump`] to view the output.
//!
//! [`itmdump`]: https://docs.rs/itm/0.2.1/itm/
//! [`itmdump`]: https://docs.rs/itm/0.3.1/itm/
//!
//! ---
......
//! Changing the panicking behavior
//!
//! The easiest way to change the panicking behavior is to use a different [panic handler crate][0].
//!
//! [0]: https://crates.io/keywords/panic-impl
#![no_main]
#![no_std]
// Pick one of these panic handlers:
// `panic!` halts execution; the panic message is ignored
extern crate panic_halt;
// Reports panic messages to the host stderr using semihosting
// NOTE to use this you need to uncomment the `panic-semihosting` dependency in Cargo.toml
// extern crate panic_semihosting;
// Logs panic messages using the ITM (Instrumentation Trace Macrocell)
// NOTE to use this you need to uncomment the `panic-itm` dependency in Cargo.toml
//extern crate panic_itm;
use cortex_m_rt::entry;
#[entry]
fn main() -> ! {
panic!("Oops")
}
target extended-remote :3333
set print asm-demangle on
monitor arm semihosting enable
monitor tpiu config internal /tmp/itm.fifo uart off 16000000 2000000
# ITM tracing
# send captured ITM to the file (or fifo) /tmp/itm.fifo
# (the microcontroller SWO pin must be connected to the programmer SWO pin)
# 16000000 must match the core clock frequency
# in this case the speed of SWO will be negotiated
monitor tpiu config internal /tmp/itm.fifo uart off 16000000
# OR: make the microcontroller SWO pin output compatible with UART (8N1)
# 16000000 must match the core clock frequency
# 2000000 is the frequency of the SWO pin
# monitor tpiu config external uart off 16000000 2000000
# enable itm ports
# enable ITM ports
monitor itm port 0 on
monitor itm port 1 on
monitor itm port 2 on
......@@ -14,12 +25,17 @@ monitor itm port 2 on
break main
# detect unhandled exceptions, hard faults and panics
break DefaultHandler
break HardFault
break core::panicking::panic_fmt
break rust_begin_unwind
# un-comment to check that flashing was successful
# compare-sections
# make sure the processor is reset before loading (flashing)
monitor reset init
load
stepi
\ No newline at end of file
# start the process but immediately halt the processor
stepi
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment