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 编译器
字符驱动设备原理及其相关函数(一)
字符驱动设备原理及其相关函数(一)
127 0
|
3月前
|
Ubuntu Linux
内核实验(六):使用misc框架,实现简单字符设备驱动
本文介绍了如何使用Linux的misc框架来实现一个简单的字符设备驱动程序,包括编写驱动源码、编译、部署以及在Qemu虚拟机中测试驱动程序,展示了如何动态分配次设备号并手动创建设备文件以进行测试。
52 0
内核实验(六):使用misc框架,实现简单字符设备驱动
|
3月前
|
Linux
内核实验(五):传统简单字符设备驱动
本文通过一个简单的字符设备驱动程序实验,演示了如何在Linux内核中编写、编译和测试驱动代码,并使用Qemu虚拟机和NFS环境进行部署和验证,同时检验了NFS环境对于提高开发效率的作用。
44 0
内核实验(五):传统简单字符设备驱动
|
2月前
|
存储 安全 测试技术
GPIO描述符消费者接口 【ChatGPT】
GPIO描述符消费者接口 【ChatGPT】
|
5月前
|
Linux
【Linux驱动学习(1)】USB与input子系统,linux统一设备模型,枚举,USB描述符深入剖析
【Linux驱动学习(1)】USB与input子系统,linux统一设备模型,枚举,USB描述符深入剖析
|
6月前
|
缓存 Python
什么是Python中的描述符(Descriptor)?如何实现一个描述符?
什么是Python中的描述符(Descriptor)?如何实现一个描述符?
67 2
|
存储 Linux API
嵌入式Linux 字符设备驱动标准ioctl接口
嵌入式Linux 字符设备驱动标准ioctl接口
|
Linux 编译器
Linux设备驱动---字符设备驱动接口函数
Linux设备驱动---字符设备驱动接口函数
175 1
|
编解码 C++
UVC调用过程部分细节分析
UVC调用过程部分细节分析
619 0
|
Linux
字符驱动设备原理及其相关函数(二)
字符驱动设备原理及其相关函数(二)
65 0