From a3dd760aba4b46ac53449a695ad84e7ca4b84ee4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20J=C3=B6rdens?= Date: Thu, 24 Jun 2021 08:11:46 +0000 Subject: [PATCH 1/2] setup: use a best-effort lock for rprintln close #382 --- src/hardware/setup.rs | 42 +++++++++++++++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 7 deletions(-) diff --git a/src/hardware/setup.rs b/src/hardware/setup.rs index 20842ae..99d0fce 100644 --- a/src/hardware/setup.rs +++ b/src/hardware/setup.rs @@ -1,6 +1,8 @@ ///! Stabilizer hardware configuration ///! ///! 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::{ self as hal, ethernet::{self, PHY}, @@ -149,8 +151,6 @@ fn load_itcm() { static mut __eitcm: u32; static mut __siitcm: u32; } - use core::{ptr, slice, sync::atomic}; - // 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 // 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); // Ensure ITCM is enabled before loading. - atomic::fence(atomic::Ordering::SeqCst); + atomic::fence(Ordering::SeqCst); let len = (&__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. - atomic::fence(atomic::Ordering::SeqCst); + atomic::fence(Ordering::SeqCst); cortex_m::asm::dsb(); cortex_m::asm::isb(); } @@ -224,10 +224,38 @@ pub fn setup( // Enable debug during WFE/WFI-induced sleep 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); - rtt_target::rtt_init_print!(); + let channels = rtt_target::rtt_init_default!(); + // Note(unsafe): The closure we pass does not establish a critical section + // as demanded but it ensure synchronization and implements a lock. + unsafe { + rtt_target::set_print_channel_cs( + channels.up.0, + &((|arg, f| { + static LOGGER_LOCK: AtomicBool = AtomicBool::new(false); + if LOGGER_LOCK.compare_exchange_weak( + false, + true, + Ordering::Acquire, + Ordering::Relaxed, + ) == Ok(false) + { + f(arg); + LOGGER_LOCK.store(false, Ordering::Release); + } + }) as rtt_target::CriticalSectionFunc), + ); + } + + static LOGGER: rtt_logger::RTTLogger = + rtt_logger::RTTLogger::new(log::LevelFilter::Info); log::set_logger(&LOGGER) .map(|()| log::set_max_level(log::LevelFilter::Trace)) .unwrap(); From 2c5afe959b4e4d284e711430205f4618844812cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20J=C3=B6rdens?= Date: Thu, 24 Jun 2021 10:21:32 +0200 Subject: [PATCH 2/2] spelling, naming --- src/hardware/setup.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/hardware/setup.rs b/src/hardware/setup.rs index 99d0fce..f647047 100644 --- a/src/hardware/setup.rs +++ b/src/hardware/setup.rs @@ -234,13 +234,13 @@ pub fn setup( let channels = rtt_target::rtt_init_default!(); // Note(unsafe): The closure we pass does not establish a critical section - // as demanded but it ensure synchronization and implements a lock. + // as demanded but it does ensure synchronization and implements a lock. unsafe { rtt_target::set_print_channel_cs( channels.up.0, &((|arg, f| { - static LOGGER_LOCK: AtomicBool = AtomicBool::new(false); - if LOGGER_LOCK.compare_exchange_weak( + static LOCKED: AtomicBool = AtomicBool::new(false); + if LOCKED.compare_exchange_weak( false, true, Ordering::Acquire, @@ -248,7 +248,7 @@ pub fn setup( ) == Ok(false) { f(arg); - LOGGER_LOCK.store(false, Ordering::Release); + LOCKED.store(false, Ordering::Release); } }) as rtt_target::CriticalSectionFunc), );