当前位置: 首页 > news >正文

《USB技术应用与开发》第七讲:CDC串口设备案例

学习目标:如何通过 USB 接口模拟出一个外设,让计算机可以识别为一个串口设备。

一、基本概念

CDC 全称 Communication Device Class,译为通讯设备类,是 USB 协议中定义的一个子类,是USB 通讯设备类。

CDC 类定义了与通信相关设备的一个抽象集合,今天讲解的是:传统纯电话业务模型下的抽象控制模型。

插入:平时使用的 USB 转串的小模块,比如 CH340 ,在使用时都需要安装厂家提供的驱动,所以这种 USB 小模块并不属于 CDC 虚拟串口,真正的 CDC 虚拟串口一般的操作系统都会集成了驱动,所以可以有以下的简单判断:

厂家定义驱动一般都属于厂家自定义设备,这样的设备是由厂家提供的驱动程序生成串口,并由电脑显示出来,这样的方式比较灵活,但是驱动程序的开发比较复杂,兼容性困难。

二、描述符

2.1设备描述符

共 18 个字节,下面是与 CDC  相关需要改变的几个字段。

在之前的 HID 与大容量类设备的时候,以上三个字段都是 00h(接口,下图中的红色字段)。
以上的 02h 表示的就是:通讯设备类,依据来自于下图。

CDC 有 CDC 控制类(第一行黄色的)并在描述那一列写的是 Both ,表明在 设备(Device)和 接口(Interface)都要描述该 CDC 控制类。

CDC 还有 CDC 数据类(第二行黄色的)并在描述那一列定义为接口。

所以接下来的讲解的 CDC 中除了有一个控制接口还有一个数据接口,它们在 接口描述符 的 02,0A 都需要写,在 设备描述符 层面要表明隶属 02h DeviceClass,子类和协议写 00 就可以(如上图)。

2.2配置描述符

无特别说明。

2.3接口描述符

2.3.1控制类接口描述符

CDC 必须有一个控制类接口作为数据类接口的依附,控制类接口描述符 v5、v6、v7 这三个类别(或者说字段)如下图。

对上图的解释:

字段数值描述
v502h类:控制类接口
v602h子类:抽象控制模型
v701h协议:通用 AT 命令集

以上就可以表示是一个虚拟串口。在接口描述符下面是允许有端点的,一般在 CDC 控制类接口下面会有一个中断端点,用来报告一些状态,但经过抓包测试即使没有中断端点也没有特殊情况,所以这里的中断端点是可选的,并不是必须的。

2.3.2数据类接口描述符

CDC 主要应用为虚拟串口进行串口收发通讯,具体的收发端点就是在这个数据类端点下实现的,具体字段要求如下。

2.4特定类描述符------功能描述符

HID 设备会在接口描述符后面出现 HID 类设备描述,对于 CDC 类设备在接口后面出现的特定描述符称之为功能描述符 。

功能描述符值作用是描述针对接口的功能,接口后面可以有多个功能描述符描述接口的功能。

后续的参数均与第三个“描述符子类型”有关,在具体的代码中讲解。

2.5端点描述符

CDC 数据接口有一组跟 U 盘一样的端点:一个 block in(批量上传端点),一个block out(批量下传端点),采用的是批量传输,使用的是 USB 协议标准的端点描述符,下图为列出的通用端点描述符,没有针对 CDC 来写。

三、类请求

下面是虚拟串口中比较常见的几个类请求,就是主机发送给设备的请求。

3.1获取串口数据格式&设置串口数据格式

格式包括但不限于:波特率、数据位、校验位、停止位等参数。

CDC 串口设备本质上模拟一个“串口”,但是由于串口需要设置以上等格式参数,所以主机也必须获取/设置 CDC 设备这些参数。

3.1.1获取串口数据

字段名值(GetLineCoding)含义说明
bmRequestType1010 0001B (0xA1)类请求 + 接收方向 + 接口为目标
bRequestGET_LINE_CODING (0x21)请求码,表示“获取当前串口配置”
wValue0x0000无含义,固定为 0
wIndexInterface接口号,即 CDC 接口编号
wLength7 字节(结构大小)主机会从设备中读取这 7 字节
DataLine Coding Structure结构体(7字节)用于返回串口参数

 3.1.2设置串口数据

字段名值(SetLineCoding)含义说明
bmRequestType0010 0001B (0x21)类请求 + 发送方向 + 接口为目标
bRequestSET_LINE_CODING (0x20)请求码,表示“设置串口配置”
wValue0x0000无含义,固定为 0
wIndexInterface接口号,即 CDC 接口编号
wLength7 字节(结构大小)主机会向设备发送这 7 字节数据
DataLine Coding Structure结构体(7字节)描述串口新参数

3.1.3获取到/设置为 的7字节结构体

英文原版
中文翻译版

可以是5、6、7、8、16位数据(中文翻译版有误)

3.1.4举例

(1)主机获取串口数据

💻 主机向设备发送请求:

字段名含义
bmRequestType0xA11010 0001 → IN(设备→主机),Class类请求,Interface为目标
bRequest0x21GET_LINE_CODING 请求码
wValue0x0000固定为 0
wIndex0x0000接口编号,一般是 CDC 数据接口号(2.3.2节)
wLength0x0007一共读取 7 字节
Data ——无,主机会接收 7 字节数据

📥 设备响应的数据(LineCoding 结构体):

比如当前串口配置是:波特率 115200、8 数据位、无校验、1停止位(8N1)

偏移字段名含义
0dwDTERate0x00 0xC2 0x01 0x000x0001C200 → 115200(注意小端)
4bCharFormat0x001 个停止位
5bParityType0x00无校验
6bDataBits0x088 位数据

