|
169 | 169 | //! conjunction with crates generated using `svd2rust`. Those *device crates* will populate the
|
170 | 170 | //! missing part of the vector table when their `"rt"` feature is enabled.
|
171 | 171 | //!
|
| 172 | +//! ## `pre_init` |
| 173 | +//! |
| 174 | +//! If this feature is enabled then a user-defined function will be run at the start of the reset |
| 175 | +//! handler, before RAM is initialized. If this feature is enabled then the macro `pre_init!` needs |
| 176 | +//! to be called to set the function to be run. This feature is intended to perform actions that |
| 177 | +//! cannot wait the time it takes for RAM to be initialized, such as disabling a watchdog. |
| 178 | +//! |
172 | 179 | //! # Inspection
|
173 | 180 | //!
|
174 | 181 | //! This section covers how to inspect a binary that builds on top of `cortex-m-rt`.
|
@@ -474,8 +481,14 @@ pub unsafe extern "C" fn Reset() -> ! {
|
474 | 481 | static mut __sdata: u32;
|
475 | 482 | static mut __edata: u32;
|
476 | 483 | static __sidata: u32;
|
| 484 | + |
| 485 | + #[cfg(feature = "pre_init")] |
| 486 | + fn _pre_init(); |
477 | 487 | }
|
478 | 488 |
|
| 489 | + #[cfg(feature = "pre_init")] |
| 490 | + _pre_init(); |
| 491 | + |
479 | 492 | // Initialize RAM
|
480 | 493 | r0::zero_bss(&mut __sbss, &mut __ebss);
|
481 | 494 | r0::init_data(&mut __sdata, &mut __edata, &__sidata);
|
@@ -872,3 +885,36 @@ macro_rules! exception {
|
872 | 885 | }
|
873 | 886 | };
|
874 | 887 | }
|
| 888 | + |
| 889 | +/// Macro to set the function to be called at the beginning of the reset handler. |
| 890 | +/// |
| 891 | +/// The function must have the signature of `unsafe fn()`. |
| 892 | +/// |
| 893 | +/// The function passed will be called before static variables are initialized. Any access of static |
| 894 | +/// variables will result in undefined behavior. |
| 895 | +/// |
| 896 | +/// # Examples |
| 897 | +/// |
| 898 | +/// ``` ignore |
| 899 | +/// pre_init!(foo::bar); |
| 900 | +/// |
| 901 | +/// mod foo { |
| 902 | +/// pub unsafe fn bar() { |
| 903 | +/// // do something here |
| 904 | +/// } |
| 905 | +/// } |
| 906 | +/// ``` |
| 907 | +#[cfg(feature = "pre_init")] |
| 908 | +#[macro_export] |
| 909 | +macro_rules! pre_init { |
| 910 | + ($handler:path) => { |
| 911 | + #[allow(unsafe_code)] |
| 912 | + #[deny(private_no_mangle_fns)] // raise an error if this item is not accessible |
| 913 | + #[no_mangle] |
| 914 | + pub unsafe extern "C" fn _pre_init() { |
| 915 | + // validate user handler |
| 916 | + let f: unsafe fn() = $handler; |
| 917 | + f(); |
| 918 | + } |
| 919 | + } |
| 920 | +} |
0 commit comments