windows USB 设备驱动开发-USB描述符

news2024/10/6 20:31:22
配置描述符

USB 设备以一系列称为 USB 配置的接口的形式公开其功能。 每个接口由一个或多个备用设置组成,每个备用设置由一组端点组成。

配置描述符中描述了 USB 配置。 配置描述符包含有关配置及其接口、备用设置及其端点的信息。 每个接口描述符或备用设置均在 USB_INTERFACE_DESCRIPTOR 结构中描述。 在配置中,每个接口描述符在内存中后跟接口和备用设置的所有端点描述符。 每个端点描述符都存储在 USB_ENDPOINT_DESCRIPTOR 结构中。

例如,请考虑 USB 设备布局中描述的 USB 网络摄像头设备。 设备支持具有两个接口的配置,第一个接口 (索引 0) 支持两个备用设置。

以下示例显示了 USB 网络摄像头设备的配置描述符:

Configuration Descriptor:
wTotalLength:         0x02CA
bNumInterfaces:       0x02
bConfigurationValue:  0x01
iConfiguration:       0x00
bmAttributes:         0x80 (Bus Powered )
MaxPower:             0xFA (500 mA)

bConfigurationValue 字段指示设备固件中定义的配置编号。 客户端驱动程序使用该数字值来选择活动配置。 有关 USB 设备配置的详细信息,请参阅 如何为 USB 设备选择配置。 USB 配置还指示某些电源特征。 bmAttributes 包含一个位掩码,指示配置是否支持远程唤醒功能,以及设备是总线供电还是自供电。 MaxPower 字段指定当设备采用总线供电时,设备可从主机提取的最大功率(以毫安为单位)。 配置描述符还指示设备支持的 (bNumInterfaces) 接口总数。

接口描述符

以下示例显示了网络摄像头设备的接口 0 的备用设置 0 的接口描述符:

Interface Descriptor:
bInterfaceNumber:     0x00
bAlternateSetting:    0x00
bNumEndpoints:        0x01
bInterfaceClass:      0x0E
bInterfaceSubClass:   0x02
bInterfaceProtocol:   0x00
iInterface:           0x02
0x0409: "Microsoft LifeCam VX-5000"
0x0409: "Microsoft LifeCam VX-5000"

在前面的示例中,请注意 bInterfaceNumber 和 bAlternateSetting 字段值。 这些字段包含客户端驱动程序用于激活接口及其备用设置之一的索引值。 对于激活,驱动程序会向 USB 驱动程序堆栈发送选择接口请求。 然后,驱动程序堆栈 (SET INTERFACE) 生成标准控制请求并将其发送到设备。 请注意 bInterfaceClass 字段。 接口描述符或其任何备用设置的描述符指定类代码、子类和协议。 0x0E 的值指示接口适用于视频设备类。 另请注意 iInterface 字段。 该值指示在接口描述符后面追加了两个字符串描述符。 字符串描述符包含 Unicode 说明,这些说明在设备枚举期间用于标识功能。 有关字符串描述符的详细信息,请参阅 USB 字符串描述符。

接口中的每个端点描述设备的单个输入或输出流。 支持不同类型函数流的设备具有多个接口。 支持与一个函数相关的多个流的设备可以支持单个接口上的多个端点。

端点描述符

除默认端点之外,所有类型的端点必须提供端点描述符,以便主机可以获取有关端点的信息。端点描述符包括其地址、类型、方向和端点可以处理的数据量等信息。 到端点的数据传输基于该信息。

以下示例显示了网络摄像头设备的端点描述符:

Endpoint Descriptor:
bEndpointAddress:   0x82  IN
bmAttributes:       0x01
wMaxPacketSize:     0x0080 (128)
bInterval:          0x01


bEndpointAddress 字段指定包含端点编号 (位 3.0) 的唯一端点地址,以及端点方向 (位 7) 。 通过读取上述示例中的这些值,我们可以确定描述符描述了端点编号为 2 的 IN 端点。 bmAttributes 属性指示端点类型为常时等量。 wMaxPacketSizefield 指示端点在单个事务中可以发送或接收的最大字节数。 位 12..11 指示每个微帧可以发送的事务总数。 bInterval 指示端点发送或接收数据的频率。

字符串描述符

