STM32串口死机问题解决
前言
项目中出现一个偶现bug,最开始找了很长时间原因
现象是这样的,上位机是labview,上位机通过串口发送指令到单片机
单片机返回数据。
但是出现一个问题。短时间发送接收未出现任何问题,连续运行两天之后突然出现bug,上位机发送指令单片机无回复。
但是单片机确认代码还在“正常运行”因为其它功能还在正常工作,程序是裸机程序,但是只有连接上位机的串口1挂掉了。
漫长的debug
最开始考虑为硬件原因,因为之前遇到过上电浪涌把串口转USB芯片烧毁问题。
然后通过其它串口软重启发现串口一恢复正常。排除硬件问题。
首先要复现这个问题,在折腾了一天后发现,上位机单线程阻塞发送指令无法复现问题,上位机多线程不加锁往串口发送指令几秒便可以复现。
分析原因
分析上位机发送的数据,多线程未加锁发送数据时多组数据同时到达串口,会造成串口数据错乱,此时单片机不会对错误数据进行处理,所以无影响。
第二种情况便是多组数据到达串口,造成数据量过大,单片机由于是超时中断+DMA方式进行串口数据搬运,但是还是会有可能数据处理不及时造成数据积压,然后溢出。
这时查看串口1寄存器发现SR寄存器ORE位被置位,且一直处于置位状态。此时单片机中断还在不断触发,但是无后续数据处理。
解决方法
首先减少中断处理函数中任务量减少中断占用时间,然后启用串口的ORE错误中断,在触发ORE错误时清掉此错误位。
__HAL_UART_ENABLE_IT(&huart1, UART_IT_ERR);
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
{
uint8_t i = 0;
if(__HAL_UART_GET_FLAG(huart,UART_FLAG_ORE) != RESET)
{
__HAL_UART_CLEAR_OREFLAG(huart);//清除ORE错误位
HAL_UART_Receive_IT(huart,(uint8_t *)&i,1);//抛弃错误数据
}
}