0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

CDC设备枚举过程解析

GReq_mcu168 来源:面包板社区 作者:面包板社区 2020-10-09 11:43 次阅读

本篇笔记将详述 CDC设备枚举过程,让大家对整体的枚举过程有个概念。

为了更好到理解并分析接下来的通信流程,鱼鹰首先介绍标准请求和描述符。

上篇笔记了解了标准请求和描述符是怎么回事,但还不够,还需要更细节的东西。

首先从标准请求的8字说起:

第一字节:位图请求信息。 D7 代表了接下来传输的数据是从主机到从机,还是从机到主机的。我们知道枚举过程使用控制传输,有三个阶段,如果有数据阶段,那么这个阶段的DATA数据是由主机发出还是由从机发出,就看这个位的值了。 当然了,因为每一次事务都有令牌包存在,所以IN令牌后的数据一定是由从机发出的,但是标准请求的这个位可以让从机做好发送数据或者接收数据的准备。

D6~D5:代表了请求类型。 请求类型代表本次请求属于什么类型的请求。目前有三类,标准、类、厂商。标准请求主要有:

除了标准请求,还有类请求,比如 CDC 类,用到了三种类请求: SET_LINE_CODING(0x20) 设置串口波特率、起始位、停止位、流控等信息 GET_LINE_CODING(0x21) 获取串口波特率、起始位、停止位、流控等信息 SET_CONTROL_LINE_STATE(0x22)用于设置串口的状态 厂商请求一般不会用于标准设备,CDC 类就没有用到(如果需要的话,应该也是能发出的)。 D4~D0:代表了请求类型。 因为请求的内容可能是面向设备,也可能面向接口、端点,所以这个域确定了本次请求面向的对象,这样设备可以根据请求的对象作相应的措施。 第二字节:bRequest:请求代码,即上面的几种请求代码,每个请求都会有请求代码,代表了具体请求。 第三四字节:wValue:这个双字节主要根据bReuest来确定含义,比如如果是获取描述符(GET_DESCRIPTOR),而描述符有很多种,比如设备描述符、字符串描述符、配置描述符,那么到底主机要获取什么描述符?就看这个双字的高字节了。如果高字节为 1,代表获取设备描述符,高字节为 2,代表获取配置描述符。 总之这个值的具体含义需要根据请求代码来确定,而每一种请求代码都会明确规定wValue具体含义。 第五六字节:wIndex:这个值和上面一样,也是需要请求代码来确定含义的。比如在获取产品序列号字符串时,这个值代表了语言 ID,告诉从机需要返回什么哪种字符串,当值为0x0409时代表英语。 第七八字节:wLenth:这个值代表接下来主机会发送或者需要接收字节长度。 一般来说,主机会根据需要在接下来的数据阶段获取或发送指定长度数据,主机发送的数据因为是由主机控制的,所以可以很容易确定这个值,但是因为主机并不清楚从机到底有多少数据会返回,所以这个值可能会比实际的更大。 比如第一次获取设备描述符时,因为主机不清楚这个描述符多长,一般会比实际的描述符长度更大,所以如果从机没有足够的数据返回,那么只要返回从机能返回的最大数据即可; 但是如果主机请求返回的数据比从机实际的数据短,那么从机就按照主机的要求来就行,不必把自己所有的数据返回。 以上就是标准请求的内容。设备返回的描述符通用格式比较简单: 第一字节:描述符总长度(包括本字节) 第二字节:描述符类型(对应标准请求wValue的高字节) 其余字节就代表了这个描述符的具体内容了,每种描述的具体内格式都不相同,需要根据实际的描述符确定,比如:

