freertos_next/
assert_callback.rs

1use crate::utils::*;
2
3#[cfg(feature = "assert-hook")]
4mod assert_hook {
5    use core::cell::OnceCell;
6
7    type Callback = fn();
8
9    pub struct FreeRtosHooks {
10        on_assert: OnceCell<Callback>,
11    }
12
13    impl FreeRtosHooks {
14        pub fn set_on_assert(&self, c: Callback) -> Result<(), Callback> {
15            self.on_assert.set(c)
16        }
17
18        pub(super) fn do_on_assert(&self) {
19            if let Some(cb) = self.on_assert.get() {
20                cb()
21            }
22        }
23    }
24
25    // SAFETY: must only be set before the scheduler starts and accessed after the
26    // kernel has asserted, both being single threaded situations.
27    unsafe impl Sync for FreeRtosHooks {}
28
29    pub static FREERTOS_HOOKS: FreeRtosHooks = FreeRtosHooks {
30        on_assert: OnceCell::new(),
31    };
32}
33#[cfg(feature = "assert-hook")]
34pub use assert_hook::*;
35
36#[allow(unused_doc_comments)]
37#[unsafe(no_mangle)]
38pub extern "C" fn assert_callback(line: u32, file_name_ptr: *const u8) {
39    let file_name = unsafe { str_from_c_string(file_name_ptr).unwrap_or("Unknown") };
40
41    #[cfg(feature = "assert-hook")]
42    FREERTOS_HOOKS.do_on_assert();
43
44    // we can't print without std yet.
45    // TODO: make the macro work for debug UART? Or use Panic here?
46    // println!("ASSERT: {} {}", line, file_name);
47    panic!("FreeRTOS ASSERT: {}:{}", file_name, line);
48    //loop {}
49}