热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

stm32网口串口模块通信丢帧、死机问题的解决

首先描述问题,是我一同事而非我本人遇到的,公司让我协助他查找问题。客户是卫通地面站,主控电脑使用的是麒麟系统,通过UDP和我们的设备进行网络通信,客户每间隔一秒钟发送一次状态查询指

首先描述问题,是我一同事而非我本人遇到的,公司让我协助他查找问题。

客户是卫通地面站,主控电脑使用的是麒麟系统,通过UDP和我们的设备进行网络通信,客户每间隔一秒钟发送一次状态查询指令,一天的时间内会出现3到5次设备不响应指令的状态,客户判定为丢帧。通过查看客户的通讯日志,发现不响应的时间竟然差不多都是40秒钟以上,40秒后恢复了响应。

情况诡异。一开始同事怀疑是网口模块的问题,毕竟客户那里发的比较频繁,有可能说是模块收发的数据太多,导致了硬件异常,模块接收发送失败。还有某研究所的一哥们提醒说他觉得moxa的网口模块和麒麟系统不兼容,容易出问题。。。对这样的提议我表示怀疑,首先moxa的网口芯片肯定都是经过大量的测试的,不会说有问题就生产销售了。对麒麟的操作系统我虽然不了解但是我知道你网络通信出了你的网关就和你本身没关系了,跟你接什么样子的网口模块还有关系,真是让人不禁莞尔。

对未知故障的猜测人们往往会向对自己有利,与自己无关的一方面想,这是人的弱点也是本性但是抱着胡乱猜疑的态度去撇清自己的关系,实在不是科研人员的素养。

继续进行问题分析,我找了一块板子进行测试用,用网口助手给板子发数据,时间是1s发一次,短时间内并没有看到什么异常现象,于是加快发送的速度,改为500ms发一次,现象暴露了,出现了丢帧问题,一分钟的时间内都丢了几帧,这个丢帧率也是真的太高了吧。但是并没有出现客户所说的连续四十秒无响应的问题。

那么首先查找这个丢帧的问题吧。其实问题很隐蔽,所以在我调快发送速度的时候也就很容易出现了。

《stm32 网口 串口模块通信丢帧、死机问题的解决》

我同事他在中断里接收数据,收到数据后计数变量index增加,当接收数据为帧尾标志的时候(0x7E),便会产生一个标志位,一帧的长度最短在24个字节。他在主程序里判断到这个标志位后呢,便把index变量清零。

这样的操作方式在低频率通信时一点问题也没有,但是当通信数据增多,这样带来的问题就是,当接收完一帧数据后,主程序里还没来得及判断,又来了数据,index在之前的基础上自增,这样这一帧数据他看第【0】字节不是帧头,第【23】字节不是帧尾,帧头不对帧尾也不对就不做反应,直到index大于缓存区长度64后,再清零。

为了解决这个问题,我让他开辟了一个FIFO,数据来了,先存进FIFO了,这样不管来多少帧数据,主程序里都能一一判断到,无非是实时性不好,但是不会丢帧。

这个问题解决了,那么客户反应的40多秒无响应是怎么回事呢?

其实在找第一个bug的过程中,我就发现了一些端倪,就是每次我给板子重启,网口模块一般在30s左右的时候才能正常接收到数据并能够发送,于是我不得不猜测,是什么问题导致了网口模块发生了硬件故障从而重启了么?是第一个BUG引起了网口模块硬件异常从而重启了吗?未必不可能,但有些牵强,因为在上面的测试过程中我确实没有遇见过客户说的现象,也即网口模块重启的现象。而且时间似乎也并不能够对的上。

阴谋论的迷雾再次笼罩了我的大脑。会不会真的是客户那里有问题呢?这时候我们和客户进行了一次通话,客户说他们是两个线程在发数据,一个线程发查询状态,一个线程发控制命令。我问,如果两个发送命令撞帧了呢,会产生什么后果吗?

客户思考了一会说,有可能,但我们站上其他厂商的设备没有出现问题,我还很忙,先挂了。

大写的尴尬。冷静下来思考一下,从TCP/IP协议的多层结构开看,从一个电脑出来的数据,即便是两个线程发,协议栈也不会把两个数据揉在一起,因为网络协议栈只有一个,一个线程在发的时候另一个一定会阻塞。不可能两个同时调用,因此从技术层面来说撞帧实现不了。

此时怀疑是stm32产生了硬件异常,进入了中断,从而导致了看门狗超时让设备重启,这样的话,时间就能够对的上了。

那就在所有可能出现硬件异常中断的地方打上断点。然而让程序运行了一段时间后就是不见进硬件异常中断。

再次压力测试,加快发送数据的频率,我提高到了每100ms发送一帧查询指令。一个不经意间一看,竟然出现了只发不回的情况!我激动的看程序的调试界面,赶紧在数据接收这里打了一个断点,咦,这数据也正在接收啊,那就很匪夷所思了:

1. 程序没有进入异常中断,证明不是看门狗引起的硬件异常从而导致重启;

2. 在出现问题后我赶紧用cmd去ping板子,发现一开始能ping通,但是过一会就故障了,然后又能ping通;

2. 程序能够接收到,但是好像没有发出来,还没等我去查为啥没发的原因,网口已经恢复正常了。又开始发了(40s时间过去了)

好不容易复现的现象稍纵即逝。怀疑是不是网口模块出现故障,只能收不能发,然后自己重启了呢?

我又陷入了不断的自我怀疑和相互怀疑之中。

“再加点压力!”我想。我直接把发送时间改成了5ms一次,结果现象非常容易复现了,这时候打断点,发现了根本问题:

