linux驱动 usb转串口ch344 改变读取缓冲区大小

news2024/10/7 14:25:11

开发环境

核心板:IMX6
内核版本:linux4.1.5

问题

通过USB扩展出来的串口接收数据会出现截断现象,而且每次截断的大小都一样。而核心板提供的串口UART就没有这个现象。
核心板自带串口正常的现象:
在这里插入图片描述
扩展串口异常现象:
在这里插入图片描述

问题分析

首先客户提出这个问题,我的第一个想法是这是个正常现象,因为我在做应用APP的时候,其实串口发送数据指令的时候,也会偶尔出现一条指令突然截断,先接收到帧头+命令字+类型,然后再接收到长度+数据内容+帧尾这类的情况,就此我们常常会在接收串口的函数中加以判断是否是一条完整的指令。如果不是就不再往下执行。
然后再回到客户这个问题,如果从应用层解决是非常简单的。只需要在读取数据的时候,加以等待函数就可以读到整条指令了,以QT应用为例:

connect(scmCOM3, SIGNAL(readyRead()), this, SLOT(scmReadyReadData()));
void CSerialThread::scmReadyReadData()
{
    //从接收缓冲区中读取串口数据
   // static QByteArray scmRecviceBuff;//静态变量static
    QByteArray tempBuff;//临时接收储存数据,因为串口收到的数据可能是不完整的
    scmCOM3->waitForReadyRead(50);
    tempBuff = scmCOM3->readAll();
   // scmRecviceBuff.append(tempBuff);

    qDebug()<<__func__<< __LINE__ << "scmRecviceBuff:"<<tempBuff.toHex();
 }

如果不考虑改变应用层的代码的话,那么只能通过尝试修改驱动层代码来兼容了。如果是驱动层的话,我第一个想法是会不会跟读取缓冲区的大小有关呢? 为什么要这样的猜测呢,因为每次截断的大小都是128个字节。如果说是上报数据的速度快慢问题的话,应该会不固定截断位置的。

先在内核源码中找一下驱动ch344的驱动文件,定位到driver/usb/class/cdc_acm.c驱动文件。

static int acm_probe(struct usb_interface *intf,
		     const struct usb_device_id *id)
{
	struct usb_cdc_union_desc *union_header = NULL;
	struct usb_cdc_country_functional_desc *cfd = NULL;
	unsigned char *buffer = intf->altsetting->extra;
	int buflen = intf->altsetting->extralen;
	struct usb_interface *control_interface;
	struct usb_interface *data_interface;
	struct usb_endpoint_descriptor *epctrl = NULL;
	struct usb_endpoint_descriptor *epread = NULL;
	struct usb_endpoint_descriptor *epwrite = NULL;
	struct usb_device *usb_dev = interface_to_usbdev(intf);
	struct acm *acm;
	int minor;
	int ctrlsize, readsize;
	u8 *buf;
	u8 ac_management_function = 0;
	u8 call_management_function = 0;
	int call_interface_num = -1;
	int data_interface_num = -1;
	unsigned long quirks;
	int num_rx_buf;
	//.......省略中间部分
	ctrlsize = usb_endpoint_maxp(epctrl) ;
	readsize = usb_endpoint_maxp(epread) *
				(quirks == SINGLE_RX_URB ? 1 : 2);
	printk("epctrl,epread,usb_endpoint_maxp(epread):%d,%d,%d\n",epctrl,epread,usb_endpoint_maxp(epread));
	acm->combined_interfaces = combined_interfaces;
	acm->writesize = usb_endpoint_maxp(epwrite) * 20;
	acm->control = control_interface;
	acm->data = data_interface;
	acm->minor = minor;
	acm->dev = usb_dev;
	acm->ctrl_caps = ac_management_function;
	if (quirks & NO_CAP_LINE)
		acm->ctrl_caps &= ~USB_CDC_CAP_LINE;
	acm->ctrlsize = ctrlsize;
	acm->readsize = readsize;
	acm->rx_buflimit = num_rx_buf;
	printk("acm->ctrlsize,acm->readsize,acm->rx_buflimit:%d,%d,%d\n",acm->ctrlsize,acm->readsize,acm->rx_buflimit);
	INIT_WORK(&acm->work, acm_softint);
	init_waitqueue_head(&acm->wioctl);
	spin_lock_init(&acm->write_lock);
	//.....省略
}

驱动加载时打印的信息如下:

ctrlsize,readsize,usb_endpoint_maxp(epread):-666437376,-666557136,64
acm->ctrlsize,acm->readsize,acm->rx_buflimit:16,128,16
cdc_acm 1-1.4:1.0: ttyACM0: USB ACM device
ctrlsize,readsize,usb_endpoint_maxp(epread):-666437312,-666557008,64
acm->ctrlsize,acm->readsize,acm->rx_buflimit:16,128,16
cdc_acm 1-1.4:1.2: ttyACM1: USB ACM device
ctrlsize,readsize,usb_endpoint_maxp(epread):-666437248,-666556880,64
acm->ctrlsize,acm->readsize,acm->rx_buflimit:16,128,16
cdc_acm 1-1.4:1.4: ttyACM2: USB ACM device
ctrlsize,readsize,usb_endpoint_maxp(epread):-666437184,-666556752,64
acm->ctrlsize,acm->readsize,acm->rx_buflimit:16,128,16
cdc_acm 1-1.4:1.6: ttyACM3: USB ACM device

