Linux 485驱动通信异常
背景
前段时间接到一个项目,要求用主控用485和MCU通信。将代码调试好之后,验证没问题就发给测试了。测试测的也没问题。
但是,到设备量产时,发现有几台设备功能异常。将设备拿回来排查,发现是485通信有问题,偶现通信失败。
排查思路
复现问题
发给测试之前,功能都验证了很多次,但是并没有发现通信失败的问题。设备拿到手,第一时间就尝试复现通信失败的问题,也没有成功。
于是,写了一个脚本,不断的和MCU通信,看什么情况下会失败。
果然,在通信若干次后,发现日志异常,主控接收数据出现了错乱。
接着,继续跑脚本,想看下什么情况下会失败。但是,每次通信异常的时机都是随机的,没有规律。
观察了下错乱的数据,和正确的数据做了对比,也没有什么发现。
清空buf
接收的数据出现了异常,第一个想到的是,是不是接收buffer不干净,有其他数据干扰呢?
尝试在接收buffer和发送buffer之前,手动清空下buf。确保不会有其它数据干扰。
重新跑脚本和MCU 通信,但是仍会失败。
收发时序
光看是什么办法了。上示波器看下主控和MCU的时序的。
正常来讲,主控和MCU的485控制管脚应该是正好反向的电平。即主控485控制管脚高电平发送的时候,MCU的485控制管脚应该是低电平。
问题复现时,对比了管脚的电平,确实是反向的,没有问题。这也排除了收发时序对不上的问题。
(绿色的是MCU的485控制管脚,黄色的是主控的485控制管脚)

收发数据正确
小示波器没有解码的功能,只能找硬件来量下主控的RX和MCU的TX。确认下,到底是主控接收的不对,还是MCU发的不对。

显然,是主控接收的数据有问题了。
仔细观察会发现,绿色波形这里有个半高电平,覆盖了黄色的低电平。导致第一帧出错了,后面的数据也都错乱了。

又重新复现了几次,发现每次失败时都是这种现象。那为什么这里会有个半高电平呢?
确认问题
和硬件对着原理图经过一番讨论,硬件给到的结论是,485芯片的RX管脚接了3.3V的上拉,只有当485芯片的使能管脚拉高时,RX才会有3.3V的半高电平出现。硬件怀疑是485控制管脚和MCU的时序没对上。
不过,我之前也量了主控和MCU的485控制管脚的电平,看了是对的?难道是我看错了?
接着又重新量了主控和MCU的485控制管脚,发现确实有问题,具体如下图。两者有1.5ms的高电平是重合的,这或许就是问题所在!