设备、配置和接口描述符可能包含对字符串描述符的引用。 本主题介绍如何从设备获取特定字符串描述符。

字符串描述符由其从 1 开始的索引号引用。 字符串描述符包含一个或多个 Unicode 字符串;每个字符串都是将其他字符串翻译成另一种语言。

客户端驱动程序使用 DescriptorType = USB_STRING_DESCRIPTOR_TYPE 的 UsbBuildGetDescriptorRequest 生成请求以获取字符串描述符。 Index 参数指定索引号,LanguageID 参数指定语言 ID, (与 Microsoft Win32 LANGID 值) 相同的值使用。 驱动程序可以请求特殊索引号 0,以确定设备支持的语言 ID。 对于此特殊值,设备返回语言 ID 数组,而不是 Unicode 字符串。

由于字符串描述符包含可变长度的数据,因此驱动程序必须分两个步骤获取它。 首先,驱动程序必须发出请求,传递足够大的数据缓冲区来保存字符串描述符(USB_STRING_DESCRIPTOR结构)的标头。 USB_STRING_DESCRIPTOR 的 bLength 成员指定整个描述符的大小(以字节为单位)。 然后,驱动程序使用大小 为 bLength 的数据缓冲区发出相同的请求。

以下代码演示如何使用语言 ID langID 请求第 i 个字符串描述符:
 

USB_STRING_DESCRIPTOR USD, *pFullUSD;
UsbBuildGetDescriptorRequest(
    pURB, // points to the URB to be filled in
    sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST),
    USB_STRING_DESCRIPTOR_TYPE,
    i, // index of string descriptor
    langID, // language ID of string.
    &USD, // points to a USB_STRING_DESCRIPTOR.
    NULL,
    sizeof(USB_STRING_DESCRIPTOR),
    NULL
);
pFullUSD = ExAllocatePool(NonPagedPool, USD.bLength);
UsbBuildGetDescriptorRequest(
    pURB, // points to the URB to be filled in
    sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST),
    USB_STRING_DESCRIPTOR_TYPE,
    i, // index of string descriptor
    langID, // language ID of string
    pFullUSD,
    NULL,
    USD.bLength,
    NULL
);
接口关联描述符

USB 接口关联描述符 (IAD) 允许设备对属于某个函数的接口进行分组。 本文介绍客户端驱动程序如何确定设备是否包含函数的 IAD。

通用串行总线规范(修订版 2.0)不支持在单个函数中对复合设备的多个接口进行分组。 但是,USB 设备工作组 (DWG) 创建了允许具有多个接口的函数的 USB 设备类。 USB 实施者论坛 (ECN) 发布了工程更改通知,该通知定义了接口分组机制。

ECN 指定一个 USB 描述符,称为接口关联描述符 (IAD) ,它允许硬件制造商定义接口分组。 最有可能使用 IAD 的设备类包括:

  • USB 视频类规范 (类代码 - 0x0E)
  • USB 音频类规范 (类代码 - 0x01)
  • USB 蓝牙类规范 (类代码 - 0xE0)
在固件中向 Windows 发出 IAD 警报的复合设备

根据通用串行总线规范的指定,复合设备的制造商通常会将值分配给设备类 (bDeviceClass) 、子类 (bDeviceSubClass) 和协议 (bDeviceProtocol) 字段的值。 制造商可以将每个单独的接口与不同的设备类和协议相关联。

USB-IF 核心团队设计了一个特殊的类和协议代码集,用于通知操作系统设备固件中存在一个或多个 IAD。 设备描述符必须具有下表中显示的值,否则操作系统无法正确检测设备的 IAD 或对设备的接口进行分组。

代码值警告不支持 IAD 的 Windows 版本安装正确枚举设备的特殊用途总线驱动程序。 如果没有设备描述符中的这些代码,系统可能无法枚举设备,或者设备可能无法正常工作。

一个设备可以有多个 IAD。 每个 IAD 必须紧挨在 IAD 描述的接口组中的接口之前。

功能类 (bFunctionClass) 、子类 (bFunctionSubclassClass) ,以及 IAD 的协议 (bFunctionProtocol) 字段必须包含描述函数中接口的 USB 设备类指定的值。

