好,进入第 2 讲。
第2讲:USB CDC 从"插上电脑"到"出现 COM 口",枚举过程到底发生了什么
后面调试时,最常见的问题不是"代码编译不过",而是:
- 插上电脑没反应
- 设备管理器里看不到东西
- 有未知设备,但没 COM 口
- 有设备名,但打不开
- 有 COM 口,但发不回去
这些问题,本质上都和枚举过程有关。
所以这一讲要学会两件事:
- 电脑插上板子后,双方在干什么
- 调试时怎么根据现象判断卡在哪一步
一、先讲一句最核心的话
"出现 COM 口"不是 USB 一插上就天然有的,而是电脑先成功识别了你的设备是 CDC,然后操作系统才把它呈现成 COM 口。
也就是说:
text
插上USB
-> 电脑检测到设备接入
-> 电脑开始枚举
-> 设备返回描述符
-> 电脑确认这是 CDC 设备
-> 系统加载对应驱动
-> 设备管理器里出现 COM 口
如果这条链中间任何一步出问题,COM 口都可能不会出现。
二、什么叫"枚举"
可以先把"枚举"理解成:
电脑在给新插入的 USB 设备做身份核验和能力确认。
电脑要确认这些问题:
- 你是不是一个合法 USB 设备?
- 你是什么设备?
- 你支持什么功能?
- 你有几个接口?
- 你有哪些端点?
- 该给你配什么驱动?
设备必须按 USB 规范回答。
如果回答对了,电脑就继续。
如果回答错了,电脑就会:
- 识别失败
- 变成 Unknown Device
- 或者根本不出 COM 口
三、从物理插入开始,到 COM 口出现,大概经历哪些步骤
下面按顺序讲。
第 1 步:物理接入,主机检测到设备存在
把 USB 线插上后,主机侧首先会感知:
"有一个 USB 设备接进来了。"
为什么能感知?
因为 USB 设备端会在数据线上表现出"我在这"的电气特征。
在板子上,这和:
DPDMUSB_SLAVE- 板上的相关上拉控制电路
有关。原理图能看到 USB_SLAVE 和 DP 存在关联链路,这就是设备接入识别相关电路的一部分。
这一阶段如果有问题,常见现象是:
- 插上电脑完全没反应
- 设备管理器没有任何刷新
- 甚至供电灯都不对
这通常先查:
- USB 线
- 供电
- D+ / D- 硬件
- 设备是否真的在跑程序
第 2 步:主机复位设备,准备开始问话
电脑发现设备后,不会立刻给你 COM 口。
它会先做一个"初始化动作",把设备拉到统一起点,然后开始问问题。
你可以把它想成:
"先让你站好,再开始查身份证。"
设备此时必须正确响应 USB 基本协议。
如果这一步都没过,后面描述符都轮不到。
第 3 步:主机读取 Device Descriptor(设备描述符)
这是第一份关键身份证。
它会告诉主机一些非常基础的信息,比如:
- USB 版本
- 厂商 ID(VID)
- 产品 ID(PID)
- 设备类别
- 设备版本
- 字符串索引等
现阶段不用背字段值,但要知道:
Device Descriptor 是主机认识你的第一步。
如果这一步有问题,常见现象:
- 设备显示为 Unknown USB Device
- 设备描述符请求失败
- 根本继续不下去
第 4 步:主机给设备分配地址
刚插上时,USB 设备并不是正式"有身份"的。
主机读完第一轮基础信息后,会给它分一个 USB 地址。
这个地址就像"点名时给你编号"。
后面主机再和你通信,就按这个地址找你。
如果这一步出问题,也会导致枚举中断。
第 5 步:主机继续读取更完整的描述符
这里就进入关键阶段了。
主机会继续读:
- Configuration Descriptor
- Interface Descriptor
- Endpoint Descriptor
- String Descriptor
可以先这样理解它们:
1. Configuration Descriptor
告诉主机:
- 我有一种怎样的工作配置
- 里面总共有多少接口
- 总长度是多少
2. Interface Descriptor
告诉主机:
- 我有哪些功能接口
- 每个接口属于什么类别
对于 CDC 来说,通常会涉及:
- 通信控制接口
- 数据接口
3. Endpoint Descriptor
告诉主机:
- 我的数据通道怎么分配
- 哪些端点用来收
- 哪些端点用来发
- 哪些端点是中断/批量等类型
4. String Descriptor
告诉主机:
- 厂商名
- 产品名
- 序列号等字符串信息
四、为什么读完这些描述符后,电脑才可能出 COM 口
因为主机必须先搞清楚:
"是不是 CDC 设备?"
只有当主机从描述符中确认:
- 这个设备的接口组织方式符合 CDC
- 类别信息正确
- 端点安排合理
操作系统才会说:
"哦,这是个虚拟串口设备,我给它挂成 COM 口。"
所以必须记住:
COM 口不是某个 GPIO 决定的,而是"USB 枚举 + CDC 描述符 + 驱动匹配"的结果。
五、为什么有的设备被识别了,但就是不出 COM 口
这是新手非常容易混淆的点。
"被电脑识别"不等于"一定有 COM 口"。
可能出现几种情况:
情况 1:设备被识别成别的 USB 类
例如:
- HID
- MSC
- 自定义类
这种情况下,设备可能完全正常,但就是不会出 COM 口。
因为它不是 CDC。
情况 2:描述符不完整或不符合 CDC 规范
这时可能出现:
- 设备能被看见
- 但驱动不匹配
- 或者只显示异常设备
- 没有虚拟串口
情况 3:驱动问题
有些系统环境下,即便设备本身枚举得差不多,如果驱动没匹配好,也可能:
- 没有 COM 口
- 有感叹号
- 无法打开
情况 4:枚举中途失败
前面几步走了一半,但后面某一步失败,也可能表现成:
- 设备一闪而过
- 反复重连
- 设备管理器刷新但不稳定
- 最终没有 COM 口
六、把整个枚举过程类比成"入职登记"
把 USB 设备想成"新员工",电脑想成"公司前台"。
第一步:你进门
前台看到"有人来了"。
第二步:让你站好
确认你是一个正常来访者。
第三步:看身份证
读取 Device Descriptor。
第四步:给你工号
给设备分配地址。
第五步:看你的岗位说明
读取 Configuration / Interface / Endpoint Descriptor。
第六步:安排你进哪个部门
如果看出来你是 CDC,就把你安排成"串口设备"这个角色。
第七步:系统里给你开账号
最终在 Windows 里变成一个 COMx。
所以:
COM 口 = 电脑完成一整套识别流程后的"岗位分配结果"
不是一插上就天然存在。
七、结合目标,最应该关注哪几个"观察点"
后面调试时,不要一上来就盯代码。
先盯现象。
观察点 1:插上后,设备管理器有没有刷新
如果完全没刷新,先怀疑:
- USB 线坏
- 板子没供电
- 板子程序没跑
- USB 硬件链路问题
- D+ / D- 没建立有效接入状态
观察点 2:有没有出现"未知设备"
如果出现 Unknown Device,说明:
- 主机感知到了设备接入
- 但枚举没成功
这时候重点查:
- 描述符
- 时钟
- USB 初始化
- 底层驱动
观察点 3:有没有出现某个 USB 设备,但不是 COM 口
这说明:
- 设备可能部分枚举成功了
- 但没被识别为 CDC
重点查:
- CDC 类注册
- CDC 描述符
- 类/接口/端点配置
- 驱动匹配
观察点 4:有没有出现 COM 口
如果已经出现 COM 口,说明前面最困难的那部分其实已经过了:
- USB 设备存在
- 枚举基本成功
- CDC 类基本成立
- 驱动基本匹配
八、为什么 USB 时钟错误会严重影响枚举
要提前建立意识。
USB 比 UART 更挑时钟。
因为 USB 设备和主机之间的数据时序要求更严格。
如果 USB 时钟不稳定或不正确,常见现象是:
- 枚举失败
- 描述符读不完整
- 设备反复断开重连
- 有时认得出,有时认不出
- COM 口时有时无
所以以后遇到"奇怪的 USB 问题",时钟一定是重点怀疑对象之一。
九、要知道"端点"是什么
端点不是物理引脚。
可以先把它理解成:
USB 设备内部的数据通道编号。
对于 CDC 设备,通常会有:
- 控制相关端点
- 数据接收端点
- 数据发送端点
主机之所以能和你的"虚拟串口"通信,不是靠 原理图上引脚,而是靠这些 USB 端点在工作。
你现在只要先知道"端点存在且很重要"即可。
十、未来会遇到的故障,按枚举阶段分类
阶段 A:物理接入失败
现象:
- 插上没任何反应
查:
- USB 线
- 电源
- 板子程序是否运行
- D+/D- 硬件链路
阶段 B:早期枚举失败
现象:
- 设备管理器有反应
- 但显示未知设备或报错
查:
- Device Descriptor
- USB Core 初始化
- 时钟
- 中断
阶段 C:类识别失败
现象:
- 设备被识别了
- 但没有 COM 口
查:
- CDC 类注册
- Interface / Endpoint Descriptor
- 驱动匹配
阶段 D:应用层失败
现象:
- 有 COM 口
- 串口助手能打开
- 但发什么都没回
查:
- CDC 接收回调
- 缓冲区
- 发送接口
- 忙状态处理
十一、这一讲该记住的结论
是:
- COM 口不是插上就有,是枚举成功后的结果。
- 电脑先读描述符,再判断你是不是 CDC。
- 只有被识别成 CDC,Windows 才会给你 COM 口。
- "设备被识别"不等于"一定有 COM 口"。
- 调 USB 问题时,要先判断卡在枚举哪一层。
十二、当前阶段的理解题
自己在脑子里答一遍:
1. 为什么 USB 设备插上后不一定有 COM 口?
因为主机要先完成枚举,并确认它是 CDC 设备,才会表现成 COM 口。
2. 为什么描述符很关键?
因为主机靠它判断设备身份、功能接口和端点组织。
3. 如果设备管理器出现 Unknown Device,说明什么?
说明主机已经感知到设备,但枚举过程中某一步失败了。
4. 如果设备被识别了但没有 COM 口,优先怀疑什么?
优先怀疑 CDC 类配置、描述符、接口和端点组织、驱动匹配。
十三、下一讲该讲什么
第3讲:做 USB CDC 虚拟串口,最小工程到底要具备哪些条件
这一讲会讲:
- 工程必须有哪些基础文件
- 时钟要满足什么
- 中断要满足什么
- USB 初始化链最小应该有哪些步骤
- 如何判断"现在这个工程具不具备出 COM 口的资格"