0级优化时osDelayUntil进入HardFaults
CUBE IDE与FREERTOS(CMSIS_V2)用于Nucleo STM32 F401 RE上当我在-O 0优化中使用osDelayUntil时,在osDelayUntil执行之后,程序转到HardFault。这个问题在其他级别的优化时不会出现。****** in main ****** const osThreadAttr_t defaultTask_attributes = {.name = "defaultTask",.priority = (osPriority_t) osPriorityNormal,.stack_size = 128 }; defaultTaskHandle = osThreadNew(StartDefaultTask, NULL, &defaultTask_attributes);void StartDefaultTask(void *argument){ /* USER CODE BEGIN 5 */ uint32_t tick; tick = osKernelGetTickCount(); /* Infinite loop */ for(;;) {tick += 1000U; // delay 1000 ticks periodicallyosDelayUntil(tick);HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5); } /* USER CODE END 5 */ }当禁用所有优化,GCC/Keil等编译器会严格按源代码顺序生成指令,可能插入大量中间变量和临时寄存器操作,导致堆栈使用量激增
若任务栈未预留足够容量,这些额外指令会导致栈指针越界,覆盖相邻内存区域,最终触发 HardFault
由于 O0 不进行死代码消除,即使某些路径不可达,这些变量仍会被保留并占用栈空间
栈向下增长的特性使得超界的局部变量可能改写内核关键数据
FreeRTOS 的调度器依赖中断实现上下文切换
如果在延迟期间发生中断嵌套,且中断服务例程也使用了相同的栈空间,则可能出现双重压栈,加速栈溢出
某项目中 SysTick 定时器中断与主任务同时访问同一寄存器变量,导致栈指针偏移量超过预期值
部分编译器为确保字对齐,会在结构体成员间自动填充字节
在 FreeRTOSConfig.h 中增大对应任务的宏定义,建议比默认值提高 50%~100%
在 HardFaultHandler 中解析 SPSR和 PC,判断异常发生时的调用链
页:
[1]