果不其然,看到acm->readsize=128,跟现象截断的字节数刚好一样,然后我尝试单单修改acm->readsize=256,串口无法正常使用,证明readsize肯定跟其他值相关联的,仔细看了下代码,我认为跟这个有关系。然后将ctrlsize的值也成倍增加,如下:

//原来的代码:
ctrlsize = usb_endpoint_maxp(epctrl) ;
	readsize = usb_endpoint_maxp(epread) *
				(quirks == SINGLE_RX_URB ? 1 : 2);
//修改后的代码:	
	ctrlsize = usb_endpoint_maxp(epctrl)*2 ;
	readsize = usb_endpoint_maxp(epread) *
				(quirks == SINGLE_RX_URB ? 1 : 4);		

成功后的打印信息:

usb 1-1.4: new full-speed USB device number 3 using ci_hdrc
ctrlsize,readsize:-666437376,-666557136,64
acm->ctrlsize,acm->readsize,acm->rx_buflimit:32,256,16
cdc_acm 1-1.4:1.0: ttyACM0: USB ACM device
ctrlsize,readsize:-666437312,-666557008,64
acm->ctrlsize,acm->readsize,acm->rx_buflimit:32,256,16
cdc_acm 1-1.4:1.2: ttyACM1: USB ACM device
ctrlsize,readsize:-666437248,-666556880,64
acm->ctrlsize,acm->readsize,acm->rx_buflimit:32,256,16
cdc_acm 1-1.4:1.4: ttyACM2: USB ACM device
ctrlsize,readsize:-666437184,-666556752,64
acm->ctrlsize,acm->readsize,acm->rx_buflimit:32,256,16
cdc_acm 1-1.4:1.6: ttyACM3: USB ACM device
X_MAX: 4096, Y_MAX: 4096, TRIGGER: 0x01

通过以上的方式,最终也解决了客户的问题。不管是应用层还是驱动层,只要分析到问题出现的点在哪,都能解决。

一贯以来的解题思路:大胆猜测,小心求证。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/45616.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【软件测试】8年资深测试说出来我们的心声......

目录&#xff1a;导读前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09;前言 执着于手动的功能测…

VLAN划分-----计算机网络

拓扑图 LSW1与LSW2都是三层交换机&#xff0c;现在两台交换机分别连着两台pc。 其中&#xff1a; LSW1的0/0/1端口连着pc1&#xff0c;0/0/2连着pc2&#xff0c;0/0/3端口连着lsw2。 LSW2的0/0/1端口连着pc3&#xff0c;0/0/2连着pc4&#xff0c;0/0/3端口连着lsw1。 不同vlan…

pycharm opencv无法自动补全

我的环境 python 3.6.9opencv-python 4.4.0.42opencv-contrib-python 4.6.66ubuntu 18.04 LTSpycharm 2020.3.2 解决方案 首先找到cv2的site-packagespip3 show opencv-python进入到该目录, 复制so结尾文件至上级目录: cp cv2.cpython-36m-x86_64-linux-gnu.so ../等待pych…

基于粒子群算法和遗传算法优化的高速列车横向悬挂

目录 前言 1.高速列车模型 2.优化算法优化模糊PID流程 3.普通PID、优化算法模糊PID仿真对比 3.1 模糊控制器设计 3.2 仿真结果 3.2.1粒子群优化PID 3.2.2粒子群优化模糊PID 3.2.3遗传算法优化模糊PID 4.总结 前言 高速列车&#xff0c;是指最高行驶速度在200km/h 及以…

二、【React-Router5】路由的基本使用

文章目录1、写在前面的总结2、效果图3、项目结构4、CODE4.1、index.js4.2、App.js4.3、About.jsx4.4、Home.jsx5、Result6、路由组件与一般组件7、Link 升级 NavLink8、封装NavLink8.1、MyNavLink.jsx8.2、修改上面4.2部分代码1、写在前面的总结 明确好界面中的导航区、展示区…

火山引擎数智平台:CDP产品要能与多方联动

更多技术交流、求职机会&#xff0c;欢迎关注字节跳动数据平台微信公众号&#xff0c;回复【1】进入官方交流群 CDP&#xff08;Customer Data Platform&#xff0c;客户数据平台&#xff09;市场将迎来新一轮的高速增长。 国际数据公司&#xff08;以下简称“IDC”&#xff0…

[附源码]Python计算机毕业设计SSM流浪猫狗救助站(程序+LW)

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

ofxTimeMeasurements——OpenFrameworks插件,可以轻松测量C++代码任何部分的执行时间

一、简介 ofxTimeMeasurements是一款用于OpenFrameworks 开源C框架的插件&#xff0c;可以让使用者轻松测量C代码任何部分的执行时间。其优势在于以图形化的方式显示代码执行时间。效果如下&#xff1a; 只是它必须依赖OpenFrameworks&#xff0c;所以如果你不用这个框架&…

