Restrict access to the UART when logging Added a mutex around the UART in the console backend to prevent multiple tasks from stomping on each other. This eliminates UART corruption garbling the tokenized output.
diff --git a/target/ast1060-evb/BUILD.bazel b/target/ast1060-evb/BUILD.bazel index 797ac15..f26545a 100644 --- a/target/ast1060-evb/BUILD.bazel +++ b/target/ast1060-evb/BUILD.bazel
@@ -60,6 +60,8 @@ deps = [ "@oot_crates_no_std//:ast1060-pac", "@pigweed//pw_status/rust:pw_status", + "@pigweed//pw_kernel/arch/arm_cortex_m:arch_arm_cortex_m", + "@pigweed//pw_kernel/kernel", "@oot_crates_no_std//:aspeed-ddk", "@oot_crates_no_std//:embedded-hal", "@oot_crates_no_std//:embedded-io",
diff --git a/target/ast1060-evb/console_backend.rs b/target/ast1060-evb/console_backend.rs index 237ef76..d5c267d 100644 --- a/target/ast1060-evb/console_backend.rs +++ b/target/ast1060-evb/console_backend.rs
@@ -12,12 +12,14 @@ use pw_status::{Error, Result}; use ast1060_pac::Peripherals; use embedded_io::Write; +use kernel::sync::spinlock::SpinLock; use aspeed_ddk::uart::{Config, Parity, StopBits, UartController}; -// Global UART controller instance +// Global UART controller instance wrapped in a spinlock static mut UART_CONTROLLER: MaybeUninit<UartController<'static>> = MaybeUninit::uninit(); static UART_INITIALIZED: AtomicBool = AtomicBool::new(false); +static UART_LOCK: SpinLock<arch_arm_cortex_m::Arch, ()> = SpinLock::new(()); struct DummyDelay; @@ -73,8 +75,10 @@ return Err(Error::Unavailable); } - // Safety: logical singlton access pattern guarded by UART_INITIALIZED. - // In a real multi-threaded kernel we'd need a spinlock here. + // Acquire spinlock to ensure exclusive UART access + let _guard = UART_LOCK.lock(arch_arm_cortex_m::Arch); + + // Safety: exclusive access is guaranteed by the spinlock guard above. let controller = unsafe { &mut *(core::ptr::addr_of_mut!(UART_CONTROLLER) as *mut UartController<'static>) };