裸机或cmsis_os2下的栈监控

张开发
2026/4/21 13:11:03 15 分钟阅读

分享文章

裸机或cmsis_os2下的栈监控
参考cmsis_os2文档bsp_stack.h#ifndefBSP_STACK_H#defineBSP_STACK_H#includestdint.h/** 线程栈和裸机栈是独立的 **/#ifdef__cplusplusexternC{#endif// 填充裸机栈底区域为 MAGIC_VALUE用于标识栈的使用情况voidBspStackFillMagic(void);// 获取当前栈使用的空间即从栈顶到栈指针的距离uint32_tBspGetCurrentStackUsage(void);// 获取裸机系统占用的最大栈空间// 这个函数通过遍历栈底区域来找到栈的最大使用空间uint32_tBspGetMaxStackUsage(void);// 获取栈的总大小通常与栈大小宏 BSP_STACK_SIZE 相同uint32_tBspGetStackTotal(void);// 获取当前任务的剩余栈空间// 此函数用于监控任务栈剩余空间防止栈溢出uint32_tBspOsThreadGetStackSpace(void);// 检查裸机栈是否发生溢出// 如果栈底的 MAGIC_VALUE 被修改则表示发生了栈溢出uint8_tBspIsStackOverflow(void);#ifdef__cplusplus}#endif#endifbsp_stack.c/* bsp_stack.c */#includebsp_stack.h#includestm32g0xx_hal.h#includecmsis_os2.h/* 与 startup_stm32g070xx.s 中 Stack_Size EQU 保持一致 */#defineBSP_STACK_SIZE0x1000U#defineMAGIC_VALUE0xDEADBEEFU/* __initial_sp 在 __MICROLIB 下已默认导出无需改汇编 */externuint32_t__initial_sp;#defineSTACK_TOP((uint32_t)__initial_sp)#defineSTACK_BOTTOM(STACK_TOP-BSP_STACK_SIZE)voidBspStackFillMagic(void){uint32_t*bottom(uint32_t*)STACK_BOTTOM;uint32_t*current_sp(uint32_t*)__get_MSP();for(uint32_t*pbottom;pcurrent_sp;p){*pMAGIC_VALUE;}}uint32_tBspGetCurrentStackUsage(void){uint32_tsp__get_MSP();if(spSTACK_TOP)return0U;returnSTACK_TOP-sp;}uint32_tBspGetMaxStackUsage(void){uint32_t*bottom(uint32_t*)STACK_BOTTOM;uint32_t*top(uint32_t*)STACK_TOP;uint32_t*pbottom;while((ptop)(*pMAGIC_VALUE)){p;}returnSTACK_TOP-(uint32_t)p;}uint32_tBspGetStackTotal(void){returnBSP_STACK_SIZE;}uint8_tBspIsStackOverflow(void){uint32_t*bottom(uint32_t*)STACK_BOTTOM;for(inti0;i4;i){if(bottom[i]!MAGIC_VALUE)return1U;}return0U;}uint32_tBspOsThreadGetStackSpace(void){//线程栈大小//osThreadGetStackSize(osThreadGetId());returnosThreadGetStackSpace(osThreadGetId());}用法main.cmain入口填充裸机栈 BspStackFillMagic();stackBuf 测试裸机栈, 让裸机栈至少占用300intmain(void){volatileuint8_tstackBuf[300];uint32_ti;for(i0;isizeof(stackBuf);i){stackBuf[i]0xAA;}BspStackFillMagic();BspInit();osKernelInitialize();__ctMain.Start();osKernelStart();while(1){}}打开cmsis_os2 堆栈水印开关#defineOS_STACK_WATERMARK1//当前线程栈容量osThreadGetStackSize(osThreadGetId());//当前线程剩余栈osThreadGetStackSpace(osThreadGetId());

更多文章