USB 的UVC协议分析

UVC(USB Video Class)是USB的一种协议,可以直接传输视频。之前在STM32和GD32上做过UVC的驱动,先大致介绍下

  1. USB的枚举
    USB枚举过程主要分为:
    1)USB主机检测到USB设备插入后,就会先对设备复位。
    2)USB设备在总线复位后其地址为0,这样主机就可以通过地址0和那些刚插入的设备通信。USB主机往地址为0的设备的端点0发送获取设备描述符的请求(控制传输的建立过程)。设备收到该请求后,会按照主机请求的参数,在数据过程将设备描述符返回给主机。
    3)主机在成功获取到一个数据包的设备描述符并确认没有错误后,就返回一个0长度的确认数据包(状态过程)给设备,从而进入到接下来的设置地址阶段。
    4)第一次主机只会读取一个数据包的设备描述符。标准的设备描述符有18字节,有些USB设备的端点0大小不足18字节(但至少具有8字节),在这种情况下,USB主机也是只发送一次数据输入请求,多余的数据将不会再次请求。因此当设备端点0大小不足18字节时,就需要注意到这个问题。也就是说在第一次获取设备描述符时,只需要返回一次数据即可,不要再等主机继续获取剩余数据(如果还有),因为主机不会这么做。当主机成功获取到设备描述符的前8字节之后(USB协议端点0最大包长至少8字节),它就知道端点0的最大包长度了,因为端点0最大包长度刚好再设备描述符的第八字节处。
    5)主机对设备又一次复位。这时就进入到了设置地址阶段。
    6) USB主机往地址为0的设备端点0发送一个设置地址的请求(控制传输的建立阶段),新的设备地址包含在建立过程的数据包中。具体的地址由USB主机负责管理,主机会分配一个唯一的地址给刚接入的设备。USB设备在收到这个建立过程之后,就直接进入状态过程,因为这个控制传输没有数据过程。设备等待主机请求状态返回(一个输入令牌包),收到输入令牌包后,设备就返回0长度的状态数据包。如果主机确认该状态包已经正确收到,就会发送应答包ACK给设备,设备在收到这个ACK之后,就要启用新的设备地址了。这样设备就分配到了唯一的设备地址,以后主机就通过它来访问该设备。
    7)主机再次获取设备描述符。 这次能第一次有些不一样,首先是主机不再使用地址0来访问呢设备,而是使用新的设备地址;另外,这次需要获取全部的18字节的设备描述符。如果你的端点0最大包长小于18字节,那就会有多次请求数据输入(即发送多个IN令牌包)。
    主机获取配置描述符。 配置描述符共9字节。主机获取到配置描述符后,根据配置描述符中所描述的配置集合总长度,获取配置集合。获取配置描述符和获取配置描述符请求是差不多的,只是指定的长度不一样。有些主机干脆不单独获取配置描述符,而是直接使用最大长度来获取配置描述符集合,因为设备实际返回的数据可以少于指定的字节数。配置描述符集合包括配置描述符、接口描述符、类特殊描述符(如果有)、端点描述符等。接口描述符、类特殊描述符、端点描述符是不能单独获取的,必须跟随配置描述符以一个集合的方式一并返回。
    流程图图1-1所示

USB 的UVC协议分析_第1张图片
图1-1

2.UVC的枚举分析
首先看标准请求的格式,如图2-1
USB 的UVC协议分析_第2张图片
图2-1
以T30为例,先看BUSHOND对枚举的数据抓取,如图2-2
USB 的UVC协议分析_第3张图片
图2-2
先看枚举阶段一
1) CTL 80 06 00 01 00 00 12 00 (获取描述符)
CTL 是“USB control transfer”,控制传输,是双向传输方式。UVC设备插入PC后,PC向其端点0发送了8个字节的 数据
0x80(1000 0000b): D7-1 设备到主机 ; D6:5-00 标准请求; D4:0-0000 接受者为设备
0x06:GET_DESCRIPTOR 获取描述符请求
0x0100 :0x01 设备描述符 ;0x00 描述符ID
0x0000: 空
0x0012: 请求数据长度,设备需要上传0x12个数据
2) IN 12 01 00 02 ef 02 01 40 15 c2 15 17 00 02 01 12 03 01 (上传设备描述符)
3) CTL 80 06 00 02 00 00 09 00 (获取配置描述符)
0x80(1000 0000b): D7-1 设备到主机 ; D6:5-00 标准请求; D4:0-0000 接受者为设备
0x06:GET_DESCRIPTOR 获取描述符请求
0x0200 :0x02 配置描述符 ;0x00 描述符ID
0x0000: 空
0x0009: 请求数据长度,设备需要上传0x09个数据
4) IN 09 02 cf 00 02 01 11 80 32 (上传配置描述符)
5) CTL 80 06 00 02 00 00 cf 00 (获取配置描述符集合,包含配置+IAD+接口+端点)
6) IN 09 02 cf 00 02 01 11 80 32 09 04 00 00 00 0e 01…(上传描述符集合)
7) SET_CONFIGURATION(设置配置指令)
CTL 00 09 01 00 00 00 00 00 SET CONFIG
0x00(0000 0000b): D7-0 主机到设备,数据为OUT方向 ; D6:5-00 标准请求; D4:0-0000 接受者为设备
0x09: SET_CONFIGURATION 设置配置请求
0x0001 :0x01 配置描述符中的Configuration Value 值
0x0000: 空
0x0000: 空
8) CTL 01 0b 00 00 01 00 00 00 (设置接口指令)
0x00(0000 0001b): D7-0 设备到主机 ; D6:5-00 标准请求; D4:0-0001 接收者为接口
0x0b: SET_INTERFACE 设置接口请求
0x0000 :接口备用配置ID
0x0001: 接口ID(VS接口)
0x0000: 空

