Merge #391
391: setup: use a best-effort lock for rprintln r=ryan-summers a=jordens close #382 * [x] tested with very long log messages that would otherwise cause the DMA deadline to be missed. (use cargo-embed git to make it work with stlink v3) Co-authored-by: Robert Jördens <rj@quartiq.de>
This commit is contained in:
commit
b7e2a3dbca
@ -1,6 +1,8 @@
|
|||||||
///! Stabilizer hardware configuration
|
///! Stabilizer hardware configuration
|
||||||
///!
|
///!
|
||||||
///! This file contains all of the hardware-specific configuration of Stabilizer.
|
///! This file contains all of the hardware-specific configuration of Stabilizer.
|
||||||
|
use core::sync::atomic::{self, AtomicBool, Ordering};
|
||||||
|
use core::{ptr, slice};
|
||||||
use stm32h7xx_hal::{
|
use stm32h7xx_hal::{
|
||||||
self as hal,
|
self as hal,
|
||||||
ethernet::{self, PHY},
|
ethernet::{self, PHY},
|
||||||
@ -149,8 +151,6 @@ fn load_itcm() {
|
|||||||
static mut __eitcm: u32;
|
static mut __eitcm: u32;
|
||||||
static mut __siitcm: u32;
|
static mut __siitcm: u32;
|
||||||
}
|
}
|
||||||
use core::{ptr, slice, sync::atomic};
|
|
||||||
|
|
||||||
// NOTE(unsafe): Assuming the address symbols from the linker as well as
|
// NOTE(unsafe): Assuming the address symbols from the linker as well as
|
||||||
// the source instruction data are all valid, this is safe as it only
|
// the source instruction data are all valid, this is safe as it only
|
||||||
// copies linker-prepared data to where the code expects it to be.
|
// copies linker-prepared data to where the code expects it to be.
|
||||||
@ -163,7 +163,7 @@ fn load_itcm() {
|
|||||||
ptr::write_volatile(ITCMCR, ptr::read_volatile(ITCMCR) | 1);
|
ptr::write_volatile(ITCMCR, ptr::read_volatile(ITCMCR) | 1);
|
||||||
|
|
||||||
// Ensure ITCM is enabled before loading.
|
// Ensure ITCM is enabled before loading.
|
||||||
atomic::fence(atomic::Ordering::SeqCst);
|
atomic::fence(Ordering::SeqCst);
|
||||||
|
|
||||||
let len =
|
let len =
|
||||||
(&__eitcm as *const u32).offset_from(&__sitcm as *const _) as usize;
|
(&__eitcm as *const u32).offset_from(&__sitcm as *const _) as usize;
|
||||||
@ -174,7 +174,7 @@ fn load_itcm() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Ensure ITCM is loaded before potentially executing any instructions from it.
|
// Ensure ITCM is loaded before potentially executing any instructions from it.
|
||||||
atomic::fence(atomic::Ordering::SeqCst);
|
atomic::fence(Ordering::SeqCst);
|
||||||
cortex_m::asm::dsb();
|
cortex_m::asm::dsb();
|
||||||
cortex_m::asm::isb();
|
cortex_m::asm::isb();
|
||||||
}
|
}
|
||||||
@ -224,10 +224,38 @@ pub fn setup(
|
|||||||
// Enable debug during WFE/WFI-induced sleep
|
// Enable debug during WFE/WFI-induced sleep
|
||||||
device.DBGMCU.cr.modify(|_, w| w.dbgsleep_d1().set_bit());
|
device.DBGMCU.cr.modify(|_, w| w.dbgsleep_d1().set_bit());
|
||||||
|
|
||||||
use rtt_logger::RTTLogger;
|
// Set up RTT channel to use for `rprintln!()` as "best effort".
|
||||||
|
// This removes a critical section around the logging and thus allows
|
||||||
|
// high-prio tasks to always interrupt at low latency.
|
||||||
|
// It comes at a cost:
|
||||||
|
// If a high-priority tasks preempts while we are logging something,
|
||||||
|
// and if we then also want to log from within that high-preiority task,
|
||||||
|
// the high-prio log message will be lost.
|
||||||
|
|
||||||
static LOGGER: RTTLogger = RTTLogger::new(log::LevelFilter::Info);
|
let channels = rtt_target::rtt_init_default!();
|
||||||
rtt_target::rtt_init_print!();
|
// Note(unsafe): The closure we pass does not establish a critical section
|
||||||
|
// as demanded but it does ensure synchronization and implements a lock.
|
||||||
|
unsafe {
|
||||||
|
rtt_target::set_print_channel_cs(
|
||||||
|
channels.up.0,
|
||||||
|
&((|arg, f| {
|
||||||
|
static LOCKED: AtomicBool = AtomicBool::new(false);
|
||||||
|
if LOCKED.compare_exchange_weak(
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
Ordering::Acquire,
|
||||||
|
Ordering::Relaxed,
|
||||||
|
) == Ok(false)
|
||||||
|
{
|
||||||
|
f(arg);
|
||||||
|
LOCKED.store(false, Ordering::Release);
|
||||||
|
}
|
||||||
|
}) as rtt_target::CriticalSectionFunc),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static LOGGER: rtt_logger::RTTLogger =
|
||||||
|
rtt_logger::RTTLogger::new(log::LevelFilter::Info);
|
||||||
log::set_logger(&LOGGER)
|
log::set_logger(&LOGGER)
|
||||||
.map(|()| log::set_max_level(log::LevelFilter::Trace))
|
.map(|()| log::set_max_level(log::LevelFilter::Trace))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
Loading…
Reference in New Issue
Block a user