UVC 基础学习(3):基础描述符介绍

简介: UVC 基础学习(3):基础描述符介绍

1. 概述


描述符用来描述USB设备性能或特性的数据结构,与设备类相关的信息都是主机向设备获取描述符来得到的。


一个UVC设备除了常用的标准描述符,另外还定义了视频设备的特殊类描述符,主要如下:


标准描述符


  • 设备描述符(Device Descriptor)


  • 设备限定描述符(Device QualifierDescriptor)


  • 设备配置描述符(Configure Descriptor)


  • 其他速度描述符(Other Speed Descriptor)


  • 字符描述符(String Descriptor)


特殊类描述符


  • 接口联合描述符(Interface Association Descriptor)


  • 视频控制接口描述符(VideoControl Interface Descriptor)


  • 视频控制端点描述符(VideoControl Endpoint Descriptor)


  • 视频流接口描述符(VideoStreaming Interface Descriptor)


  • 视频流端点描述符(VideoStreaming Endpoint Descriptor)


接下来,我们将重点分析这些描述符信息。


2. UVC设备逻辑组织


uvc 设备逻辑组织如下。至少包含一个配置描述符两个接口,接口0负责VideoControl,接口1负责VideoStream。


image.png


3. 描述符介绍


3.1 设备描述符


设备描述符信息如下(来源于USB_Video_Class_1.5)


  • bLength:固定长度 0x12


  • bDescriptorType:设备类型,默认设为1


  • bcdUSB:USB版本号。1.1~0x0110 2.0~0x0200


  • bDeviceClass:设备类.此处设为0xEF


  • bDeviceSubClass:设备子类。此处设为0x02


  • bDeviceProtocol:协议代码。默认为0x1


  • bMaxPacketSize0:控制端点最大包长。动态设置


  • idVendor:厂商编号


  • idProduct:产品ID


  • bcDevice:设备版本号


  • iManufacturer:厂商字符串描述符索引


  • iProduct:产品字符串描述符索引


  • iSerialNumber:产品序列号描述符索引


  • bNumConfigurations:支持的配置数量,一般为1

image.png


对比 driver/usb/gadget/webcam.c,可以看到dynamic都是可以动态调整的。


static struct usb_device_descriptor webcam_device_descriptor = {
 .bLength  = USB_DT_DEVICE_SIZE,
 .bDescriptorType = USB_DT_DEVICE,
 .bcdUSB   = cpu_to_le16(0x0200),
 .bDeviceClass  = USB_CLASS_MISC,
 .bDeviceSubClass = 0x02,
 .bDeviceProtocol = 0x01,
 .bMaxPacketSize0 = 0, /* dynamic */
 .idVendor  = cpu_to_le16(WEBCAM_VENDOR_ID),
 .idProduct  = cpu_to_le16(WEBCAM_PRODUCT_ID),
 .bcdDevice  = cpu_to_le16(WEBCAM_DEVICE_BCD),
 .iManufacturer  = 0, /* dynamic */
 .iProduct  = 0, /* dynamic */
 .iSerialNumber  = 0, /* dynamic */
 .bNumConfigurations = 0, /* dynamic */
};


3.2 配置描述符


配置描述符如下:


  • bLength:描述符长度,固定为0x9


  • bDescriptorType:配置描述符类型。默认为0x2


  • wTotalLength:表示整个配置描述符的总长度,包括配置描述符,接口描述符,类特殊描述符和端点描述符


  • bNumInterFaces:配置支持的接口数


  • bConfigurationValue:配置ID,每个配置都有一个标识值


  • iConfiguration:配置描述符字符串索引。


  • bmAttributes:描述供电特性 D7保留,D6辨识供电方式,为1表示自供电的,否则是总线供电,D5标识是否支持远程唤醒(1),D4-D0保留


  • bMaxPower:总线供电时的最大电流,如值为100则最大电流为200mA。



配置描述符配置在driver/usb/gadget/compsite.c下


/* driver/usb/gadget/compsite.c */
static int config_buf(struct usb_configuration *config,
  enum usb_device_speed speed, void *buf, u8 type)
{
 struct usb_config_descriptor *c = buf;
 void    *next = buf + USB_DT_CONFIG_SIZE;
 int    len;
 struct usb_function  *f;
 int    status;
 len = USB_COMP_EP0_BUFSIZ - USB_DT_CONFIG_SIZE;
 /* write the config descriptor */
 c = buf;
 c->bLength = USB_DT_CONFIG_SIZE;
 c->bDescriptorType = type;
 /* wTotalLength is written later */
 c->bNumInterfaces = config->next_interface_id;
 c->bConfigurationValue = config->bConfigurationValue;
 c->iConfiguration = config->iConfiguration;
 c->bmAttributes = USB_CONFIG_ATT_ONE | config->bmAttributes;
 c->bMaxPower = encode_bMaxPower(speed, config);
    ......
 /* add each function's descriptors */
    ......
 len = next - buf;
 c->wTotalLength = cpu_to_le16(len);
 return len;
}