《Head First HTML5 javascript》第10章 自定义对象

2022.11.23 第10章 自定义对象 面向对象OOP(Object Oriented Programming) 对象是一个包含相关数据和方法的集合&#xff08;通常由一些变量和函数组成&#xff0c;我们称之为对象里面的属性和方法&#xff09;对象是存储在单个分组中的相关功能的集合。在 JavaScript 中&…

第二证券|多只公募基金损失惨重;储能板块低开高走

今天早盘&#xff0c;A股大幅低开&#xff0c;上证50指数直接跳空跌破2500点&#xff0c;最多跌逾3%&#xff0c;创业板指亦跌破2300点整数关口。 盘面上&#xff0c;酒店餐饮、旅游、储能、ST等板块逆势活跃&#xff0c;酿酒、工程机械、互联网、证券等板块跌幅居前。北上资金…

【LeetCode每日一题:1758. 生成交替二进制字符串的最少操作数~~~模拟+遍历+计数】

题目描述 给你一个仅由字符 ‘0’ 和 ‘1’ 组成的字符串 s 。一步操作中&#xff0c;你可以将任一 ‘0’ 变成 ‘1’ &#xff0c;或者将 ‘1’ 变成 ‘0’ 。 交替字符串 定义为&#xff1a;如果字符串中不存在相邻两个字符相等的情况&#xff0c;那么该字符串就是交替字符…

KVM虚拟机热扩容

创建一个虚拟机用于练习在线扩容 virt-install --name centos8-3 --memory 4096,currentMemory1024 --vcpus 2,maxvcpus8 --disk /var/lib/libvirt/images/centos8-3.qcow2,busvirtio,formatqcow2 --import --os-variant rhel8.0 --graphics vnc --network networkdefault…

Docker-JenKins安装及配置!

Jenkins官网&#xff1a;Jenkins 安装主机配置&#xff08;官方&#xff09;&#xff1a; 最低&#xff1a; 256 MB 内存 1 GB 的驱动器空间&#xff08;尽管如果将 Jenkins 作为 Docker 容器运行&#xff0c;则建议至少 10 GB&#xff09; 小团队推荐&#xff1a; 4 GB …

针对支付宝-当面付实现的个人支付

测试地址 项目背景 为什么想做这个 一是工作中也接触到了支付宝&#xff0c;微信支付方面&#xff0c;二是自己也想弄个收费服务&#xff0c;比如之后做的程序想收费可以直接让用户扫码支付&#xff0c;而不用微信交流了。 了解什么支付适合个人支付 微信支付&#xff1a;需要…

基于SpringBoot的实习管理系统

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SpringBoot 前端&#xff1a;Vue、HTML 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#…

Unity与IOS⭐Xcode打包,上架TestFlight的完整教程

文章目录 🟥 本章注意事项1️⃣ 证书及Archive2️⃣ 更新版本及加密规则🟧 Xcode打包出ipa文件🟨 将ipa上传到App Store Connect🟥 本章注意事项 1️⃣ 证书及Archive 上架TestFlight需要苹果企业版证书,而不是个人版证书。Archive时必须插上手机,否则会失败。2️⃣…

Prometheus 采集rabbitmq监控数据

Prometheus采集主机监控参考部署下载&#xff0c;图形生成 系统安装Grafana downloadWindows参考图形生成参考win_exporterLinux参考node_exporterMysql参考Mysql_exporterSQL Server参考SQL exporterRedis 参考Redis_exportercadvisor参考cadvisorrabbitmq参考参考rabbitmq s…

众多互联网公司都在用的Elasticsearch还不会?熬夜整理基于 Elasticsearch 7.x 版本的核心知识学习手册,值得拥有!

简介 简单来说 ElasticSearch 就是一个搜索框架。对于搜索这个词我们并不陌生&#xff0c;当我们输入关键词后&#xff0c;返回含有该关键词的所有信息结果。 在我们平时用到最多的便是数据库搜索&#xff1a; SELECT * FROM USE WHERE NAME LIKE %小菜%但是用数据库做搜索存…

Scala函数至简原则

一、Scala中的函数基础知识 1、基本语法 【函数和方法的区别】 【核心概念】 &#xff08;1&#xff09;为完成某一功能的程序语句的集合&#xff0c;称为函数。 &#xff08;2&#xff09;类中的函数称之方法。 【案例实操】 &#xff08;1&#xff09;Scala 语言可以在任何…

THP Maleimide,1314929-99-1,THP-Mal凯新生物双功能螯合剂

一、产品描述&#xff1a; THP-Mal 双功能螯合剂。肽和抗体标记。对SH基团的特异性反应&#xff0c;如半胱氨酸。炔烃马来酰亚胺是一种双功能接头试剂&#xff0c;可将末端炔烃连接到各种含硫醇分子&#xff0c;例如含有半胱氨酸残基的蛋白质&#xff0c;然后可以通过铜催化的…