UCOSIII下串口中断服务中使用OSIntEnter函数使程序卡死解决方案
本文侧重于 STM32 标准库,HAL 库可以借鉴,因为该项目是基于标准库做的(因为涉及到保密,这里我就张贴源码进行描述了)。
因项目需求,需要使用RTOS实时操作系统来完成单片机程序的应用开发,今天在串口模块开发完成后自测,功能实现没有问题,问题出在串口在高频数据收发下,会造成整个程序卡死(因为只对串口收发模块做了改动,所以可以直接锁定问题出处,就死在串口收发上),用Debug进行程序调试,发现卡死的程序最终都会跑飞,一直在中断函数HardFault_Handler中死循环。
/**
* @brief This function handles Hard Fault exception.
* @param None
* @retval None
*/
void HardFault_Handler(void)
{
/* Go to infinite loop when Hard Fault exception occurs */
while (1)
{
}
}
在学习了众多资料后,得出了一个结论,就是只要是中断函数,我们都把函数 OSIntEnter 与 函数 OSIntExit 怼起来(这里加删除线的原因是因为,这句话大部分时候是正确的,但有时候还是不管用,不要记住这句话,因为他是不完美的) ,大致形式如下:
void XXX_IRQHandler()
{
OSIntEnter();
。。。
OSIntExit();
}
基于以上的形式,我对串口中断服务函数做了相同的处理,为了避免中断被打断,我还加了函数 OSSemPend 与函数 OSSemPost 来确保串口在数据接收过程中不被打断,在中间还使用了函数 OSQPost 来提交消息队列,把完整有效的数据帧传递到一个任务中进行处理。
在高频的串口数据收发模式下,我在网上查阅了很多资料,然而并没有把问题解决掉,我看有篇文章说有情况下的函数 OSIntEnter 使用会带来很大开销,然后又用 ChatGPT 查了一下,初步判定函数 OSIntEnter 对程序卡死会有一定影响,屏蔽掉函数 OSIntEnter 与 函数 OSIntExit 后,测试,还是会卡死,不过正常使用的次数多了几次,接着把函数 OSSemPend 与函数 OSSemPost 也给屏蔽掉,发现串口高频收发正常了,程序也不会卡死了。
下面是一些chatGPT的截图:
学习分享,一起成长!以上为小编的经验分享,若存在不当之处,请批评指正!