完整返回的 7 字节数据为:00 C2 01 00  00 00 08

(2)主机设置串口参数

现在主机想设置成:波特率 9600、7 数据位、偶校验、1.5 个停止位

💻 主机发送控制请求(含 7 字节数据):

字段名含义
bmRequestType0x210010 0001 → OUT(主机→设备),Class类请求,Interface为目标
bRequest0x20SET_LINE_CODING 请求码
wValue0x0000固定为 0
wIndex0x0000接口编号
wLength0x0007向设备写入 7 字节
Data 80 25 00 00 01 02 077 字节结构体内容(解析如下)

📤 主机发送的数据解析:

偏移字段名含义
0dwDTERate0x80 0x25 0x00 0x000x00002580 → 9600 bps
4bCharFormat0x011.5 个停止位
5bParityType0x02偶校验
6bDataBits0x077 位数据位

3.2设置控制线状态

驱动 RTS 和DTR 这两根线。

上图展示了 USB CDC 类中的类请求:设置(模拟)串口通信中控制信号线,比如RTS(Request to Send) 和 DTR(Data Terminal Ready)。

🧩 这条请求的完整结构解释如下:

字段名含义
bmRequestType00100001B,表示类请求(Class)、主机到设备(Host to Device)、接口(Interface)
bRequest0x22,即 SET_CONTROL_LINE_STATE
wValue控制信号位图(Control Signal Bitmap)(下面会解释)
wIndex接口号(一般为 CDC 接口号)
wLength恒为 0,无数据阶段
Data

🧠 wValue(控制信号位图)详解:wValue 是一个 16 位 数,其中

Bit位含义对应串口信号
D0DTR(Data Terminal Ready)V.24 的信号 108/2
D1RTS(Request To Send)V.24 的信号 105
D2~D15保留,必须设为 0无作用

(1)D0:DTR(Data Terminal Ready)

  • 用来表示主机(DTE)是否已经“准备好”开始通信。

  • 在传统串口中,这个信号用于通知设备(DCE)主机上线了

  • 0 = 未准备好
    1 = 准备好通信(常用于“开机、连上电”的意义)

(2)D1:RTS(Request To Send)

  • 用来请求设备允许发送数据。

  • 半双工模式 下有效,用于协商谁发送谁接收

  • 0 = 停止请求发送(关闭发送权限)
    1 = 请求发送数据(激活 carrier)

  • ⚠️ 设备一般在全双工模式(默认)中 会忽略 RTS

  • 如果主机设置 RTS=1,设备可能会根据这个信号开关接收缓冲区,或发送 ACK/NACK 等。

虽然没有真实的 RS-232 电平线,但USB 协议中会模拟这些控制线的功能,就通过我们之前学的 SetControlLineState (0x22) 请求实现:

  • 设置 DTR = 1:表示主机“打开串口调试助手”

  • 设置 RTS = 1:表示主机“点击发送前的准备动作”

3.3获取串口状态

感兴趣的自行了解。

四、软件实现及效果演示

4.1硬件平台

可以做全速的 CDC ,比特率最快应该就是 1 兆。

4.2软件框架

4.3代码

5.8必须更新完。

希望身边讨厌的人没有关注我的博客。


本专栏说明:本人是USB的初学者,该专栏是我CSDN上第一个学习USB技术的专栏,笔记会比较口语,不是很精炼,后续有点基础后,争取“字字珠玑”

本文参考:

《USB技术应用与开发》第七讲:CDC串口设备案例_哔哩哔哩_bilibili

http://www.xdnf.cn/news/331003.html

相关文章:

  • 【AlphaFold2】深入浅出,讲解Evoformer|学习笔记
  • 【汇正自控阀门集团】签约智橙PLM,智橙助泵阀“以国代进”
  • ntdll!CsrServerApiRoutine函数--csrsrv!CsrCallServerFromServer什么时候被调用?
  • 计算机硬件(南桥):主板芯片组FCH和PCH的区别
  • 苍穹外卖(用户下单、订单支付)
  • 当体育数据API遇上WebSocket:一场技术互补的「攻防战」
  • UGUI如何使用EventTrigger
  • LeetCode105_从先序与中序遍历序列构造二叉树
  • 如何从路由表优化的角度理解[CIDR]无类别域间路由选择技术?
  • 六级阅读---2024.12 卷一 仔细阅读1
  • 【编译原理】第五章 自下而上语法分析
  • 快速上手SpringBoot开发指南
  • 力扣热题100之反转链表
  • Linux系统Shell脚本之shell数组、正则表达式、及AWK
  • Mongo3.4升级到mongo6性能降低9倍
  • HSV颜色空间
  • 51camera将参加第九届沥青路面论坛暨新技术新成果展示会
  • 代码随想录算法训练营第三十三天(补)
  • Unity Gizmos
  • 题解 洛谷 Luogu P1073 [NOIP 2009 提高组] 最优贸易 强连通分量 Tarjan 缩点 拓扑排序 动态规划 C++
  • Vue与Python的深度整合:构建现代Web应用的全栈范式
  • 国标GB28181设备管理软件EasyGBS打造明厨亮灶食品安全监管防线
  • 对称二叉树(简单)
  • sqlite数据库操作
  • Qt开发:枚举的介绍和使用
  • 【Win】插入u盘/固态硬盘Hub不显示在我的电脑
  • ModuleNotFoundError: No module named ‘numpy.typing‘
  • oracle 优化器
  • 【DB2】DB2启动失败报错SQL1042C
  • 深入解析进程间通信与Socket原理:从理论到TypeScript实战