IAD 的类和子类字段不需要与 IAD 描述的接口集合中的接口的类和子类字段相匹配。 Microsoft 建议集合的第一个接口具有与 IAD 的类和子类字段匹配的类和子类字段。 下表指示应匹配的字段。

IAD 的 bFirstInterface 字段指示函数中第一个接口的编号。 IAD 的 bInterfaceCount 字段指示接口集合中的接口数。 IAD 接口集合中的接口必须是连续的的接口编号列表中不能有间隙,因此具有第一个接口号的计数足以指定集合中的所有接口。

访问 IAD 的内容

客户端驱动程序无法直接访问 IAD 描述符。 IAD 工程更改通知 (ECN) 指定设备在收到主机软件对配置描述符 (GetDescriptor 配置) 的请求时返回的配置信息中必须包含 IAD。 主机软件无法使用 GetDescriptor 请求直接检索 IAD。

但是,客户端驱动程序可以查询 USB 设备的父驱动程序以获取设备的硬件标识符ID,并且设备的硬件 ID 包含有关 IAD 字段的嵌入信息。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1891352.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何使用python网络爬虫批量获取公共资源数据教程?

原文链接:如何使用python网络爬虫批量获取公共资源数据教程?https://mp.weixin.qq.com/s?__bizMzUzNTczMDMxMg&mid2247608240&idx4&snef281f66727afabfaae2066c6e92f792&chksmfa826657cdf5ef41571115328a09b9d34367d8b11415d5a5781dc4c…

Audio Processing Graphs 管理 Audio Units

Audio Processing Graphs 管理 Audio Units Audio Processing Graphs 管理 Audio UnitsAudio Processing Graph 拥有精确的 I/O UnitAudio Processing Graph 提供线程安全通过 graph "pull" 音频流 Audio Processing Graphs 管理 Audio Units audio processing grap…

Flutter——最详细(Badge)使用教程

背景 主要常用于组件叠加上圆点提示; 使用场景,消息数量提示,消息红点提示 属性作用backgroundColor红点背景色smallSize设置红点大小isLabelVisible是否显示offset设置红点位置alignment设置红点位置child设置底部组件 代码块 class Badge…

Go语言学习:每日一练3

Go语言学习:每日一练3 目录 Go语言学习:每日一练3方法接口继承类型断言 方法 方法是一类有接收者参数的函数。 接收者的类型定义和方法的声明必须在一个包里 type MyInt intfunc (m MyInt) Add(add int) int {return int(m) add } //OR func (m *MyInt)…

Python绘制动态股价曲线图并保存视频

用akshare库获取英伟达(股票代码:105.NVDA) 在2014年6月19日到2024年6月19日期间的股票的收盘价数据(用后复权的收盘价); 基于后复权的收盘价数据,做一个动态股价曲线图,逐日显示英伟达股价的动态变化情况&…

Python28-7.1 降维算法之PCA主成分分析

降维算法是一类数据处理技术,主要用于将高维数据映射到低维空间中,从而减少数据的维度。降维不仅可以减少计算复杂度,提高算法性能,还可以帮助数据可视化。常见的降维算法包括主成分分析(PCA)、线性判别分析…

DP:背包问题----0/1背包问题

文章目录 💗背包问题💛背包问题的变体🧡0/1 背包问题的数学定义💚解决背包问题的方法💙例子 💗解决背包问题的一般步骤?💗例题💗总结 ❤️❤️❤️❤️❤️博客主页&…

力扣Hot100-19删除链表的倒数第n个节点(双指针)

给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。 示例 1: 输入:head [1,2,3,4,5], n 2 输出:[1,2,3,5]示例 2: 输入:head [1], n 1 输出:[]示例 3:…

UCOS-III 任务调度与就绪列表管理

01. 就绪优先级位图 在实时操作系统中,任务调度的效率至关重要。UCOS-III通过就绪优先级位图来快速查找最高优先级的就绪任务,从而实现高效调度。就绪优先级位图是一个按位表示的结构,每个位代表一个优先级,当某个优先级上有任务就…

本地Windows电脑 连接 Windows 服务器

Windows电脑 连接 Windows 服务器 方式1:直接搜索 在电脑的搜索栏,输入“远程桌面连接” 可以选择点击 “打开” 或者直接按 回车键 “Enter”,打开 远程桌面连接 方式2:运行框打开服务器连接 同时按:Windows徽标键…

