Skip to content

Commit

Permalink
Adds a paint-stack feature.
Browse files Browse the repository at this point in the history
Paints the stack with a fixed 0xcccccccc value, which makes it easier to see the stack high-water mark.

Also update the qemu.rs example to verify a .data value and a .bss value.
  • Loading branch information
thejpster committed Aug 7, 2024
1 parent 6e4da72 commit ab76798
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 10 deletions.
1 change: 1 addition & 0 deletions cortex-m-rt/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ device = []
set-sp = []
set-vtor = []
zero-init-ram = []
paint-stack = []

[package.metadata.docs.rs]
features = ["device"]
14 changes: 12 additions & 2 deletions cortex-m-rt/examples/qemu.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,25 @@
#![no_main]
#![no_std]

use core::fmt::Write;
use core::{
fmt::Write,
sync::atomic::{AtomicU32, Ordering},
};

static DATA_VAL: AtomicU32 = AtomicU32::new(1234);

static BSS_VAL: AtomicU32 = AtomicU32::new(0);

#[cortex_m_rt::entry]
fn main() -> ! {
let x = 42;

loop {
let mut hstdout = cortex_m_semihosting::hio::hstdout().unwrap();
write!(hstdout, "x = {}\n", x).unwrap();
// check that .data and .bss were initialised OK
if DATA_VAL.load(Ordering::Relaxed) == 1234 && BSS_VAL.load(Ordering::Relaxed) == 0 {
_ = writeln!(hstdout, "x = {}", x);
}
cortex_m_semihosting::debug::exit(cortex_m_semihosting::debug::EXIT_SUCCESS);
}
}
Expand Down
43 changes: 35 additions & 8 deletions cortex-m-rt/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,13 @@
//! value to the `_ram_end` value from the linker script. This is not usually required, but might be
//! necessary to properly initialize memory integrity measures on some hardware.
//!
//! ## `paint-stack`
//!
//! Everywhere between `__sheap` and `___stack_start` is painted with the fixed value `STACK_PAINT_VALUE`.
//! You can then inspect memory during debugging to determine how much of the stack has been used
//! - where the stack has been used the 'paint' will have been 'scrubbed off' and the memory will
//! have a value other than `STACK_PAINT_VALUE`.
//!
//! # Inspection
//!
//! This section covers how to inspect a binary that builds on top of `cortex-m-rt`.
Expand Down Expand Up @@ -467,6 +474,13 @@

extern crate cortex_m_rt_macros as macros;

/// The 32-bit value the stack is painted with before the program runs.
///
/// Note: keep this value in-sync with the start-up assembly code, as we can't
/// use const values in `global_asm!` yet.
#[cfg(feature = "paint-stack")]
pub const STACK_PAINT_VALUE: u32 = 0xcccc_cccc;

#[cfg(cortex_m)]
use core::arch::global_asm;
use core::fmt;
Expand Down Expand Up @@ -545,24 +559,37 @@ cfg_global_asm! {
"ldr r0, =__sbss
ldr r1, =__ebss
movs r2, #0
2:
0:
cmp r1, r0
beq 3f
beq 1f
stm r0!, {{r2}}
b 2b
3:",
b 0b
1:",

// If enabled, paint stack/heap RAM with 0xcccccccc.
// `__sheap` and `_stack_start` come from the linker script.
#[cfg(feature = "paint-stack")]
"ldr r0, =__sheap
ldr r1, =_stack_start
ldr r2, =0xcccccccc // This must match STACK_PAINT_VALUE
0:
cmp r1, r0
beq 1f
stm r0!, {{r2}}
b 0b
1:",

// Initialise .data memory. `__sdata`, `__sidata`, and `__edata` come from the linker script.
"ldr r0, =__sdata
ldr r1, =__edata
ldr r2, =__sidata
4:
0:
cmp r1, r0
beq 5f
beq 1f
ldm r2!, {{r3}}
stm r0!, {{r3}}
b 4b
5:",
b 0b
1:",

// Potentially enable an FPU.
// SCB.CPACR is 0xE000_ED88.
Expand Down

0 comments on commit ab76798

Please sign in to comment.