又重新复现了几次问题,发现每次通信失败时,都会有一段高电平是重合的。
到这里,基本也就明确了问题原因:主控和MCU的485控制管脚时序没对上!
寻找问题根因
从波形找出了问题所在,回归串口编程,继续看下代码吧。把重点放在了时序切换的代码上。
代码里面,在切换485管脚时有这样两段代码。
以下只是伪代码
代码一:
setdir(SEND) //切换为发送状态
write() //发送数据
tcdrain(fd) //判断是否写完
setdir(READ) //切换为读状态
代码二:
do
{ioctl(fd,TIOCSERGETLSR,&lsr) //判断发送buffer是否写完
}while(!(lsr&TIOCSER_TEMT)) //如果TX为空,返回TIOCSER_TEMT
这两段代码,都是和485管脚切换相关的,根据不同情况走不同逻辑,出问题的代码走的是代码一片段。
tcdrain 和 TIOCSERGETLSR
那这两段代码有什么区别呢?
tcdrain是应用层控制tty的一个函数,调用 tcdrain()函数后会使得应用程序阻塞, 直到串口输出缓冲区中的数据全部发送完毕为止。
ioctl(fd,TIOCSERGETLSR,&lsr)是获取tty 设备的线路状态寄存器( LSR )的值。
这两段代码最大区别就是延时不同!
tcdrain()是等待fd所引用的串口设备数据传输完毕。虽然在物理上数据已传输完毕时,但Linux对硬件实时性高,对于用户请求的实时性较低。所以操作系统会有延时,导致tcdrain()多停留几ms,从而导致数据发送完后,485管脚的控制方向不能及时切换。
如果对接的485设备,接收和应答的延迟小于tcdrain()的延时,那方向切换不及时将导致数据接收丢失。这就是问题根因所在。
那为什么操作系统会有延时呢?
这个得说说Linux工作队列相关机制,对于硬件操作Linux处理的很及时,但是对于数据Linux可能将其交给系统的下半部的内核线程去处理,这就可能导致用户的系统调用存在一定的延时,而485通信对时间要求又很严格,1ms的延时就会导致数据错乱。
总结
- 严谨细致。在问题发生时,我也去量过主控和和MCU 485控制管脚的电平,只看到了两者是反向的,但是并没有放大去看最后一段电平的细节。导致遗漏了解决问题的线索。
- 一切问题发生都是有原因的。偶现问题并不好排查,但是我们可以尝试制作偶现问题发生的条件,看有没有可能成为必现问题。如果不能必现,可尝试通过脚本去不断运行在问题发生的场景,使其出现的概率提升。
相关文章:
Linux 485驱动通信异常
背景 前段时间接到一个项目,要求用主控用485和MCU通信。将代码调试好之后,验证没问题就发给测试了。测试测的也没问题。 但是,到设备量产时,发现有几台设备功能异常。将设备拿回来排查,发现是485通信有问题ÿ…...
mybatis配置与标签大全
文章目录 mybatis配置与标签大全mybatis的配置属性(properties)设置(settings)类型别名(typeAliases)类型处理器(typeHandlers)对象工厂(objectFactory)插件&…...
Mysql的基本用法(上)非常详细、快速上手
上篇结束了java基础,本篇主要对Mysql中的一些常用的方法进行了总结,主要对查询方法进行了讲解,包括重要的多表查询用到的内连接和外连接等,以下代码可以直接复制到可视化软件中,方便阅读以及练习; SELECT *…...
使用Vite创建React + TypeScript(node版本为16.17.0,含资源下载)
PC端 安装指令: npm create vitelatest react-ts-pro -- --template react-tsVite是一个框架无关的前端工具链,可以快速的生成一个React TS的开发环境,并且可以提供快速的开发体验说明: 1. npm create vitelatest固定写法&#…...
Springboot集成RabbitMq二
接上一篇:Springboot集成RabbitMq一-CSDN博客 1、搭建项目-消费者 与之前一样 2、创建配置类 package com.wym.rabbitmqconsumer.utils;import org.springframework.amqp.core.Binding; import org.springframework.amqp.core.BindingBuilder; import org.spring…...
机器学习笔记 - 基于Python的不平衡数据的欠采样技术
一、简述 随着从不同的来源生成和捕获大量数据。尽管信息量巨大,但它往往反映了现实世界现象的不平衡分布。数据不平衡的问题不仅仅是统计上的挑战,它对数据驱动模型的准确性和可靠性具有深远的影响。 以金融行业欺诈检测为例。尽管我们希望避免欺诈,因为其具有高度破坏性,…...
facebook广告的基础知识
Facebook广告是在Facebook、Instagram、Audience Network等与Facebook相关的SNS和服务上投放的广告。以下是关于Facebook广告的基础知识: 广告类型: 静态图片广告:主要通过Facebook的新闻提要投放的图片广告,可以张贴产品和服务…...
java常见面试题:什么是异常?Java中的异常有哪些分类?
异常是一个汉语词语,读音为y chng,指非正常的;不同于平常的;非常。在Java中,异常(Exception)是程序在运行过程中出现的不正常情况,例如除以零、数组越界等。异常分为两大类ÿ…...
类的加载顺序问题-demo展示
面试的的时候经常会被问到包含静态代码块、实例代码块和构造器等代码结构的加载顺序问题,下面借用一个面试题,回顾一下类的代码加载顺序。 public class AooTest {public static void main(String[] args) {AooTest.f1();}static AooTest test1 new Ao…...
[蓝桥杯2020国赛]答疑
答疑 题目描述 有 n 位同学同时找老师答疑。每位同学都预先估计了自己答疑的时间。 老师可以安排答疑的顺序,同学们要依次进入老师办公室答疑。 一位同学答疑的过程如下: 首先进入办公室,编号为 i 的同学需要 si 毫秒的时间。然后同学问…...
【AIGC表情prompt】提示词练习技巧
表情类提示词练习技巧 医疗机器人,男人笑脸景深,数据,座标,12k,c4d渲染,高分辨率,,暖色调,高清对比 医疗机器人,男人微笑,景深,数据,座标…...
SpringBoot项目的三种创建方式
手动创建方式: ①:新建maven项目 ②:引入依赖 <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.10.RELEASE</version>&l…...
【docker实战】01 Linux上docker的安装
Docker CE是免费的Docker产品的新名称,Docker CE包含了完整的Docker平台,非常适合开发人员和运维团队构建容器APP。 Ubuntu 14.04/16.04(使用 apt-get 进行安装) # step 1: 安装必要的一些系统工具 sudo apt-get update sudo ap…...
Baumer工业相机堡盟工业相机如何通过NEOAPI SDK设置相机的图像剪切(ROI)功能(C#)
Baumer工业相机堡盟工业相机如何通过NEOAPI SDK设置相机的图像剪切(ROI)功能(C#) Baumer工业相机Baumer工业相机的图像剪切(ROI)功能的技术背景CameraExplorer如何使用图像剪切(ROI)…...
软件测试之安全测试
一、测试范围 管理系统:url、登录框、搜索框、输入框、文件上传、文件下载 客户端:搜索框、输入框、文件上传、系统功能 二、测试点 密码安全 XSS注入 SQL注入 操作越权 上传安全 下载安全 三、工具 fiddler sqlmap 同时,在这我为…...
【华为OD机试真题2023CD卷 JAVAJS】会议室占用时间
华为OD2023(C&D卷)机试题库全覆盖,刷题指南点这里 会议室占用时间 时间限制:1s 空间限制:256MB 限定语言:不限 题目描述: 现有若干个会议,所有会议共享一个会议室,用数组表示每个会议的开始时间和结束时间,格式:[[会议1开始时间,会议1结束时间], [会议2开始时间…...
UR5机器人的旋转向量转换到四元数,再从四元数转换到旋转向量python代码
能够通过接口获得UR5机器人末端在基坐标系下的位姿,姿态表示方法是用旋转向量表示的,一般会涉及到四元数和旋转向量之间的转换。 1、方法一 import numpy as np from pytransform3d import rotations as pr import copy # 输入旋转向量 quaternion2 n…...
MD5--加密原理及代码示例(C#)
1.MD5详述 MD5(Message-Digest Algorithm 5)是一种哈希算法,用于将任意长度的信息映射为固定长度的哈希值(128位)。MD5算法具有以下特点: 哈希值长度固定:MD5算法将任意长度的输入数据计算为128…...
理解 RPC 与 Protobuf:完整指南
一、Protobuf 数据格式简析 Protobuf 是什么? 在数据密集型应用领域,Google 开发的 Protobuf 作为一种高效数据编码方式而广受欢迎。它胜任于 JSON 及 XML 对比,不仅在体积和速度上表现出色,而且其结构化方式优化了网络传输中的…...
成为一名合格的前端架构师,前端知识技能与项目实战教学
一、教程描述 本套前端架构师教程,大小35.94G,共有672个文件。 二、教程目录 01.node介绍和环境配置(共6课时) 02.ES6语法(共5课时) 03.node基础(共29课时) 04.Express框架&am…...
XML Group端口详解
在XML数据映射过程中,经常需要对数据进行分组聚合操作。例如,当处理包含多个物料明细的XML文件时,可能需要将相同物料号的明细归为一组,或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码,增加了开…...
Python爬虫实战:研究MechanicalSoup库相关技术
一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...
Python|GIF 解析与构建(5):手搓截屏和帧率控制
目录 Python|GIF 解析与构建(5):手搓截屏和帧率控制 一、引言 二、技术实现:手搓截屏模块 2.1 核心原理 2.2 代码解析:ScreenshotData类 2.2.1 截图函数:capture_screen 三、技术实现&…...
【Python】 -- 趣味代码 - 小恐龙游戏
文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...
css实现圆环展示百分比,根据值动态展示所占比例
代码如下 <view class""><view class"circle-chart"><view v-if"!!num" class"pie-item" :style"{background: conic-gradient(var(--one-color) 0%,#E9E6F1 ${num}%),}"></view><view v-else …...
云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地
借阿里云中企出海大会的东风,以**「云启出海,智联未来|打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办,现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...
前端倒计时误差!
提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...
使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装
以下是基于 vant-ui(适配 Vue2 版本 )实现截图中照片上传预览、删除功能,并封装成可复用组件的完整代码,包含样式和逻辑实现,可直接在 Vue2 项目中使用: 1. 封装的图片上传组件 ImageUploader.vue <te…...
音视频——I2S 协议详解
I2S 协议详解 I2S (Inter-IC Sound) 协议是一种串行总线协议,专门用于在数字音频设备之间传输数字音频数据。它由飞利浦(Philips)公司开发,以其简单、高效和广泛的兼容性而闻名。 1. 信号线 I2S 协议通常使用三根或四根信号线&a…...
C#中的CLR属性、依赖属性与附加属性
CLR属性的主要特征 封装性: 隐藏字段的实现细节 提供对字段的受控访问 访问控制: 可单独设置get/set访问器的可见性 可创建只读或只写属性 计算属性: 可以在getter中执行计算逻辑 不需要直接对应一个字段 验证逻辑: 可以…...
