FreeRTOS Priority 引起的assert问题

项目场景:

`提示:FreeRTOS Priority 引起的assert问题


问题描述

提示:这里描述项目中遇到的问题:
当时在CM3平台timer0 callback中调用xQueueSendFromISR函数,导致assert 发生。如下图所示
在这里插入图片描述


原因分析:

1、查看port.c 得到死机的原因,如下
在这里插入图片描述
2、从上图可知是 Priority 优先级出了问题,由于用的是timer0 的callback,查看平台中对timer0 中断的IRQn_Type 定义,
在这里插入图片描述
freeRTOS 中允许中断嵌套的优先级如下图,优先级0~4 是不允许中断调用FreeRTOS 中的API函数。
在这里插入图片描述

3、从 https://blog.csdn.net/sinat_23338865/article/details/52640028 补充一下 优先级的一些知识,在此引用原文,如有不妥之处,请联系我删除,感谢。

解决方案:

调用原生API 重新设定timer0 的优先级

NVIC_SetPriority(Timer0_IRQn, 5);

心得,遇到问题不要慌,抽丝剥茧方可想到好的办法。

<think>好的,我现在需要帮助用户解决FreeRTOS系统卡死的问题。首先,用户提到了FreeRTOS卡死在sys调试的情况,可能涉及系统初始化、任务调度或中断处理的问题。我需要回忆一下FreeRTOS常见的卡死原因和解决方法,同时结合用户提供的引用内容来分析。 首先,用户提供的引用[2]提到了FreeRTOS的代码框架、运行方式、中断优先级和调度器,这可能与卡死有关。比如,中断优先级设置不当可能导致任务无法正常切换,或者调度器配置错误使得系统无法正确运行。另外,引用中的“中断驱动的运行方式”也提示我需要检查中断服务例程(ISR)是否正确处理,是否存在未清除的中断标志或长时间的中断阻塞。 接下来,我应该分步骤来排查问题。第一步,检查系统初始化是否正确,包括堆栈分配、硬件初始化和FreeRTOS的配置参数。比如,configTOTAL_HEAP_SIZE是否足够,configMAX_PRIORITIES是否合理。如果堆栈不足,可能导致内存溢出,进而系统崩溃。 第二步,检查任务调度。用户可能创建了多个任务,但优先级设置有问题,导致高优先级任务一直占用CPU,低优先级任务无法运行,或者任务间出现死锁。使用vTaskList()或uxTaskGetStackHighWaterMark()来查看任务状态和堆栈使用情况可能会有帮助。 第三步,分析中断处理。FreeRTOS要求某些中断的优先级必须低于或等于configMAX_SYSCALL_INTERRUPT_PRIORITY,否则可能破坏临界区,导致系统卡死。需要确认用户的中断优先级设置是否符合这个要求,特别是SysTick和PendSV中断的优先级是否最低。 第四步,检查临界区代码。如果在临界区内调用了可能导致任务切换的API函数(如vTaskDelay),或者在中断服务程序中没有使用正确的后缀(如xQueueSendFromISR),也可能导致系统卡死。需要确保这些API的正确使用。 第五步,利用调试工具,如断点、日志输出或硬件调试器,观察系统在何处卡住。比如,检查是否卡死在某个特定的函数或循环中,是否有断言失败的情况,或者堆栈溢出。 最后,用户可能需要生成相关问题,比如如何配置中断优先级,如何检测堆栈溢出,或者FreeRTOS的任务调度策略是怎样的。这些问题能帮助用户更全面地理解和解决类似问题。 综合以上思考,我需要将这些步骤整理成一个清晰的解答,确保用户能够逐步排查问题,并提供相关的解决方案和调试方法。</think>### FreeRTOS系统卡死调试方法及解决方案 #### 1. 检查系统初始化配置 - **堆内存分配**:确认`configTOTAL_HEAP_SIZE`是否足够。内存不足会导致分配失败,引发系统崩溃。例如: ```c #define configTOTAL_HEAP_SIZE ( ( size_t ) ( 32 * 1024 ) ) // 32KB堆空间 ``` - **任务优先级设置**:检查`configMAX_PRIORITIES`是否合理。若任务优先级过多或冲突,可能阻塞调度[^2]。 #### 2. 分析任务调度状态 - **查看任务列表**:通过`vTaskList()`输出任务状态,确认是否有任务占用CPU时间过长或死锁: ```c char taskListBuffer[512]; vTaskList(taskListBuffer); printf("%s\n", taskListBuffer); ``` - **堆栈溢出检测**:使用`uxTaskGetStackHighWaterMark()`监控任务堆栈使用量。返回值接近0时,需增大堆栈: ```c UBaseType_t stack = uxTaskGetStackHighWaterMark(NULL); ``` #### 3. 中断优先级与配置验证 - **中断优先级规则**:FreeRTOS要求可调用API的中断优先级**必须低于**`configMAX_SYSCALL_INTERRUPT_PRIORITY`。例如,若配置: $$configMAX_SYSCALL_INTERRUPT_PRIORITY = 5$$ 则所有调用FreeRTOS API的中断优先级需≤5,否则会破坏临界区导致卡死。 - **SysTick/PendSV优先级**:确认SysTick和PendSV中断优先级设置为最低(数值最大),避免抢占关键操作。 #### 4. 临界区代码检查 - **禁止在临界区调用阻塞函数**:例如`vTaskDelay()`或队列操作。以下代码会引发死锁: ```c taskENTER_CRITICAL(); vTaskDelay(100); // 错误!临界区内不可阻塞 taskEXIT_CRITICAL(); ``` - **中断服务程序(ISR)规范**:确保ISR中使用带`FromISR`后缀的API,如`xQueueSendFromISR()`,否则可能触发断言。 #### 5. 调试工具辅助定位 - **断言(Assert)信息**:启用`configASSERT()`并连接调试器,捕获具体的错误位置。 - **硬件断点**:在`vApplicationStackOverflowHook()`或`vApplicationMallocFailedHook()`中设置断点,捕捉堆栈溢出或内存分配失败。 - **日志追踪**:在任务函数关键节点添加输出,观察执行流程是否停滞。 #### 示例调试流程 ```c void vApplicationStackOverflowHook(TaskHandle_t xTask, char *pcTaskName) { printf("堆栈溢出! 任务名: %s\n", pcTaskName); while(1); // 触发断点 } int main() { xTaskCreate(task1, "T1", 512, NULL, 3, NULL); xTaskCreate(task2, "T2", 512, NULL, 4, NULL); vTaskStartScheduler(); // 若卡死在此处,需检查初始化或堆内存 return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值