FreeRTOS stack overflow detection mechanism_attached source code analysis

1. Turn on the stack overflow detection function

freertos provides a stack overflow detection function, which can be enabled by defining the configCHECK_FOR_STACK_OVERFLOW macro in the FreeRTOSConfig.h file, and the detection stack overflow operation will be automatically performed when the task is switched

/*
 * 大于0时启用堆栈溢出检测功能,如果使用此功能 
 * 用户必须提供一个栈溢出钩子函数,如果使用的话
 * 此值可以为1或者2,因为有两种栈溢出检测方法 */
#define configCHECK_FOR_STACK_OVERFLOW			1   

2. The first stack overflow detection mechanism

When the configCHECK_FOR_STACK_OVERFLOW macro is 1, the first stack overflow detection mechanism is adopted. By comparing the stack top pointer and stack start pointer or
the stack top pointer and stack bottom pointer,
the source code of FreeRTOS is as follows

insert image description here


3. The second stack overflow detection mechanism

When the configCHECK_FOR_STACK_OVERFLOW macro is 2, the second stack overflow detection mechanism is used
to judge whether the last 16 bytes of data in the stack space are all equal to 0xa5 . If one of them is not equal to 0xa5, it means that the stack may overflow.
The following is the source code of FreeRTOS

3.1 When the stack grows downward: determine whether the first 4 bytes of data on the stack have been modified

insert image description here

3.2 When the stack grows upwards: determine whether the 20 bytes of data at the end of the stack have been modified

insert image description here

Where did 0xa5 come from, see the source code

When using the vTaskCreate function to create a new task, if the value of the configCHECK_FOR_STACK_OVERFLOW macro is 2,
the stack space will be filled with 0x5a (taskSTAC_FILL_BYTE macro)

insert image description here


4. Determine the timing of stack overflow

Of course, when the task is switched, that is, in the vTaskSwitchContext(void) function, the function
taskCHECK_FOR_STACK_OVERFLOW() is called in this function . This function can be seen in the first two pictures above, but it is not marked.

void vTaskSwitchContext( void )
{
    
    
	if( uxSchedulerSuspended != ( UBaseType_t ) pdFALSE )
	{
    
    
		/* The scheduler is currently suspended - do not allow a context
		switch. */
		xYieldPending = pdTRUE;
	}
	...
	...
	/* Check for stack overflow, if configured. */
	taskCHECK_FOR_STACK_OVERFLOW();  //检查栈溢出
	...
	...
}	

At this point, the stack overflow detection mechanism of FreeRTOS has been clarified, yes!


5. Advantages and disadvantages of the two methods

method one:

  1. Advantages: fast
  2. Disadvantages: Cannot detect all stack overflows. For example, the stack top pointer crosses the bounds during task execution, but the stack top pointer points back to the legal position before task switching. At this time, the stack overflow cannot be detected.

Method Two:

  1. Pros: slightly slower than method one (but still fast for users)
  2. Disadvantages: Although almost all stack overflow situations can be detected, if the stack overflow value is the same as the stack mark value when the stack overflows , that is, the last four bytes of the stack space are exactly 0xa5, the stack overflow cannot be detected in this case

6. How to avoid stack overflow

Reference blog: https://blog.csdn.net/fanxueya1322/article/details/86567390

  • Estimate the task stack size in advance, and set the task stack size to twice the memory size required by the task
  • To reduce the demand for stack space, do not define auto variables that take up a lot of memory . You should modify such variables into pointers and allocate memory from the heap space .
  • Do not pass large structures/unions/objects in function parameters , use references or pointers as function parameters.
  • Reduce the level of function calls, and use recursive functions with caution , such as A->B->C->A ring call.

Guess you like

Origin blog.csdn.net/HuangChen666/article/details/131911863