2024-07-08
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
Recently, I found that after merging some codes from other platforms into STM32, crash problems occurred, so I wanted to sort out the principles of crash troubleshooting on STM32 as a whole.
The above is a section of crash print information. After investigation, it was found that the timer stack depth of FreeRTOS was set too small, there were too many contents running in the timer running function, and the memory requested by each local variable could not be released in time, which eventually led to a crash.
Here we talk about the timer in FreeRTOS. In fact, it can be understood as a task, which is equivalent to creating a thread that keeps timing, and then polling the current timer list, and executing it when it finds which timer has expired.
Therefore, the memory size used by the timer also needs to be configured.
R0~R12 are general purpose registers
R13 is the stack pointer. Physically, there are two stack pointers:The main stack pointer (MSP) is the default stack pointer, which is selected for use after reset and when the processor is in processing mode; the other stack pointer is the process stack pointer (PSP), which can only be used in thread mode (when there is an RTOS)
R14 is the link register (LR), which is used to save the return address when a function or subroutine is called. At the end of a function or subroutine, program control can return to the calling program by loading the value of LR into the program counter (PC) and continue execution. During exception handling, LR is automatically updated to a special EXC_RETURN value.
For example, if a calls b, the address of b's sub-function is placed in the pc pointer at this time, and the address of a is placed in the LR. After b is executed, the address of a is placed in the LR into the PC pointer for execution.
A crash in ARM is actually an abnormal interrupt. When an interrupt occurs, the processor saves the current task status to the stack.
Stack Frame
A stack frame is a memory area used to store function parameters, local variables, return addresses, and other information during a function call.
When a function is called, STM32 allocates a stack frame for it. The size of the stack frame depends on factors such as the number of parameters, the number of local variables, and the optimization settings of the compiler.
Combining the above information, we can know that if we want to get which function crashed, we need to find the stack frame that was pushed when the exception interrupt was triggered, and this stack frame is stored in the R13 (Stack point) stack pointer.
In the crash handling function HardFault_Handler(), we find a way to get the content pointed to by the pointer of the R13 register and then print it out.
The STM32 microcontroller uses the ARM Cortex-M core, which has two stack pointers, one is the main stack pointer (MSP) and the other is the process stack pointer (PSP).
MSP (Main Stack Pointer): The main stack pointer is mainly used by the operating system kernel or interrupt service routine.
PSP (Process Stack Pointer): The process stack pointer is mainly used by user applications.
When the Cortex-M core returns to Thread mode, it can switch back to the main stack pointer MSP or the process stack pointer PSP according to the setting of the CONTROL register.
The PSP stores the context related to the running user application. Specifically, it includes the following:
一些或全部的通用寄存器的值,这些寄存器在用户程序运行时会使用。
Program Counter(PC):指向下一条将要执行的指令。
Processor Status Register(PSR)的值:包含标志位状态。
Stack pointer: Saves the location of the previous stack frame.
Usually, when switching tasks (also called context switching), this information is saved to the stack, and when a new task starts, its context information is restored from the stack.
It should be noted that what is saved will vary depending on the specific scheduling strategy and operating system design.
Determine the value of the LR/PC pointer
First we need to determine whether RTOS is used. If it is used, then our crash information should be stored in the PSP.
We need to read out this information first, and then when we know the values of LR and PC, we can find the crash point through the Debug method in keil5 or through the map file generated during the compilation process to find the corresponding crash point.
Right-click in the Disassembly window—