《FreeRTOS的检测栈溢出一种方法》(uxTaskGetStackHighWaterMark())

时间:2023-02-08 15:14:39


为什么要栈检测

首先看我们创建每个任务使用者都是用自己的经验,这个任务大概占多大根据经验然后我们分配给它空间,但是任务栈空间的实际使用量会随着任务执行和中断处理过程上下浮动,所以FreeRTOS提供了一种检测栈剩余的接口。

注意事项

使用这个API首先要在FreeRTOS.h中打开uxTaskGetStackHighWaterMark

#ifndef INCLUDE_uxTaskGetStackHighWaterMark
    #define INCLUDE_uxTaskGetStackHighWaterMark 1
#endif
检测栈剩余函数的介绍

uxTaskGetStackHighWaterMark()

unsigned portBASE_TYPE uxTaskGetStackHighWaterMark( xTaskHandle xTask );

参数名

xTask  被查询任务的句柄,如果传入 NULL 句柄,则是自己任务的栈剩余

返回值

返回从任务启动栈空间具有的最小剩余量这个值越是接近 0,说明这个任务快溢出了。

下面是官网的介绍

Parameters:
xTask     The handle of the task being queried. A task may query its own high water mark by passing NULL as the xTask parameter.
Returns:
The value returned is the high water mark in words (for example, on a 32 bit machine a return value of 1 would indicate that 4 bytes of stack were unused). If the return value is zero then the task has likely overflowed its stack. If the return value is close to zero then the task has come close to overflowing its stack.
使用的事例

可以用单独的一个任务去检测需要检测的任务 Main函数

int main()
{
    if(xTaskCreate(stack_overflow_cat, "stack_overflow_cat", 512, NULL,1, NULL) != pdPASS){
        printf("[%s] stack_overflow error\n",__func__);
    }
    if(xTaskCreate(test_1, "test_1", 512, NULL,1,&pv_handle) != pdPASS){
        printf("[%s] test_1 error\n",__func__);
    }
    vTaskStartScheduler();
    for(;;);
}

检测的函数和demo函数

static xTaskHandle pv_handle = NULL;
void test_1(void *param)
{
    printf("test_1 stack:%d\n",(int)uxTaskGetStackHighWaterMark(NULL));
    for(;;)
    {
        /*各种操作*/
        vTaskDelay(10000);
    }
    vTaskDelete( NULL );
}
void stack_overflow_cat(void *param)
{

    for(;;)
    {
        printf("stack:%d\n",(int)uxTaskGetStackHighWaterMark(pv_handle));
        vTaskDelay(500);
    }
    vTaskDelete( NULL );
}

打印

statack:501   这个是test1刚进入的时候栈剩余
stack:347
stack:347
stack:347
stack:347
stack:347
stack:347