bcdUSB 代表 USB 版本号,比如 0x0110,代表 USB 1.1 版本(bcd编码,即写成十六进制时的版本号),这样主机就知道这个设备只支持全速 12 Mbit/s 那么关于关于高速的请求qualifier(wValue 高字节为6)就不用发送到该设备了,因为发送给设备也肯定会被回复 STALL,那么主机就没必要浪费这个带宽了。 但是如果你这里写成 0x0200,那么这个设备可能是全速的,也可能是高速的,那么主机就会发送请求来询问是否支持高速,如果设备不支持,回复的描述符设置为0即可。 接下来的三个字节根据设备属于什么类别来确定,比如 CDC 类,这三个值分别为 0x02 ,0x00,0x00。 bMaxPacketSize0 确定了端点0的数据包大小,主机可以据此知道设备的传输能力,进而控制传输数据包的大小,不然主机一次发送的数据包太大,那么从机可能无法正确接收。 idVendor 由 USB-IF 分配,这个值确定了这个设备属于哪个厂家的产品。比如 0xC251,代表了KEIL,只要主机看到了这个代号,就知道这个设备由哪个厂家生产的了,因为这个在USB-IF中挂了号,大家都可以从网上查到。 和必须购买的 idVendor 不同却类似的是,iProduct 是由厂家自己定义的,可以根据这个来确定这个设备属于哪个产品。 这个USB设备更新到哪一个版本了?通过bcdDevice 即可确定,也是bcd 编码。 iManufacture 代表厂商的字符串序号,一般都是 1,这样当主机需要获取厂商的字符串,只要在wValue 的低字节为设置为 1,那么从机就知道该发送什么字符串给主机了。 iProject 代表产品字符串序号,一般为2。 iSerialNumber 代表产品序列字符串序号,一般为3。 为什么从 1 开始编号,而不是从 0 开始呢,这是因为如果设备没有这个字符串的话,可以设置该值为 0,这样主机就知道没有这个字符串,也就不会主动获取这个字符串。 当然了,即使你告诉了主机有这个字符串存在,主机也是按照需求来获取的,不一定会把所有的字符串描述符都获取回来。 iNumConfigurations 代表了设备有多少种配置,前面说过,设备可能会在不同时刻的功能表现不一样,那么可以通过该值确定这个设备有多少种配置,一般而言这个值是1,即只有一种配置。毕竟复合设备可以同时满足多功能的要求,没必要使用多种配置来达到多种功能的要求。 以上就是设备描述符的具体含义,其他描述符比如配置描述符、接口描述符、端点描述符等就自行看鱼鹰给的资料理解即可,只要找到对应描述符的格式说明,分析代码中的描述符数据也不是那么难的事情。 接下来鱼鹰介绍枚举总体流程。 主机在对设备复位后,首先会请求获取设备描述符。这个描述符一般为18个字节,但是主机一开始并不知道这个描述符多大(虽然一般是18,但万一不是呢),所以一般主机会以更大的请求长度来获取,而从机根据实际长度18字节返回即可。 现在我们从多个维度看看这次交互的数据情况: 从传输事务的角度看:

从包的角度看:

从DATA内容看: 主机发送数据:80 06 00 01 00 00 40 00

从机回复数据:

从D+、D-数据线电平变化的角度: 主机发送(建立阶段):

从机回复(数据阶段):

状态阶段:

现在把整个枚举过程大概图解一遍(其他请求交互的具体情况请看鱼鹰提供的资料):

数据流截取(鱼鹰提供的《CDC设备完整数据通信.txt》):

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 设备
    +关注

    关注

    2

    文章

    4502

    浏览量

    70600
  • CDC
    CDC
    +关注

    关注

    0

    文章

    57

    浏览量

    17800

原文标题:【图解USB】USB 之CDC 设备枚举过程详解

