当前位置: 首页 > ds >正文

【STM32】CUBEMX下FreeRTOS 任务栈管理与栈溢出检测(CMSIS_V2接口)

一、FreeRTOS 中的栈管理机制

在 FreeRTOS 中,每个任务都会分配一个独立的栈空间用于保存局部变量、上下文等。

✅ 相关宏配置:
宏名称含义
configMINIMAL_STACK_SIZE最小任务栈大小(单位:words)
uxTaskGetStackHighWaterMark()获取当前任务历史上最小的剩余栈空间(越小越危险)
uxTaskGetSystemState()获取所有任务的栈使用情况
configCHECK_FOR_STACK_OVERFLOW是否开启栈溢出检测(值为 1 或 2)
configUSE_TRACE_FACILITY开启任务信息追踪(如任务名、栈)
configUSE_STATS_FORMATTING_FUNCTIONS开启格式化任务状态打印支持

二、FreeRTOS 栈溢出检测机制

🧪 启用检测:

CUBEMX配置参数:
在这里插入图片描述

#define configUSE_TRACE_FACILITY        1
#define configUSE_STATS_FORMATTING_FUNCTIONS 1
#define configCHECK_FOR_STACK_OVERFLOW  2

configCHECK_FOR_STACK_OVERFLOW :

  • 1:简单检测方法,只在任务切换时检查栈顶哨兵值是否被改写。
  • 2:更强的检测方法,除了栈顶哨兵值,还检查栈底向上是否越界。
🛠 栈溢出钩子函数(CUBEMX自动生成):
extern void MX_LWIP_Init(void);
void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) *//* Hook prototypes */
void vApplicationStackOverflowHook(xTaskHandle xTask, signed char *pcTaskName);/* USER CODE BEGIN 4 */
void vApplicationStackOverflowHook(xTaskHandle xTask, signed char *pcTaskName)
{/* Run time stack overflow checking is performed ifconfigCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook function iscalled if a stack overflow is detected. */printf("\r\n");printf("=============================================================\r\n");printf("!!!!                 STACK OVERFLOW DETECTED             !!!!\r\n");printf("=============================================================\r\n");printf(">>> Task causing overflow : %s\r\n", pcTaskName);printf(">>> Taking emergency action: system halted\r\n");printf("=============================================================\r\n");// 关闭中断,进入死循环taskDISABLE_INTERRUPTS();for (;;);
}
/* USER CODE END 4 */

三、如何查看任务的剩余栈空间

使用 uxTaskGetSystemState()usStackHighWaterMark 获取每个任务曾经最小剩余栈空间

🧾 自定义打印函数:
void printTaskStackInfo(void)
{TaskStatus_t taskStatusArray[24];UBaseType_t taskCount, i;taskCount = uxTaskGetSystemState(taskStatusArray, 24, NULL);qsort(taskStatusArray, taskCount, sizeof(TaskStatus_t), compareTaskName);printf("\r\n+------------------+------------------------+------------------+\r\n");printf("| %-16s | %-22s | %-16s |\r\n", "任务名", "剩余栈空间 (words)", "剩余栈空间 (bytes)");printf("+------------------+------------------------+------------------+\r\n");for (i = 0; i < taskCount; i++){const char *name = taskStatusArray[i].pcTaskName;UBaseType_t highWater = taskStatusArray[i].usStackHighWaterMark;printf("| %-16s | %-22u | %-16u |\r\n", name, highWater, highWater * sizeof(StackType_t));}printf("+------------------+------------------------+------------------+\r\n");
}
  • 输出结果:
    在这里插入图片描述

四、FreeRTOS 任务模板函数(带栈使用示例)

void myTask(void *argument)
{while (1){// 模拟工作vTaskDelay(pdMS_TO_TICKS(1000));// 检查自身栈剩余空间(单位:words)UBaseType_t stackLeft = uxTaskGetStackHighWaterMark(NULL);if (stackLeft < 50)  // 阈值根据实际栈大小设定{printf("⚠️ Warning: task '%s' low stack: %lu words\r\n", pcTaskGetName(NULL), stackLeft);}}
}

五、建议:如何设置合适的任务栈大小?

  1. 开发初期可以设得大一点,如 512 words
  2. 启动任务后运行一段时间,调用 printTaskStackInfo()
  3. 看实际 剩余栈空间,酌情缩小分配。
  4. 建议保留 安全边际(>50 words),避免任务创建失败或运行中溢出。

http://www.xdnf.cn/news/16389.html

相关文章:

  • 【深入探究系列(6)】算法设计:高效算法的实现与优化
  • 机器学习 KNN 算法,鸢尾花案例
  • DP4871音频放大芯片3W功率单通道AB类立体声/音频放大器
  • Python day24
  • 残月头像阁
  • Vue3中的标签 ref 与 defineExpose:模板引用与组件暴露
  • Java零基础入门学习知识点2-JDK安装配置+Maven
  • vue3 组件生命周期,watch和computed
  • 【ResNet50图像分类部署至RK3588】模型训练→转换RKNN→开发板部署
  • Agent领域,近年来的前沿研究方向:多智能体协作、认知启发架构、伦理安全、边缘计算集成
  • 《计算机组成原理与汇编语言程序设计》实验报告一 基本数字逻辑及汉字显示
  • Avalonia 发布完cv到Linux上运行 出现字体丢失/不显示问题
  • 【C++详解】模板进阶 非类型模板参数,函数模板特化,类模板全特化、偏特化,模板分离编译
  • 【第十二篇】 SpringBoot定时任务
  • 详解FreeRTOS开发过程(八)-- 时间标志
  • HyperWorks教程:HyperWorks助力精准打造游艇的设计
  • SIP广播对讲系统:构建高效智能的语音通信网络
  • 一道检验编码能力的字符串的题目
  • Vue2-VueRouter
  • 刷题日记0725
  • Python,仿生计算新前沿:Python实现进化-强化学习混合算法
  • php语法--foreach和in_array的使用
  • HttpServletRequest知识点
  • 线性代数 下
  • Oracle转Mysql建表脚本
  • RocketMQ常见问题梳理
  • IDM:registered with a fake serial number
  • 【JavaEE】Spring Web MVC(上)
  • NineData 数据库 DevOps 全面支持 GaussDB,国产化管理再升级!
  • Canal 1.1.7的安装