aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cortex-m-rt/Cargo.toml1
-rw-r--r--cortex-m-rt/link.x.in5
-rw-r--r--cortex-m-rt/src/lib.rs31
3 files changed, 23 insertions, 14 deletions
diff --git a/cortex-m-rt/Cargo.toml b/cortex-m-rt/Cargo.toml
index d22c5df..9cd9d19 100644
--- a/cortex-m-rt/Cargo.toml
+++ b/cortex-m-rt/Cargo.toml
@@ -21,4 +21,3 @@ panic-abort = "0.2.0"
[features]
device = []
-pre_init = []
diff --git a/cortex-m-rt/link.x.in b/cortex-m-rt/link.x.in
index dfcf262..02cdb32 100644
--- a/cortex-m-rt/link.x.in
+++ b/cortex-m-rt/link.x.in
@@ -51,6 +51,11 @@ PROVIDE(UserHardFault = DefaultUserHardFault);
/* # Interrupt vectors */
EXTERN(__INTERRUPTS); /* `static` variable similar to `__EXCEPTIONS` */
+/* # Pre-initialization function */
+/* If the user overrides this using the `pre_init!` macro or by creating a `__pre_init` function,
+ then the function this points to will be called before the RAM is initialized. */
+PROVIDE(__pre_init = 0);
+
/* # Sections */
SECTIONS
{
diff --git a/cortex-m-rt/src/lib.rs b/cortex-m-rt/src/lib.rs
index 7b023ed..d73dc4f 100644
--- a/cortex-m-rt/src/lib.rs
+++ b/cortex-m-rt/src/lib.rs
@@ -169,13 +169,6 @@
//! conjunction with crates generated using `svd2rust`. Those *device crates* will populate the
//! missing part of the vector table when their `"rt"` feature is enabled.
//!
-//! ## `pre_init`
-//!
-//! If this feature is enabled then a user-defined function will be run at the start of the reset
-//! handler, before RAM is initialized. If this feature is enabled then the macro `pre_init!` needs
-//! to be called to set the function to be run. This feature is intended to perform actions that
-//! cannot wait the time it takes for RAM to be initialized, such as disabling a watchdog.
-//!
//! # Inspection
//!
//! This section covers how to inspect a binary that builds on top of `cortex-m-rt`.
@@ -244,6 +237,10 @@
//! have a size of 32 vectors (on ARMv6-M) or 240 vectors (on ARMv7-M). This array is located after
//! `__EXCEPTIONS` in the `.vector_table` section.
//!
+//! - `__pre_init`. This is a function to be run before RAM is initialized. It defaults pointing at
+//! `0` and if not changed to point to another address, usually by calling the `pre_init!` macro,
+//! the `_pre_init` function is skipped.
+//!
//! If you override any exception handler you'll find it as an unmangled symbol, e.g. `SysTick` or
//! `SVCall`, in the output of `objdump`,
//!
@@ -385,6 +382,14 @@
//! println!("cargo:rustc-link-search={}", out.display());
//! }
//! ```
+//!
+//! ## `pre_init!`
+//!
+//! A user-defined function can be run at the start of the reset handler, before RAM is
+//! initialized. The macro `pre_init!` can be called to set the function to be run. The function is
+//! intended to perform actions that cannot wait the time it takes for RAM to be initialized, such
+//! as disabling a watchdog. As the function is called before RAM is initialized, any access of
+//! static variables will result in undefined behavior.
// # Developer notes
//
@@ -482,12 +487,13 @@ pub unsafe extern "C" fn Reset() -> ! {
static mut __edata: u32;
static __sidata: u32;
- #[cfg(feature = "pre_init")]
- fn _pre_init();
+ fn __pre_init();
}
- #[cfg(feature = "pre_init")]
- _pre_init();
+ let pre_init: unsafe extern "C" fn() = __pre_init;
+ if pre_init as usize != 0 {
+ pre_init();
+ }
// Initialize RAM
r0::zero_bss(&mut __sbss, &mut __ebss);
@@ -904,14 +910,13 @@ macro_rules! exception {
/// }
/// }
/// ```
-#[cfg(feature = "pre_init")]
#[macro_export]
macro_rules! pre_init {
($handler:path) => {
#[allow(unsafe_code)]
#[deny(private_no_mangle_fns)] // raise an error if this item is not accessible
#[no_mangle]
- pub unsafe extern "C" fn _pre_init() {
+ pub unsafe extern "C" fn __pre_init() {
// validate user handler
let f: unsafe fn() = $handler;
f();