diff options
author | 2022-02-22 03:11:12 +0000 | |
---|---|---|
committer | 2022-02-24 01:44:16 +0000 | |
commit | 7813e4d5572199f345a081fc7b217c4ba607c686 (patch) | |
tree | 41eff29d0aee791e96b832d75ab1b5ce33461fc7 | |
parent | 2810f97fe909bc68f1052de1c6a92b7817d86783 (diff) | |
download | cortex-m-7813e4d5572199f345a081fc7b217c4ba607c686.tar.gz cortex-m-7813e4d5572199f345a081fc7b217c4ba607c686.tar.zst cortex-m-7813e4d5572199f345a081fc7b217c4ba607c686.zip |
Add set-sp and set-vtor features to cortex-m-rt.
-rw-r--r-- | cortex-m-rt/Cargo.toml | 2 | ||||
-rwxr-xr-x | cortex-m-rt/ci/script.sh | 5 | ||||
-rw-r--r-- | cortex-m-rt/src/lib.rs | 30 |
3 files changed, 37 insertions, 0 deletions
diff --git a/cortex-m-rt/Cargo.toml b/cortex-m-rt/Cargo.toml index 5289057..ae4eb9f 100644 --- a/cortex-m-rt/Cargo.toml +++ b/cortex-m-rt/Cargo.toml @@ -42,6 +42,8 @@ required-features = ["device"] [features] device = [] +set-sp = [] +set-vtor = [] [package.metadata.docs.rs] features = ["device"] diff --git a/cortex-m-rt/ci/script.sh b/cortex-m-rt/ci/script.sh index a9c2b19..4683566 100755 --- a/cortex-m-rt/ci/script.sh +++ b/cortex-m-rt/ci/script.sh @@ -57,6 +57,11 @@ main() { done cargo rustc --target "$TARGET" --example device --features device -- $linker cargo rustc --target "$TARGET" --example device --features device --release -- $linker + + cargo rustc --target "$TARGET" --example minimal --features set-sp -- $linker + cargo rustc --target "$TARGET" --example minimal --features set-sp --release -- $linker + cargo rustc --target "$TARGET" --example minimal --features set-vtor -- $linker + cargo rustc --target "$TARGET" --example minimal --features set-vtor --release -- $linker done fi diff --git a/cortex-m-rt/src/lib.rs b/cortex-m-rt/src/lib.rs index 0cfed4d..7a3f7e0 100644 --- a/cortex-m-rt/src/lib.rs +++ b/cortex-m-rt/src/lib.rs @@ -158,6 +158,19 @@ //! conjunction with crates generated using `svd2rust`. Those *device crates* will populate the //! missing part of the vector table when their `"rt"` feature is enabled. //! +//! ## `set-sp` +//! +//! If this feature is enabled, the stack pointer (SP) is initialised in the reset handler to the +//! `_stack_start` value from the linker script. This is not usually required, but some debuggers +//! do not initialise SP when performing a soft reset, which can lead to stack corruption. +//! +//! ## `set-vtor` +//! +//! If this feature is enabled, the vector table offset register (VTOR) is initialised in the reset +//! handler to the start of the vector table defined in the linker script. This is not usually +//! required, but some bootloaders do not set VTOR before jumping to application code, leading to +//! your main function executing but interrupt handlers not being used. +//! //! # Inspection //! //! This section covers how to inspect a binary that builds on top of `cortex-m-rt`. @@ -496,6 +509,23 @@ cfg_global_asm! { mvns r4, r4 mov lr, r4", + // If enabled, initialise the SP. This is normally initialised by the CPU itself or by a + // bootloader, but some debuggers fail to set it when resetting the target, leading to + // stack corruptions. + #[cfg(feature = "set-sp")] + "ldr r0, =_stack_start + msr msp, r0", + + // If enabled, initialise VTOR to the start of the vector table. This is normally initialised + // by a bootloader when the non-reset value is required, but some bootloaders do not set it, + // leading to frustrating issues where everything seems to work but interrupts are never + // handled. The VTOR register is optional on ARMv6-M, but when not present is RAZ,WI and + // therefore safe to write to. + #[cfg(feature = "set-vtor")] + "ldr r0, =0xe000ed08 + ldr r1, =__vector_table + str r1, [r0]", + // Run user pre-init code which must be executed immediately after startup, before the // potentially time-consuming memory initialisation takes place. // Example use cases include disabling default watchdogs or enabling RAM. |