STM32F407结合SEGGER SYS VIEW实现LED闪烁任务异常问题
FreeRTOS任务仅执行一次后停滞,System View显示持续运行空闲任务的问题排查
我在STM32F407开发板上运行FreeRTOS,通过J-Link使用SEGGER System View进行持续录制时遇到如下问题:
异常场景代码
任务仅执行一次后便一直运行空闲任务,不再重复执行:
status = xTaskCreate(task1_handler, "Task-1", 200, NULL, 1, &task_1_handle); configASSERT(status == pdPASS); void task1_handler(void* parameters) { while (1) { HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_12); // 翻转绿色LED //printf("LED1 toggled\n"); vTaskDelay(pdMS_TO_TICKS(10)); } }
正常场景代码
以下代码中任务可正常循环执行直至停止录制:
status = xTaskCreate(task1_handler,"Task-1",200,"Hello world from Task-1", 1 ,&task_1_handle); configASSERT(status == pdPASS); void task1_handler(void* parameters) { //char msg[100]; while(1) { printf("%s\n" , (char*)parameters); //snprintf(msg,100,"%s\n" , (char*)parameters); //SEGGER_SYSVIEW_PrintfTarget(msg); taskYIELD(); //vTaskDelay(pdMS_TO_TICKS(1000)); } }
已尝试增大RTT缓冲区,但问题未解决,附当前结果截图与预期结果截图。
排查方向与解决方案
1. 检查FreeRTOS系统节拍(SysTick)配置
vTaskDelay依赖系统节拍中断唤醒任务,节拍机制异常会直接导致任务无法重新调度:
- 确认
configTICK_RATE_HZ配置正确(通常设为1000,对应1ms节拍),确保pdMS_TO_TICKS(10)能正确转换为10个节拍周期。 - 验证SysTick中断优先级:FreeRTOS要求该优先级不高于
configMAX_SYSCALL_INTERRUPT_PRIORITY(需匹配NVIC优先级分组设置),优先级过高会导致节拍中断被屏蔽。 - 排查HAL库与FreeRTOS的SysTick冲突:若HAL_Init()初始化了SysTick,需确保FreeRTOS接管控制权(替换SysTick中断服务函数为
xPortSysTickHandler,或通过configUSE_TICK_HOOK兼容)。
2. 排查任务栈溢出风险
尽管第二个任务栈大小相同且正常运行,但GPIO操作或vTaskDelay可能隐含额外栈需求:
- 尝试增大任务栈大小测试:
xTaskCreate(task1_handler, "Task-1", 512, NULL, 1, &task_1_handle); - 开启FreeRTOS栈溢出检测:将
configCHECK_FOR_STACK_OVERFLOW设为1或2,实现vApplicationStackOverflowHook钩子函数定位溢出问题。
3. 检查System View录制配置
System View的部分设置可能干扰任务状态显示或调度:
- 确认未启用“Stop on Idle”等自动暂停录制的选项。
- 检查录制过滤规则,确保Task-1的事件未被过滤隐藏。
- 关闭System View录制,直接通过LED闪烁判断任务是否真的停滞(排除工具显示异常的可能)。
4. 验证GPIO操作的合法性
GPIO翻转操作若存在硬件配置错误,可能触发异常导致任务退出:
- 确认GPIOD端口时钟已使能,引脚配置为推挽输出模式。
- 添加HardFault钩子函数排查硬件异常:
void HardFault_Handler(void) { while(1); // 触发时会停在此处,便于调试定位 }
内容的提问来源于stack exchange,提问作者Rizwan Ahmad
相关产品推荐
相关产品推荐