分布式数据库HBase:从零开始了解列式存储

在接触过大量的传统关系型数据库后你可能会有一些新的问题: 无法整理成表格的海量数据该如何储存? 在数据非常稀疏的情况下也必须将数据存储成关系型数据库吗? 除了关系型数据库我们是否还有别的选择以应对Web2.0时代的海量数据? 如果你也曾经想到过这些问题, 那么HBase将是…

CTF之unseping

拿到题目看不懂&#xff1f;这是难度1&#xff1f;含泪去看大佬的wp&#xff0c;写下我的自传&#xff01; <?php highlig…

常微分方程算法之编程示例十-两点狄利克雷边值问题(理查德森外推法)

目录 一、研究问题 二、C++代码 三、计算结果 一、研究问题 本节我们采用理查德森法对示例八中的两点狄利克雷边值问题进行外推求解,相应的原理及推导思路请参考: 常微分方程算法之高精度算法(Richardson法+紧差分法)_richardson外推法-CSDN博客https://blog.csdn.net/…

【SVN的使用-源代码管理工具-SVN介绍-服务器的搭建 Objective-C语言】

一、首先,我们来介绍一下源代码管理工具 1.源代码管理工具的起源 为什么会出现源代码管理工具,是为了解决源代码开发的过程中出现的很多问题: 1)无法后悔:把项目关了,无法Command + Z后悔, 2)版本备份:非空间、费时间、写的名称最后自己都忘了干什么的了, 3)版本…

【服装识别系统】图像识别+Python+人工智能+深度学习+算法模型+TensorFlow

一、介绍 服装识别系统&#xff0c;本系统作为图像识别方面的一个典型应用&#xff0c;使用Python作为主要编程语言&#xff0c;并通过TensorFlow搭建ResNet50卷积神经算法网络模型&#xff0c;通过对18种不同的服装&#xff08;‘黑色连衣裙’, ‘黑色衬衫’, ‘黑色鞋子’, …

Linux多进程和多线程(五)进程间通信-消息队列

多进程(五) 进程间通信 消息队列 ftok()函数创建消息队列 创建消息队列示例 msgctl 函数示例:在上⼀个示例的基础上&#xff0c;加上删除队列的代码 发送消息 示例: 接收消息示例 多进程(五) 进程间通信 消息队列 消息队列是一种进程间通信机制&#xff0c;它允许两个或多个…

终身免费的Navicat数据库,不需要破解,官方支持

终身免费的Navicat数据库&#xff0c;不需要破解&#xff0c;官方支持 卸载了Navicat&#xff0c;很不爽上干货&#xff0c;Navicat免费版下载地址 卸载了Navicat&#xff0c;很不爽 公司不让用那些破解的数据库软件&#xff0c;之前一直使用Navicat。换了几款其他的数据库试了…

大数据开发如何快速进阶

目录 1. 个人经验与心得分享1.1 试错的价值与机会把握1.2 投入产出比的考量1.3 刻意练习与技能提升1.4 目标设定与职业规划1.5 自我驱动与成长1.6 第一性原理的应用 2. 大数据开发领域的挑战与机遇2.1 技术革新的挑战2.2 数据治理的难题2.3 人才短缺的问题2.4 投入产出比的考量…

电子部件烧录流程(仅供参考)

&#x1f34e;个人博客&#xff1a;个人主页 &#x1f3c6;个人专栏&#xff1a;日常聊聊 ⛳️ 功不唐捐&#xff0c;玉汝于成 目录 前言 正文 部件烧录流程的详细步骤 1. 准备工作 2. 连接硬件 3. 配置烧录软件 4. 校验和设置 5. 开始烧录 6. 验证和测试 7. 断开…

Docker实现Redis主从,以及哨兵机制

Docker实现Redis主从,以及哨兵机制 目录 Docker实现Redis主从,以及哨兵机制准备Redis镜像创建Redis主节点配置文件启动Redis从节点确认主从连接哨兵主要功能配置哨兵文件创建Redis哨兵的Docker容器 要通过Docker实现Redis的主从&#xff08;master-slave&#xff09;复制&#…