Skip to content

Instantly share code, notes, and snippets.

@kaidokert
Created July 12, 2025 02:59
Show Gist options
  • Save kaidokert/307bcd99ead724528286e9b43acf3543 to your computer and use it in GitHub Desktop.
Save kaidokert/307bcd99ead724528286e9b43acf3543 to your computer and use it in GitHub Desktop.
Quick and dirty cortex m stack watermarking
extern "C" {
static _stack_start: u32; // End of the stack (top of memory)
static _ram_length: u32; // Total RAM length (stack size in bytes)
}
const SAFE_ZONE_BYTES: usize = 256; // Reserve top and bottom bytes
#[inline(always)]
pub fn check_stack_high_water_mark() -> usize {
check_stack_high_water_mark_inner::<SAFE_ZONE_BYTES>()
}
#[inline(always)]
pub fn paint_stack() {
paint_stack_inner::<SAFE_ZONE_BYTES>();
}
pub fn paint_stack_inner<const SAFE_ZONE_BYTES: usize>() {
unsafe {
let stack_start = &_stack_start as *const u32 as *mut u8;
let stack_size = &_ram_length as *const u32 as usize;
let stack_end: *mut u8 = stack_start.offset(-(stack_size as isize));
let safe_stack_end = stack_end.offset(SAFE_ZONE_BYTES as isize);
let bytes_to_write = stack_size - (2 * SAFE_ZONE_BYTES);
core::ptr::write_bytes(safe_stack_end, 0xAA, bytes_to_write);
}
}
pub fn check_stack_high_water_mark_inner<const SAFE_ZONE_BYTES: usize>() -> usize {
unsafe {
let stack_start = &_stack_start as *const u32 as *mut u8;
let stack_size = &_ram_length as *const u32 as usize;
let stack_end = stack_start.offset(-(stack_size as isize));
let safe_stack_end = stack_end.offset(SAFE_ZONE_BYTES as isize);
let mut current = safe_stack_end;
while current < stack_start && *current == 0xAA {
current = current.offset(1);
}
let used_stack = stack_start.offset_from(current) as usize;
used_stack
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment