freertos_rust/
hooks.rs

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