aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Adam Greig <adam@adamgreig.com> 2022-02-22 03:11:12 +0000
committerGravatar Adam Greig <adam@adamgreig.com> 2022-02-24 01:44:16 +0000
commit7813e4d5572199f345a081fc7b217c4ba607c686 (patch)
tree41eff29d0aee791e96b832d75ab1b5ce33461fc7
parent2810f97fe909bc68f1052de1c6a92b7817d86783 (diff)
downloadcortex-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.toml2
-rwxr-xr-xcortex-m-rt/ci/script.sh5
-rw-r--r--cortex-m-rt/src/lib.rs30
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.