DUE TO SPAM, SIGN-UP IS DISABLED. Goto Selfserve wiki signup and request an account.
ARMv7-M Run Time Stack Checking
Overview
Nuttx supports facilities to verify the dynamically allocated stacks and fixed stacks used by the tasks and interrupt context running under Nuttx. There are 2 types of stack checking that can be used together or separately.
- The Stack Monitor
- Per function Call (ARMV7 Only)
The Stack Monitor
The use of the Stack Monitor application requires that CONFIG_STACK_COLORATION be enabled. This compile time option enables the writing of a know pattern STACK_COLOR to the stack memory at creation time. In the case of the idle task and interrupt, this is done in the code that runs just after reset at startup. This is known as stack coloring.
...
This brings us the the next method of stack checking.
Per function Call
This method of stack checking leverages the profiler hook mechanism supported by the compiler. Once enabled using CONFIG_ARMV7M_STACKCHECK, one register is set aside (R10 is the default) and the value of the base of stack is saved there (rBS). Then every function call will have a preamble and a postamble code added to it. The preamble ({{
...
__cyg_profile_func_enter
...
}}) checks the current stack pointer, minus a margin of 64 bytes (with an additional 136 bytes for the FP registers) against the value in the reserved register rBS. If the computed value lies below the value in rBS a hard fault is generated. The postamble code ({{
...
__cyg_profile_func_exit
...
}}) just returns to the caller.
...
As of commit 4942867 Register R11 will contain the value that the stack pointer would hit that caused the fault. This can be used to calculate the stack size needed for that task that faulted. To do so, take the difference of R10-R11 and round it up by 12 bytes (The round up is to make up for the 8 byte stack alignment and 4 byte decrease that may happen in the stack allocation) Then add that amount to the failing tasks stack size.
Details for Support of Per Call Stack Checking
Currently only ARMV7 derivatives support Per Call Stack Checking. Support requires the following components:
...
This is done for a given architecture in {{nuttxin nuttx/arch/arm/src/
...
<arch>
...
/Make.defs}}:
| Code Block |
|---|
ifeq ($(CONFIG_ARMV7M_STACKCHECK),y)
CMN_CSRCS += up_stackcheck.c
endif
|
The compiler flags are added in the nuttx/arch/arm/src/armv7-m/Toolchain.defs
TBD
| Code Block |
|---|
# enable precise stack overflow tracking
ifeq ($(CONFIG_ARMV7M_STACKCHECK),y)
INSTRUMENTATIONDEFINES = -finstrument-functions -ffixed-r10
endif
|
Other Considerations
If using the export build feature of Nuttx: For the runtime stack checking both the Application and Nuttx need to be built with the CONFIG_ARMV7M_STACKCHECK option set the same state, enabled or disabled. Any mismatch will created either compile time or runtime issues.