|
185 | 185 | //! value to the `_ram_end` value from the linker script. This is not usually required, but might be
|
186 | 186 | //! necessary to properly initialize memory integrity measures on some hardware.
|
187 | 187 | //!
|
| 188 | +//! ## `paint-stack` |
| 189 | +//! |
| 190 | +//! Everywhere between `__sheap` and `___stack_start` is painted with the fixed value |
| 191 | +//! `STACK_PAINT_VALUE`, which is `0xCCCC_CCCC`. |
| 192 | +//! You can then inspect memory during debugging to determine how much of the stack has been used - |
| 193 | +//! where the stack has been used the 'paint' will have been 'scrubbed off' and the memory will |
| 194 | +//! have a value other than `STACK_PAINT_VALUE`. |
| 195 | +//! |
188 | 196 | //! # Inspection
|
189 | 197 | //!
|
190 | 198 | //! This section covers how to inspect a binary that builds on top of `cortex-m-rt`.
|
|
225 | 233 | //! using the `main` symbol so you will also find that symbol in your program.
|
226 | 234 | //!
|
227 | 235 | //! - `DefaultHandler`. This is the default handler. If not overridden using `#[exception] fn
|
228 |
| -//! DefaultHandler(..` this will be an infinite loop. |
| 236 | +//! DefaultHandler(..` this will be an infinite loop. |
229 | 237 | //!
|
230 | 238 | //! - `HardFault` and `_HardFault`. These function handle the hard fault handling and what they
|
231 | 239 | //! do depends on whether the hard fault is overridden and whether the trampoline is enabled (which it is by default).
|
|
467 | 475 |
|
468 | 476 | extern crate cortex_m_rt_macros as macros;
|
469 | 477 |
|
| 478 | +/// The 32-bit value the stack is painted with before the program runs. |
| 479 | +// Note: keep this value in-sync with the start-up assembly code, as we can't |
| 480 | +// use const values in `global_asm!` yet. |
| 481 | +#[cfg(feature = "paint-stack")] |
| 482 | +pub const STACK_PAINT_VALUE: u32 = 0xcccc_cccc; |
| 483 | + |
470 | 484 | #[cfg(cortex_m)]
|
471 | 485 | use core::arch::global_asm;
|
472 | 486 | use core::fmt;
|
@@ -545,24 +559,37 @@ cfg_global_asm! {
|
545 | 559 | "ldr r0, =__sbss
|
546 | 560 | ldr r1, =__ebss
|
547 | 561 | movs r2, #0
|
548 |
| - 2: |
| 562 | + 0: |
| 563 | + cmp r1, r0 |
| 564 | + beq 1f |
| 565 | + stm r0!, {{r2}} |
| 566 | + b 0b |
| 567 | + 1:", |
| 568 | + |
| 569 | + // If enabled, paint stack/heap RAM with 0xcccccccc. |
| 570 | + // `__sheap` and `_stack_start` come from the linker script. |
| 571 | + #[cfg(feature = "paint-stack")] |
| 572 | + "ldr r0, =__sheap |
| 573 | + ldr r1, =_stack_start |
| 574 | + ldr r2, =0xcccccccc // This must match STACK_PAINT_VALUE |
| 575 | + 0: |
549 | 576 | cmp r1, r0
|
550 |
| - beq 3f |
| 577 | + beq 1f |
551 | 578 | stm r0!, {{r2}}
|
552 |
| - b 2b |
553 |
| - 3:", |
| 579 | + b 0b |
| 580 | + 1:", |
554 | 581 |
|
555 | 582 | // Initialise .data memory. `__sdata`, `__sidata`, and `__edata` come from the linker script.
|
556 | 583 | "ldr r0, =__sdata
|
557 | 584 | ldr r1, =__edata
|
558 | 585 | ldr r2, =__sidata
|
559 |
| - 4: |
| 586 | + 0: |
560 | 587 | cmp r1, r0
|
561 |
| - beq 5f |
| 588 | + beq 1f |
562 | 589 | ldm r2!, {{r3}}
|
563 | 590 | stm r0!, {{r3}}
|
564 |
| - b 4b |
565 |
| - 5:", |
| 591 | + b 0b |
| 592 | + 1:", |
566 | 593 |
|
567 | 594 | // Potentially enable an FPU.
|
568 | 595 | // SCB.CPACR is 0xE000_ED88.
|
@@ -872,6 +899,7 @@ pub static __ONCE__: () = ();
|
872 | 899 | /// Registers stacked (pushed onto the stack) during an exception.
|
873 | 900 | #[derive(Clone, Copy)]
|
874 | 901 | #[repr(C)]
|
| 902 | +#[allow(dead_code)] |
875 | 903 | pub struct ExceptionFrame {
|
876 | 904 | r0: u32,
|
877 | 905 | r1: u32,
|
|
0 commit comments