aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cortex-m-rt/link.x.in1
-rw-r--r--cortex-m-rt/src/lib.rs157
2 files changed, 141 insertions, 17 deletions
diff --git a/cortex-m-rt/link.x.in b/cortex-m-rt/link.x.in
index 30d4af1..4db25fa 100644
--- a/cortex-m-rt/link.x.in
+++ b/cortex-m-rt/link.x.in
@@ -191,6 +191,7 @@ ASSERT(SIZEOF(.vector_table) > 0x40, "
ERROR(cortex-m-rt): The interrupt vectors are missing.
Possible solutions, from most likely to less likely:
- Link to a svd2rust generated device crate
+- Check that you actually use the device/hal/bsp crate in your code
- Disable the 'device' feature of cortex-m-rt to build a generic application (a dependency
may be enabling it)
- Supply the interrupt handlers yourself. Check the documentation for details.");
diff --git a/cortex-m-rt/src/lib.rs b/cortex-m-rt/src/lib.rs
index 8bfdd69..150ca8e 100644
--- a/cortex-m-rt/src/lib.rs
+++ b/cortex-m-rt/src/lib.rs
@@ -416,33 +416,156 @@ pub use macros::{entry, exception, pre_init};
#[doc(hidden)]
pub static __ONCE__: () = ();
-/// Registers stacked (pushed into the stack) during an exception
+/// Registers stacked (pushed onto the stack) during an exception.
#[derive(Clone, Copy)]
#[repr(C)]
pub struct ExceptionFrame {
- /// (General purpose) Register 0
- pub r0: u32,
+ r0: u32,
+ r1: u32,
+ r2: u32,
+ r3: u32,
+ r12: u32,
+ lr: u32,
+ pc: u32,
+ xpsr: u32,
+}
+
+impl ExceptionFrame {
+ /// Returns the value of (general purpose) register 0.
+ #[inline(always)]
+ pub fn r0(&self) -> u32 {
+ self.r0
+ }
+
+ /// Returns the value of (general purpose) register 1.
+ #[inline(always)]
+ pub fn r1(&self) -> u32 {
+ self.r1
+ }
+
+ /// Returns the value of (general purpose) register 2.
+ #[inline(always)]
+ pub fn r2(&self) -> u32 {
+ self.r2
+ }
+
+ /// Returns the value of (general purpose) register 3.
+ #[inline(always)]
+ pub fn r3(&self) -> u32 {
+ self.r3
+ }
+
+ /// Returns the value of (general purpose) register 12.
+ #[inline(always)]
+ pub fn r12(&self) -> u32 {
+ self.r12
+ }
+
+ /// Returns the value of the Link Register.
+ #[inline(always)]
+ pub fn lr(&self) -> u32 {
+ self.lr
+ }
- /// (General purpose) Register 1
- pub r1: u32,
+ /// Returns the value of the Program Counter.
+ #[inline(always)]
+ pub fn pc(&self) -> u32 {
+ self.pc
+ }
- /// (General purpose) Register 2
- pub r2: u32,
+ /// Returns the value of the Program Status Register.
+ #[inline(always)]
+ pub fn xpsr(&self) -> u32 {
+ self.xpsr
+ }
- /// (General purpose) Register 3
- pub r3: u32,
+ /// Sets the stacked value of (general purpose) register 0.
+ ///
+ /// # Safety
+ ///
+ /// This affects the `r0` register of the preempted code, which must not rely on it getting
+ /// restored to its previous value.
+ #[inline(always)]
+ pub unsafe fn set_r0(&mut self, value: u32) {
+ self.r0 = value;
+ }
- /// (General purpose) Register 12
- pub r12: u32,
+ /// Sets the stacked value of (general purpose) register 1.
+ ///
+ /// # Safety
+ ///
+ /// This affects the `r1` register of the preempted code, which must not rely on it getting
+ /// restored to its previous value.
+ #[inline(always)]
+ pub unsafe fn set_r1(&mut self, value: u32) {
+ self.r1 = value;
+ }
- /// Linker Register
- pub lr: u32,
+ /// Sets the stacked value of (general purpose) register 2.
+ ///
+ /// # Safety
+ ///
+ /// This affects the `r2` register of the preempted code, which must not rely on it getting
+ /// restored to its previous value.
+ #[inline(always)]
+ pub unsafe fn set_r2(&mut self, value: u32) {
+ self.r2 = value;
+ }
- /// Program Counter
- pub pc: u32,
+ /// Sets the stacked value of (general purpose) register 3.
+ ///
+ /// # Safety
+ ///
+ /// This affects the `r3` register of the preempted code, which must not rely on it getting
+ /// restored to its previous value.
+ #[inline(always)]
+ pub unsafe fn set_r3(&mut self, value: u32) {
+ self.r3 = value;
+ }
- /// Program Status Register
- pub xpsr: u32,
+ /// Sets the stacked value of (general purpose) register 12.
+ ///
+ /// # Safety
+ ///
+ /// This affects the `r12` register of the preempted code, which must not rely on it getting
+ /// restored to its previous value.
+ #[inline(always)]
+ pub unsafe fn set_r12(&mut self, value: u32) {
+ self.r12 = value;
+ }
+
+ /// Sets the stacked value of the Link Register.
+ ///
+ /// # Safety
+ ///
+ /// This affects the `lr` register of the preempted code, which must not rely on it getting
+ /// restored to its previous value.
+ #[inline(always)]
+ pub unsafe fn set_lr(&mut self, value: u32) {
+ self.lr = value;
+ }
+
+ /// Sets the stacked value of the Program Counter.
+ ///
+ /// # Safety
+ ///
+ /// This affects the `pc` register of the preempted code, which must not rely on it getting
+ /// restored to its previous value.
+ #[inline(always)]
+ pub unsafe fn set_pc(&mut self, value: u32) {
+ self.pc = value;
+ }
+
+ /// Sets the stacked value of the Program Status Register.
+ ///
+ /// # Safety
+ ///
+ /// This affects the `xPSR` registers (`IPSR`, `APSR`, and `EPSR`) of the preempted code, which
+ /// must not rely on them getting restored to their previous value.
+ #[inline(always)]
+ pub unsafe fn set_xpsr(&mut self, value: u32) {
+ self.xpsr = value;
+ }
}
impl fmt::Debug for ExceptionFrame {