STM32串口DMA接收253字节就死机原因排查

日前做了一个方案,是关于STM32通过M5311连接MQTT服务器进行通信的。在各项参数测试完毕后,通过MQTT服务器下发了一个300bytes的设备参数配置指令,结果直接死机了。经过多次测试,问题现象具体确定为MQTT服务器发送253字节可以正常,发送大于254字节以上STM32必死机。

为定位问题原因,于是分开测试。先测试STM32的串口通信,串口DMA接收了500字节也正常。再单独测试M5311,串口发送了300字节也正常。这就郁闷了,俩单独都没问题,为啥到一起就死机了。

  1. 先怀疑是串口接收缓存不够,于是检查了一下,是1000字节,绰绰有余的啊!
  2. 再怀疑是串口ORE溢出导致死机,结果程序里跟踪了半天,没问题,它是被冤枉的。
  3. 检查串口波形,发现STM32的好像波特率稍微低了一点点,不过相互都能识别,应该是在误差范围内。把波特率调整了一点,问题涛声依旧啊。
  4. 再怀疑是DMA错误,程序跟踪检查,没错儿。
  5. 实在没办法了,那就跟踪串口中断函数把。在各个if–else里都添加了打印语句,一路跟踪下来,发现串口中断处理也是很完美的。它也是被冤枉的。
  6. 在串口中断处理完成以后,是服务器指令解析函数,最后检查它。居然问题就是它导致的!收到串口数据后,它先把数据搬运到另一个缓存数组,然后打开DMA接收下一批数据。问题就出在搬的时候,使用了for循环,而且使用了循环变量是uint8_t,但是退出循环的判断条件是超出255的,也就是无意间变成了死循环。所以死机了。
/********************************************************************
函 数 名:void Data_Transfer_To_Cache(void)
功能:数据缓存到另一个数组,然后立即再次打开DMA进行接收
参数:无
返回值:无
***********************************************************************/	
uint8_t Data_Transfer_To_Cache(void)
{
	//先立即转存,然后打开DMA接收,再进行判断
	uint8_t data_err = 0;
	Clear_Tmp_Sz();
	if(UART3_Rx_len<TP_LENGTH)//防止数组意外越界
	{
		for(uint16_t i=0;i<UART3_Rx_len;i++)
		{
			tmp_rx_sz[i] = UART3_Rx_buffer[i];
		}
		tmp_i = UART3_Rx_len;
	}
	else	
	{
		data_err = 1;
	}
	DMA_UART3_Start();//清空接收缓存,打开DMA继续接收
	
//	printf("\r\n%s\r\n",tmp_rx_sz);
	if(data_err)
	{
		printf("数据超出缓存!\r\n");
		return 0;
	}
	else
	{
		return 1;	
	}
}

这个函数负责搬砖,其中用的for(uint8_t i=0; i<UART3_Rx_len; i++)循环,在UART3_Rx_len大于255的时候,就陷入了死循环。这个是从以前的项目上直接copy过来的,根本没有考虑到这个 i 会出问题。
花了2天时间,从硬件到软件查了个遍,连串口波形都检查了,一个小小的问题浪费了很多时间,这是个教训。希望大家引以为戒吧,以后移植copy代码时候得仔细啊,或者干脆写这种循环的代码,i变量一律使用uint32_t类型,这个不可能出不去了。

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ydgd118

您的鼓励是我最大的动力!谢赏!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值