FreeRTOS在单片机上长时间运行后,有任务卡死
是构建了四个任务,然后长时间运行后,按键根本不响应了,但是显示还在刷新,显示的数据来源于HT7036_task_function,数据是正确的,说明只有按键任务没有被2执行,这个现象只发生在长时间运行后,刚上电的第一天没有问题。
//创建按键扫描任务
xTaskCreate((TaskFunction_t )key_task_function,
(const char* )"key_task",
(uint16_t )128,
(void* )NULL,
(UBaseType_t )2,
(TaskHandle_t* )&keytask_handler);
//创建显示任务
xTaskCreate((TaskFunction_t )display_task_function,
(const char* )"display_task",
(uint16_t )128,
(void* )NULL,
(UBaseType_t )3,
(TaskHandle_t* )&display_handler);
//创建HT7036运行任务,读取电能数据
xTaskCreate((TaskFunction_t )HT7036_task_function,
(const char* )"HT7036_task",
(uint16_t )128,
(void* )NULL,
(UBaseType_t )2,
(TaskHandle_t* )&HT7036_handler);
//485数据接收超时检测
xTaskCreate((TaskFunction_t ) receiver_task_function,
(const char* ) "receiver_task",
(uint16_t ) 128,
(void* ) NULL,
(UBaseType_t ) 2,
(TaskHandle_t* ) &receiver_handler);
基于Monster 组和GPT的调写:
问题以及解决方案:
具体不知道什么情况,当时觉得如果可以的话,是不是可以在扫描按键哪里看可以加一个看门狗程序,如果出现卡死的情况,就让系统进行重启
有没有可能不是这个任务的问题,而是按键处理的问题
该回答引用于gpt与OKX安生共同编写:
另外,建议在出现任务卡死时使用FreeRTOS提供的trace功能进行调试,以了解每个任务的执行情况和系统资源的使用情况。此外,如果你的应用程序需要复杂的同步或通信机制,请确保这些机制的正确性和稳定性,并避免死锁和竞态条件等问题。
最后,建议将你的代码分解成更小
基于bing、GPT部分内容和本人思考总结:
可能是因为任务优先级设置不合理导致的问题。在任务优先级设置中,key_task 和 HT7036_task 的优先级都是 2,而 display_task 的优先级是 3。这样会导致 key_task 和 HT7036_task 一直互相抢占 CPU 资源,而 display_task 一直在后面等待执行。如果 key_task 和 HT7036_task 运行时间过长,就会导致 display_task 无法及时得到执行,从而导致按键无法响应。
建议将 key_task 和 HT7036_task 的优先级降低,例如将它们的优先级设置为 1,这样就能够让 display_task 得到更多的 CPU 时间,从而保证按键响应的及时性。同时,可以在任务函数中增加适当的延时,以避免任务在短时间内抢占 CPU 资源过于频繁。如果问题仍然存在,可以考虑增加任务堆栈大小或者检查任务函数是否存在死循环等问题。
以下答案由GPT-3.5大模型与博主波罗歌共同编写:
出现任务卡死的原因可能有多种,以下是一些可能的排查方法和解决方案:
在FreeRTOS中,任务的优先级数值越大,优先级越高。如果任务优先级设置不正确,比如两个任务的优先级相同,或者高优先级任务阻塞等待低优先级任务释放资源,就可能出现任务卡死的情况。建议按照任务功能和相互依赖关系进行优先级设置。
任务之间的阻塞和调度策略也会对系统稳定性产生影响。如果一个任务一直在等待某个资源,但该资源由另一个低优先级的任务持有,就可能导致任务阻塞或卡死。此时可以考虑调整任务之间的依赖关系,或者使用延时等待函数取代阻塞函数。
任务堆栈不够大或者任务处理函数出现异常,都可能导致任务卡死。可以通过调整堆栈大小,或者加入平台相关的异常处理函数来解决问题。
下面是一个修改后的代码供您参考:
//创建按键扫描任务
xTaskCreate((TaskFunction_t )key_task_function,
(const char* )"key_task",
(uint16_t )128,
(void* )NULL,
(UBaseType_t )1, // 优先级设置为1
(TaskHandle_t* )&keytask_handler);
//创建显示任务
xTaskCreate((TaskFunction_t )display_task_function,
(const char* )"display_task",
(uint16_t )128,
(void* )NULL,
(UBaseType_t )2, // 优先级设置为2
(TaskHandle_t* )&display_handler);
//创建HT7036运行任务,读取电能数据
xTaskCreate((TaskFunction_t )HT7036_task_function,
(const char* )"HT7036_task",
(uint16_t )128,
(void* )NULL,
(UBaseType_t )3, // 优先级设置为3
(TaskHandle_t* )&HT7036_handler);
// 485数据接收超时检测
xTaskCreate((TaskFunction_t ) receiver_task_function,
(const char* ) "receiver_task",
(uint16_t ) 128,
(void* ) NULL,
(UBaseType_t ) 4, // 优先级设置为4,确保比其他任务都高
(TaskHandle_t* ) &receiver_handler);
注:上文代码仅供参考,具体情况需根据实际项目需求来确定优先级和任务处理函数等。
如果我的回答解决了您的问题,请采纳!