|
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 |
| -//! |
179 | 172 | //! # Inspection
|
180 | 173 | //!
|
181 | 174 | //! This section covers how to inspect a binary that builds on top of `cortex-m-rt`.
|
|
244 | 237 | //! have a size of 32 vectors (on ARMv6-M) or 240 vectors (on ARMv7-M). This array is located after
|
245 | 238 | //! `__EXCEPTIONS` in the `.vector_table` section.
|
246 | 239 | //!
|
| 240 | +//! - `__pre_init`. This is a function to be run before RAM is initialized. It defaults pointing at |
| 241 | +//! `0` and if not changed to point to another address, usually by calling the `pre_init!` macro, |
| 242 | +//! the `_pre_init` function is skipped. |
| 243 | +//! |
247 | 244 | //! If you override any exception handler you'll find it as an unmangled symbol, e.g. `SysTick` or
|
248 | 245 | //! `SVCall`, in the output of `objdump`,
|
249 | 246 | //!
|
|
385 | 382 | //! println!("cargo:rustc-link-search={}", out.display());
|
386 | 383 | //! }
|
387 | 384 | //! ```
|
| 385 | +//! |
| 386 | +//! ## `pre_init!` |
| 387 | +//! |
| 388 | +//! A user-defined function can be run at the start of the reset handler, before RAM is |
| 389 | +//! initialized. The macro `pre_init!` can be called to set the function to be run. The function is |
| 390 | +//! intended to perform actions that cannot wait the time it takes for RAM to be initialized, such |
| 391 | +//! as disabling a watchdog. As the function is called before RAM is initialized, any access of |
| 392 | +//! static variables will result in undefined behavior. |
388 | 393 |
|
389 | 394 | // # Developer notes
|
390 | 395 | //
|
@@ -482,12 +487,13 @@ pub unsafe extern "C" fn Reset() -> ! {
|
482 | 487 | static mut __edata: u32;
|
483 | 488 | static __sidata: u32;
|
484 | 489 |
|
485 |
| - #[cfg(feature = "pre_init")] |
486 |
| - fn _pre_init(); |
| 490 | + fn __pre_init(); |
487 | 491 | }
|
488 | 492 |
|
489 |
| - #[cfg(feature = "pre_init")] |
490 |
| - _pre_init(); |
| 493 | + let pre_init: unsafe extern "C" fn() = __pre_init; |
| 494 | + if pre_init as usize != 0 { |
| 495 | + pre_init(); |
| 496 | + } |
491 | 497 |
|
492 | 498 | // Initialize RAM
|
493 | 499 | r0::zero_bss(&mut __sbss, &mut __ebss);
|
@@ -904,14 +910,13 @@ macro_rules! exception {
|
904 | 910 | /// }
|
905 | 911 | /// }
|
906 | 912 | /// ```
|
907 |
| -#[cfg(feature = "pre_init")] |
908 | 913 | #[macro_export]
|
909 | 914 | macro_rules! pre_init {
|
910 | 915 | ($handler:path) => {
|
911 | 916 | #[allow(unsafe_code)]
|
912 | 917 | #[deny(private_no_mangle_fns)] // raise an error if this item is not accessible
|
913 | 918 | #[no_mangle]
|
914 |
| - pub unsafe extern "C" fn _pre_init() { |
| 919 | + pub unsafe extern "C" fn __pre_init() { |
915 | 920 | // validate user handler
|
916 | 921 | let f: unsafe fn() = $handler;
|
917 | 922 | f();
|
|
0 commit comments