枚举阶段二
USB 的UVC协议分析_第4张图片
以上指令都是特定类请求
以第一条为例
CTL a1 86 00 02 00 03 01 00 GET INFO
0xa1(1010 0001b): D7-0 设备到主机,指的是主机请求获取数据 ; D6:5-01 类请求; D4:0-0001 接受者为接口
0x86: GET_INFO 获取功能或动态
0x0200 :0x02 PU_BRIGHTNESS_CONTROL ; 0x00 Zero
0x0300: 0x03 单元ID ; 0x00 接口ID(VC接口)
0x0001: 请求数据长度,设备需要上传1个数据
以上就是UVC的枚举过程
打开摄像头和关闭摄像头
在这里插入图片描述
UVC相机在打开时,会使用SET_INTERFACE命令,在停止播放时,也会发送SET_INTERFACE命令。
打开时,数据抓包为:
CTL 01 0b 01 00 01 00 00 00 SET INTERFACE
停播放时,数据抓包为:
CTL 01 0b 00 00 01 00 00 00 SET INTERFACE
通过SET_INTERFACE数据命令分析,可知
01 :x01表示从主机到设备,请求标准命令,接收者为接口。
0b :表示设置接口
打开时,值为 01 00,即0x0001,表示接口,转换接口=1
打开时,值为 01 00,即0x0000,表示接口,转换接口=0
01 00 :表示接口为1.
00 00 :表示数据长度为0.
通过上面可以知道,打开或停止摄像头,是通过转换接口来实现的。
在T30程序中,当打开摄像头时,程序会进入uint8_t USBD_UVC_SOF (USBD_HandleTypeDef *pdev)中,在里面将状态标志置为UVC_STATE_NEED_FRAME,然后再进入uint8_t USBD_UVC_DataIn (USBD_HandleTypeDef *pdev,uint8_t epnum)中,里面的状态标志判断为UVC_STATE_NEED_FRAME,之后就发送数据了。
4.通讯接口
通讯都是靠VC命令的控制对比度来实现,每次只能传输2个字节,需要发送多次SET和GET,以单点校正为例,如图4-1
USB 的UVC协议分析_第5张图片
图4-1
1)通讯命令的接收
发送的2个字节都会进入到uint8_t USBD_UVC_EP0_RxReady (USBD_HandleTypeDef *pdev)中,在USB_COM_Receive(VideoCtl,&USB_Command,&USB_instructReply)函数中进行一帧数据的完整接收,按照VIVA协议来进行。USB_Command是接收的结构体,USB_instructReply是回复的结构体。若是1帧完整接收,且CRC校验都正常,则会置位接收按成的标志位。
2)通讯命令的解析
当接收完成后,USB_CommunicationInteractive(&USB_Command,&USB_instructReply)函数进行解析, 在Data_Analysis文件中。所有的通讯命令如单点校正都在此文件中进行解析
3)通讯命令的驱动
当解析完成后,需要进行相应的命令驱动。我把所有的命令驱动都放在了CommandDrever文件中。
4)通讯命令的回复
主机会发送GET指令,程序最终会进入到void UVC_Req_GetCurrent(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)中,每GET1次,传输2个字节。PtrUPloadInformation是个全局指针,指向回复的结构体地址。如图4-2和4-3所示
USB 的UVC协议分析_第6张图片
图4-2
USB 的UVC协议分析_第7张图片
图4-3

UVC的话资料不多,有个网站对这一块研究挺深的
USB中文网

你可能感兴趣的:(stm32)