网口模块根本没有重启,是单片机的重启带动了网口模块的复位,而且单片机也根本没有进入异常中断,而是说不断地进入了一个中断!

不断进入中断的原因被我发现了,第一个判断条件根本就没有通过,原因是定时器竟然是DISABLE的?

《stm32 网口 串口模块通信丢帧、死机问题的解决》

同事在接收到帧头数据的时候关闭了定时器2,(可能是想接收数据不被打断…)即调用了STOP_TIME这个宏;

《stm32 网口 串口模块通信丢帧、死机问题的解决》

但是关定时器的操作有点迷:

#define START_TIME RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 , ENABLE);TIM_Cmd(TIM2, ENABLE)
#define STOP_TIME TIM_Cmd(TIM2, DISABLE);RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 , DISABLE)

使能/失能定时器的时候,干嘛还给RCC时钟树使能/失能呢?这样导致的问题就是,我在执行START_TIME时,被STOP_TIME中断,导致时钟树是关闭的,但定时是开启的,开启定时产生了计时,溢出后产生中断,但是被判断定时器是失能 的,这就导致中断清除不掉 ,但是串口又能接收数据(串口优先级比定时器高),同时看门狗一直喂不了狗,导致重启。。。。

《stm32 网口 串口模块通信丢帧、死机问题的解决》

问题找到后,同事去给客户重新烧录了程序,经过了一天的观察,问题再也没有复现,悬着的心终于落下了…


推荐阅读
  • 本文介绍了Java工具类库Hutool,该工具包封装了对文件、流、加密解密、转码、正则、线程、XML等JDK方法的封装,并提供了各种Util工具类。同时,还介绍了Hutool的组件,包括动态代理、布隆过滤、缓存、定时任务等功能。该工具包可以简化Java代码,提高开发效率。 ... [详细]
  • 开发笔记:计网局域网:NAT 是如何工作的?
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了计网-局域网:NAT是如何工作的?相关的知识,希望对你有一定的参考价值。 ... [详细]
  • 本文介绍了Paxos的世界中关于复制日志与状态机的概念和重要性。通过存储日志来实现数据的持久化,并通过日志流来记录数据的变化,而不是直接持久化数据本身。这样做的好处是简化了持久化存储的操作,并且方便多机之间的数据同步。 ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • 图解redis的持久化存储机制RDB和AOF的原理和优缺点
    本文通过图解的方式介绍了redis的持久化存储机制RDB和AOF的原理和优缺点。RDB是将redis内存中的数据保存为快照文件,恢复速度较快但不支持拉链式快照。AOF是将操作日志保存到磁盘,实时存储数据但恢复速度较慢。文章详细分析了两种机制的优缺点,帮助读者更好地理解redis的持久化存储策略。 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • 本文介绍了在CentOS 7.x上进行端口映射配置的方法,通过修改内核和配置防火墙实现端口映射。作者分享了自己使用华为服务器进行端口映射的经验,发现网速比直连还快且稳定。详细的配置过程包括开启系统路由模式功能、设置IP地址伪装、设置端口映射等。同时,还介绍了如何监听本地端口的tcp请求,以及删除规则和开放的端口的方法。 ... [详细]
  • Linux如何安装Mongodb的详细步骤和注意事项
    本文介绍了Linux如何安装Mongodb的详细步骤和注意事项,同时介绍了Mongodb的特点和优势。Mongodb是一个开源的数据库,适用于各种规模的企业和各类应用程序。它具有灵活的数据模式和高性能的数据读写操作,能够提高企业的敏捷性和可扩展性。文章还提供了Mongodb的下载安装包地址。 ... [详细]
  • 集成电路企业在进行跨隔离网数据交换时面临着安全性问题,传统的数据交换方式存在安全性堪忧、效率低下等问题。本文以《Ftrans跨网文件安全交换系统》为例,介绍了如何通过丰富的审批流程来满足企业的合规要求,保障数据交换的安全性。 ... [详细]
  • 本文介绍了操作系统的定义和功能,包括操作系统的本质、用户界面以及系统调用的分类。同时还介绍了进程和线程的区别,包括进程和线程的定义和作用。 ... [详细]
  • 篇首语:本文由编程笔记#小编为大家整理,主要介绍了软件测试知识点之数据库压力测试方法小结相关的知识,希望对你有一定的参考价值。 ... [详细]
  • 本文介绍了H5游戏性能优化和调试技巧,包括从问题表象出发进行优化、排除外部问题导致的卡顿、帧率设定、减少drawcall的方法、UI优化和图集渲染等八个理念。对于游戏程序员来说,解决游戏性能问题是一个关键的任务,本文提供了一些有用的参考价值。摘要长度为183字。 ... [详细]
  • POCOCLibraies属于功能广泛、轻量级别的开源框架库,它拥有媲美Boost库的功能以及较小的体积广泛应用在物联网平台、工业自动化等领域。POCOCLibrai ... [详细]
  • slmp协议和mc协议区别_TCP协议与UDP协议的区别
    TCP协议和UDP协议TCPIP协议是一个协议簇。里面包括很多协议的,UDP只是其中的一个,之所以命名为TCPIP协议,因 ... [详细]
  • UDP千兆以太网FPGA_verilog实现(四、代码前期准备UDP和IP协议构建)
    UDP:userDatagramprotocol用户数据报协议无连接的传输层协议,提供面向事务的简单不可靠信息传送服务,IETFRFC76 ... [详细]
author-avatar
小甜蜜陈诗蓉_614
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有