3.3 接口关联描述符(IAD)


接口关联描述符信息如下:


  • bLength:固定长度,为0x8


  • bDescriptorType:接口关联描述符类型。0xb 表示IAD


  • bFristInterface:接口number


  • bInterfaceCount:连续的video 接口数,这里为2


  • bFunctionClass:设备类。0xE 表示Video Class


  • bFunctionSubClass:子类。表示支持的具体功能。这里是0x3对应

VIDEO_INTERFACE_COLLECTION,支持VideoControl 和VideoInterface


  • bFunctionProtocol:默认0


  • iFunction:字符串索引


image.png


可以看到,UVC设备通过 IAD 去描述一个视频接口集合(Video Interface Collection)


注:Video Interface Collection 是一个视频接口集合。一个UVC设备必须通过IAD来描述Video Interface Collection,并且至少包含一个VideoControl Interface 和一个或多个VideoStream Interface


image.png



/* driver/usb/gadget/function/f_uvc.c */
static struct usb_interface_assoc_descriptor uvc_iad = {
 .bLength  = sizeof(uvc_iad),
 .bDescriptorType = USB_DT_INTERFACE_ASSOCIATION,
 .bFirstInterface = 0,
 .bInterfaceCount = 2,
 .bFunctionClass  = USB_CLASS_VIDEO,
 .bFunctionSubClass = UVC_SC_VIDEO_INTERFACE_COLLECTION,
 .bFunctionProtocol = 0x00,
 .iFunction  = 0,
};


4. 总结


有关 UVC的描述符组织信息,实在太多,本文先介绍基础描述符,后续陆续介绍,VideoControl ,VideoStream等描述符信息,这个是UVC的关键。


所有信息来源于《UVC 1.5 Class specfication》和《USB_Video_Example.pdf》以及内核源码参考。

相关文章
|
Ubuntu Linux 编译器
字符驱动设备原理及其相关函数(一)
字符驱动设备原理及其相关函数(一)
114 0
|
11月前
|
存储 Linux 调度
【看表情包学Linux】系统下的文件操作 | 文件系统接口 | 系统调用与封装 | open,write,close 接口 | 系统传递标记位 O_RDWR,O_RDONLY,O_WRONLY...
【看表情包学Linux】系统下的文件操作 | 文件系统接口 | 系统调用与封装 | open,write,close 接口 | 系统传递标记位 O_RDWR,O_RDONLY,O_WRONLY...
95 1
|
2月前
|
Ubuntu Linux
内核实验(六):使用misc框架,实现简单字符设备驱动
本文介绍了如何使用Linux的misc框架来实现一个简单的字符设备驱动程序,包括编写驱动源码、编译、部署以及在Qemu虚拟机中测试驱动程序,展示了如何动态分配次设备号并手动创建设备文件以进行测试。
33 0
内核实验(六):使用misc框架,实现简单字符设备驱动
|
4月前
|
Linux
【Linux驱动学习(1)】USB与input子系统,linux统一设备模型,枚举,USB描述符深入剖析
【Linux驱动学习(1)】USB与input子系统,linux统一设备模型,枚举,USB描述符深入剖析
|
5月前
|
缓存 Python
什么是Python中的描述符(Descriptor)?如何实现一个描述符?
什么是Python中的描述符(Descriptor)?如何实现一个描述符?
56 2
|
10月前
|
存储 Windows
4.6 Windows驱动开发:内核遍历进程VAD结构体
在上一篇文章`《内核中实现Dump进程转储》`中我们实现了ARK工具的转存功能,本篇文章继续以内存为出发点介绍`VAD`结构,该结构的全程是`Virtual Address Descriptor`即`虚拟地址描述符`,VAD是一个`AVL`自`平衡二叉树`,树的每一个节点代表一段虚拟地址空间。程序中的代码段,数据段,堆段都会各种占用一个或多个`VAD`节点,由一个`MMVAD`结构完整描述。
111 0
4.6 Windows驱动开发:内核遍历进程VAD结构体
|
12月前
|
存储 Linux API
嵌入式Linux 字符设备驱动标准ioctl接口
嵌入式Linux 字符设备驱动标准ioctl接口
驱动开发:通过ReadFile与内核层通信
驱动与应用程序的通信是非常有必要的,内核中执行代码后需要将其动态显示给应用层,但驱动程序与应用层毕竟不在一个地址空间内,为了实现内核与应用层数据交互则必须有通信的方法,微软为我们提供了三种通信方式,如下先来介绍通过`ReadFile`系列函数实现的通信模式。
319 0
驱动开发:通过ReadFile与内核层通信
|
编解码 C++
UVC调用过程部分细节分析
UVC调用过程部分细节分析
560 0
|
Linux
字符驱动设备原理及其相关函数(二)
字符驱动设备原理及其相关函数(二)
57 0