@@ -2,24 +2,31 @@ use crate::base::*;
2
2
use crate :: prelude:: v1:: String ;
3
3
use crate :: utils:: * ;
4
4
5
+ use core:: cell:: OnceCell ;
6
+
5
7
type Callback = fn ( ) ;
6
8
7
9
pub struct FreeRtosHooks {
8
- on_assert : Callback ,
10
+ on_assert : OnceCell < Callback > ,
9
11
}
10
12
11
13
impl FreeRtosHooks {
12
- pub fn set_on_assert ( & mut self , c : Callback ) {
13
- self . on_assert = c ;
14
+ pub fn set_on_assert ( & mut self , c : Callback ) -> Result < ( ) , Callback > {
15
+ self . on_assert . set ( c )
14
16
}
15
17
16
18
fn do_on_assert ( & self ) {
17
- ( self . on_assert ) ( ) ;
19
+ if let Some ( cb) = self . on_assert . get ( ) {
20
+ cb ( )
21
+ }
18
22
}
19
23
}
20
24
21
- // TODO: It's unsafe to use, we should build some safe wrapper around
22
- pub static mut FREERTOS_HOOKS : FreeRtosHooks = FreeRtosHooks { on_assert : || { } } ;
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 { on_assert : OnceCell :: new ( ) } ;
23
30
24
31
#[ allow( unused_doc_comments) ]
25
32
#[ no_mangle]
@@ -29,9 +36,7 @@ pub extern "C" fn vAssertCalled(file_name_ptr: FreeRtosCharPtr, line: FreeRtosUB
29
36
file_name = str_from_c_string ( file_name_ptr) . unwrap ( ) ;
30
37
}
31
38
32
- unsafe {
33
- FREERTOS_HOOKS . do_on_assert ( ) ;
34
- }
39
+ FREERTOS_HOOKS . do_on_assert ( ) ;
35
40
36
41
// we can't print without std yet.
37
42
// TODO: make the macro work for debug UART? Or use Panic here?
0 commit comments