文章出处:【微信号:mcu168,微信公众号:硬件攻城狮】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    USB复合设备MSC+CDC,MSC异常影响CDC收发怎么解决?

    MSC读写物理存储设备的时候,如果返回一次错误(错误码:-1),不知道为什么会触发一个枚举中断(USB_OTG_GINTSTS_ENUMDNE0),会调用到reset_callback,也会把CDC也会reset,导致
    发表于 07-23 06:23

    ESP32S2使用单根USB线创建MSC+CDC与上位机通信,CDC异常的原因?

    断开。 附件内有用WIRESHARK 4.2.0抓取到的数据包log可供参考,以下是对log的一些解析: 2.46.2是CDC设备 2.46.3是MSC设备 2.41.2是串口打印
    发表于 06-06 07:29

    解析经典蓝牙设备连接过程

    应用中,蓝牙设备发现、连接、断开等使用场景较为常见,其中设备连接是至关重要的一环,它涵盖了设备之间建立连接的整个过程。本文将对经典蓝牙设备
    的头像 发表于 06-05 09:11 2199次阅读
    <b class='flag-5'>解析</b>经典蓝牙<b class='flag-5'>设备</b>连接<b class='flag-5'>过程</b>

    STM32 USB Host LibraryV3.2.2枚举死机的原因?

    STM32 USB Host LibraryV3.2.2库刚移植的USB主机库,在使用的时候发现,反复拔插U盘出现死机现象甚至不识别,怀疑是枚举过程中出了问题。
    发表于 05-10 07:59

    使用nucleo_f767做USB CDC的测试,bus hound抓不到USB的包怎么解决?

    现在使用nucleo_f767做USB CDC的测试。驱动一直有问题,所以想通过bus hound查看一下枚举过程是不是有问题。但bus hound一直抓不到任何数据。在 插入usb的时候,没有数据产生。请问各位有什么好办法吗?谢谢。
    发表于 04-30 07:00

    用STM32f205+PHY做一个高速usb的Device设备,USB批量传输设置两个端点为OUT、IN后异常怎么解决?

    各位大神,小弟现在正在用STM32f205+PHY做一个高速usb的Device设备,需要使用两个端点,分别设置:端点2为OUT、端点6为IN的BULK模式。 正常逻辑应该是:枚举过程成功后,收到
    发表于 04-24 07:41

    请问USB CDC host怎么与多串口的从机通信?

    USB CDC host怎么与多串口的从机通信? 有一个从设备的USB虚拟了3个串口,作为主设备,如何分别识别出每个串口,分别于每个串口通信? 我的主设备使用的是官方单独的USB标准库
    发表于 04-11 06:11

    调试USB hots的时候,枚举过不去,为什么?

    调试USB hots的时候,枚举过不去,第一步的状态都不对。我看数据是中断函数USBH_OTG_ISR_Handler返回的,请问哪位有相关说明发一下,现在总是触发gintsts.b.sofintr中断。谢谢!
    发表于 04-10 07:28

    STM32H750 FATFS文件系统挂载USB驱动,USB驱动枚举过程一直处于ready状态是为什么?

    就是FATFS文件系统挂载USB驱动,读写U盘,我一直不成功USB驱动枚举过程一直处于ready 状态,文件系统挂载不成功!请问大家有知道怎么解决的吗?或者类似案列参考一下!谢谢!
    发表于 03-27 06:52

    USB复合设备MSC+CDC,CDC_Transmit_FS函数发送不正常的原因?

    单独测试CDC、MSC功能均正常,实现MSC+CDC复合设备后,均可正常识别到,但CDC_Transmit_FS函数不正常,现象如下: 1、在主循环里调用
    发表于 03-13 07:40

    求助,关于USB复合设备HID+CDC串口问题求解

    分别写了CustomHID的键鼠代码、CDC代码测试均无问题,整合到一起后,插上电脑有时识别串口,有时识别HID,最终过不了几秒HID的设备挂掉报代码10,虽然串口显示设备正常运行,但
    发表于 03-07 06:11

    如何同时枚举SlaveFIFO和UART(CDC)?

    我使用Re: Slave FIFO + UART Driver Setup中的程序,将img下载进FX3中,成功枚举出了“USB串行设备(COM13)”,但是并没有出现
    发表于 02-28 07:23

    对cyusb3014写入slavefifo + CDC固件后,低概率被枚举为2.0接口的原因?

    对cyusb3014经Control Center写入slavefifo + CDC固件后,低概率被枚举为 USB2.0 接口,正常为 USB3.0 接口 , 这个问题通常要考虑哪些原因所致呢?
    发表于 02-27 07:36

    请问PSoC63 USB能同时枚举CDC、Audio、HID吗?

    在用CY8C6347FMI-BUD53这颗芯片做USB开发,是否同时枚举CDC、Audio、HID这三类设备,或者同时枚举CDC、Aud
    发表于 02-18 07:07

    枚举有多大?c语言枚举end的作用是什么?

    枚举有多大?c语言枚举end的作用是什么? 枚举在C语言中是一种常见的数据类型,用于定义一组相互关联的常量或者变量。它通常用于表示一系列可能的取值,使得程序更加易读和易维护。在C语言中,枚举
    的头像 发表于 01-19 14:19 593次阅读