ITM Mystery Solved
In the source code below, the first iprintln!
gets caught in a spinlock forever, while the second iprintln!
transmits an ITM packet as expected.
I didn’t have answers to why the two iprintln!
were behaving differently until today.
It was due to the different behavior of ITM::ptr().read()
& *ITM::ptr()
ITM::ptr().read()
Performs a bitwise copy from ITM::ptr()
. Copying the struct is useless,
because writing to the bitwise copy has no effect to the actual hardware register block.
This was why my program hung forever at https://docs.rs/cortex-m/0.6.3/src/cortex_m/itm.rs.html#16 .
*ITM::ptr()
Provides direct access to the memory pointed by ITM::ptr()
. Writing to struct *ITM::ptr()
is writing directly to the hardware register block.
#![no_main]
#![no_std]
extern crate panic_abort;
use stm32f4xx_hal as hal;
use crate::hal::{
prelude::*,
stm32,
};
use cortex_m::{iprintln, Peripherals};
use cortex_m_rt::entry;
use cortex_m::peripheral::ITM;
use cortex_m::asm::bkpt;
#[entry]
fn main() -> ! {
if let (Some(p), Some(cp)) = (stm32::Peripherals::take(), Peripherals::take()) {
// Constrain clock registers
let rcc = p.RCC.constrain();
// Configure clock to 168 MHz (i.e. the maximum) and freeze it
rcc.cfgr.sysclk(168.mhz()).freeze();
// Below line hangs forever at https://docs.rs/cortex-m/0.6.3/src/cortex_m/itm.rs.html#16
iprintln!(unsafe { &mut ITM::ptr().read().stim[0] }, "HELLO-1");
// Below line works properly as expected!
iprintln!(unsafe { &mut (*ITM::ptr()).stim[0] }, "HELLO-2");
}
loop { }
}