FreeRTOS有任务卡死

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的调写:

  • 可能跟任务优先级、资源争用或任务阻塞等问题导致的。

问题以及解决方案:

  • 1.任务优先级设置不正确:要按键任务的优先级比其他任务都要高。这样,当按键被按下时,它将立即响应。
  • 2.资源争用:如果按键任务和其他任务正在争用某些共享资源(例如,IO口、共享内存等),则会出现任务阻塞的情况。在访问共享资源时用适当的同步机制,例如信号量、互斥量等。
  • 3.任务阻塞:任务可能会由于等待事件而阻塞。例如,如果按键任务在等待队列中的数据,则它可能会一直阻塞,直到队列中有新数据。考虑用超时机制,保证任务不会一直阻塞。
  • 4.堆栈溢出:如果任务的堆栈空间不足,可能会任务卡死。保证每个任务都有足够的堆栈空间,根据需要增加堆栈大小。
  • 5.任务死循环:如果任务处于死循环中,则它将无法响应其他任务或中断。保证任务的代码中没有死循环。
  • 另外,考虑在FreeRTOS中启用任务监视器来检测任务阻塞的情况,以便能够及时发现问题并进行调试。

具体不知道什么情况,当时觉得如果可以的话,是不是可以在扫描按键哪里看可以加一个看门狗程序,如果出现卡死的情况,就让系统进行重启

有没有可能不是这个任务的问题,而是按键处理的问题

该回答引用于gpt与OKX安生共同编写:
  • 该回答引用于gpt与OKX安生共同编写:
  • 出现任务卡死的原因可能是因为有高优先级的任务一直占用了CPU时间,导致低优先级的任务得不到执行。你可以尝试增加按键扫描任务的优先级,让其比其他任务更高。你也可以使用FreeRTOS提供的堆栈溢出保护功能,以检查是否已经超出某个任务的堆栈,从而导致任务挂起。
  • 此外,你可以使用FreeRTOS的调试工具来分析任务卡死的原因。FreeRTOS提供了几种不同的调试工具,如vTaskList和vTaskGetRunTimeStats等,它们可以帮助你诊断任务卡死的根本原因。
  • 你还可以使用一些调试工具来检查是否存在死锁或死循环等问题,例如代码调试器或代码分析器。这些工具可以帮助你找到并修复任务卡死的问题。
  • 另一个可能的问题是堆栈大小。由于每个任务都需要一定的堆栈空间,如果任务需要的堆栈空间超过了其分配的堆栈空间,就会出现堆栈溢出的问题。在你的代码中,每个任务的堆栈大小为128字节,这可能不足以满足一些任务的需要。建议适当增加堆栈大小,并使用FreeRTOS提供的堆栈监控功能,以确保任务不会因为堆栈溢出而出现问题。

另外,建议在出现任务卡死时使用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大模型与博主波罗歌共同编写:
出现任务卡死的原因可能有多种,以下是一些可能的排查方法和解决方案:

  1. 检查任务优先级设置是否正确

在FreeRTOS中,任务的优先级数值越大,优先级越高。如果任务优先级设置不正确,比如两个任务的优先级相同,或者高优先级任务阻塞等待低优先级任务释放资源,就可能出现任务卡死的情况。建议按照任务功能和相互依赖关系进行优先级设置。

  1. 检查任务阻塞及调度策略是否合理

任务之间的阻塞和调度策略也会对系统稳定性产生影响。如果一个任务一直在等待某个资源,但该资源由另一个低优先级的任务持有,就可能导致任务阻塞或卡死。此时可以考虑调整任务之间的依赖关系,或者使用延时等待函数取代阻塞函数。

  1. 检查任务堆栈和任务处理函数是否正常

任务堆栈不够大或者任务处理函数出现异常,都可能导致任务卡死。可以通过调整堆栈大小,或者加入平台相关的异常处理函数来解决问题。

下面是一个修改后的代码供您参考:

//创建按键扫描任务
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);

注:上文代码仅供参考,具体情况需根据实际项目需求来确定优先级和任务处理函数等。
如果我的回答解决了您的问题,请采纳!