USB接口驱动从原理到应用

1.USB概览

当涉及到USB通信时,可以从最物理层到最高应用层对其内容进行详细说明:

物理层(Physical Layer):

  • USB连接线:USB使用四根线,其中两根用于数据传输(D+和D-),一根用于电源(VCC),最后一根用于接地(GND)。
  • 差分信号:USB采用差分信号传输,以提高抗干扰能力和传输质量。
  • 电气特性:USB定义了数据线和电源线的电压电流规范,以及阻抗匹配和线缆长度等要求。
  • 接口类型:USB有多种连接接口类型,如USB Type-A、USB Type-B、Micro USB、USB Type-C等,用于适配不同设备和外设。

数据链路层(Data Link Layer):

  • 帧和令牌(Token):USB数据传输以帧为单位进行,每个帧由同步字段、PID(包标识符),地址、端点、CRC等组成。
  • 令牌传输:主机通过发送令牌包来控制设备的状态和通信流程,令牌类型有同步令牌、分离令牌和握手令牌。
  • 数据传输:数据阶段用于实际的数据传输,包括数据包的发送和接收。
  • 握手:数据传输完成后,设备和主机之间进行握手确认,确认接收到的数据的完整性。
  • 错误检测和重传:USB使用CRC(循环冗余校验)来检测数据传输中的位错误,并根据需要进行重传机制。

传输层(Transaction Layer):

  • 事务(Transaction):USB使用事务来管理数据传输,一个事务通常包含多个帧,以满足数据传输的需求。
  • 管道(Pipe):管道是设备和主机之间进行数据传输的通道,可以分为控制传输管道、批量传输管道和中断传输管道。

主机控制器层(Host Controller Layer):

  • 主机控制器:主机控制器是主机系统中用于管理USB通信的硬件或软件模块,负责控制和管理USB设备的连接和通信。
  • 主机控制器接口(HCI):主机控制器和主机之间使用特定的传输协议进行通信,如USB Host Controller Interface (HCI)。

应用层(Application Layer):

  • USB类别和协议:USB设备使用特定的类别和协议规范来定义其功能和应用特性,如USB存储类、音频类、打印机类等。
  • 驱动程序:为了与USB设备进行通信,主机需要相应的驱动程序来识别设备、控制和管理其功能。
  • 应用程序接口(API):操作系统和开发平台提供USB的应用程序接口,用于开发者与USB设备进行交互和控制。

2.USB应用层 

当涉及到USB的应用层时,可以进一步展开细说其内容。USB应用层定义了不同的类别和协议,用于实现特定的功能和应用。以下是一些常见的USB应用层类别和协议:

  1. USB存储类(USB Mass Storage Class):USB存储类协议用于连接和传输存储设备。它允许主机系统将USB闪存驱动器、外部硬盘、U盘等存储设备视为逻辑存储单元,并进行数据的读取和写入。

  2. USB音频类(USB Audio Class):USB音频类协议用于连接和传输音频设备。它定义了音频流的格式和通信方式,允许主机系统实现音频输入和输出功能。常见的应用包括USB话筒、耳机、音频接口等。

  3. USB打印机类(USB Printer Class):USB打印机类协议用于连接和控制打印机设备。它定义了打印机命令和数据格式,允许主机系统发送打印任务和接收打印机状态、设置打印参数等。

  4. USB图像类(USB Image Class):USB图像类协议用于连接和传输图像设备,如摄像头(v4l2的使用 详见linux中的USB摄像头驱动(应用层)(基于V4L2) 这篇文章的解释) 、扫描仪等。它定义了图像数据的格式和传输方式,允许主机系统进行图像的捕捉、传输和控制。

  5. USB人机接口设备类(USB Human Interface Device):USB HID协议用于连接和传输人机接口设备,如键盘、鼠标、游戏控制器等。它定义了输入数据的报告格式和通信方式,允许主机系统获取用户的输入数据并进行相应的操作。

  6. CDC(Communications Device Class):CDC用于支持通信类设备,例如调制解调器、串行通信设备和网络适配器等。它提供了一个虚拟串口的功能,使得操作系统可以通过标准的串口接口与设备进行通信

3.USB HID简介 

USB HID(Human Interface Device)是一种用于人机交互设备的USB协议,它定义了一组报告格式和通信规范,用于传输输入设备(如键盘、鼠标、游戏控制器等)的数据。

USB HID的工作原理如下:

  1. 设备识别:当USB HID设备插入到主机系统上时,主机会检测到设备的存在并进行识别。
  2. 报告描述:USB HID设备包含有关报告格式的描述信息,通常使用HID描述符定义报告的结构和属性。该描述符定义了报告的大小、字段和数据类型等信息。
  3. 报告传输:HID设备将输入数据以报告的形式发送给主机系统。每个报告由一个或多个数据包组成。
  4. 中断传输:HID设备通常使用中断传输方式与主机进行通信。它使用中断端点(endpoint)来定期传输报告,以确保实时交互和低延迟。

USB HID数据包的传输过程如下:

  1. 开始标记:传输开始时,HID设备发送一个特殊的开始标记以通知主机数据包的到来。
  2. 报告ID(可选):某些报告可能具有报告ID,用于标识报告的类型或用途。如果报告有报告ID,则它会在数据包中包含报告ID字段。
  3. 数据包:数据包中包含了报告的数据。报告的数据根据报告描述符中定义的格式进行编码和组织。
  4. 端点确认:在数据包传输完成后,HID设备会等待主机发送端点确认信号,以表示数据包已成功接收。
  5. 可能的话,重复步骤2和3以传输下一个报告。

USB HID支持不同的速率,常见的有:

  • 高速(High-Speed):传输速率为480 Mbps(兼容USB 2.0)。
  • 全速(Full-Speed):传输速率为12 Mbps(兼容USB 1.1)。
  • 低速(Low-Speed):传输速率为1.5 Mbps(兼容USB 1.1)。

4.USB HID 驱动 - linux

 4.1 USB-HID实现方式1

       原始hid驱动

  1. hid-core.c:这是Linux内核中核心的HID驱动代码文件,位于drivers/hid/hid-core.c。它提供了USB HID设备的通用驱动框架,并处理识别、初始化、输入报告解析和传输等核心功能。

  2. hid-input.c:位于drivers/hid/hid-input.c,它负责处理HID设备中的输入报告,将其转换为标准的Linux输入事件,如按键、鼠标移动等。

  3. hid-generic.c:位于drivers/hid/hid-generic.c,这是一个通用的HID驱动,可以用于不需要特殊处理的HID设备。它通过最小限度的解析报告描述符来驱动大多数USB HID设备。

  4. hiddev.c:位于drivers/hid/usbhid/hiddev.c,它提供了一个用户空间与HID设备之间的接口,允许用户程序通过/dev/hiddevX设备文件读取和写入HID设备的原始数据。

  5. hid.h:位于include/linux/hid.h,它定义了HID设备的结构体和相关的常量,供驱动程序使用。

 4.2 USB-HID实现方式2 

     USB gadget模拟

USB gadget是一种在嵌入式系统中模拟USB设备的功能,将嵌入式设备作为USB设备使用。通过模拟不同类型的USB设备,实现与外部主机的通信和数据交互。

当使用USB gadget模块在Linux系统中模拟USB HID(Human Interface Device)功能时,涉及以下重要的文件和步骤:

  1. usb/gadget/hid.h:这个头文件定义了用于USB HID gadget的相关数据结构和函数接口。

  2. drivers/usb/gadget/function/f_hid.c:这个文件实现了USB Function HID(HID gadget)驱动代码。它负责处理HID相关的请求和功能。

  3. drivers/usb/gadget/configfs.c:这个文件实现了使用configfs接口动态配置USB gadget的相关功能。它负责解析和处理配置对象,并将配置应用于USB gadget设备。

步骤如下:

  1. 配置内核:在编译Linux内核时,启用USB gadget和HID gadget相关模块。确保相关驱动程序(如f_hid)被编译为内核模块或静态编译进内核。

  2. 定义HID功能:在应用程序中定义HID功能的报告描述符。报告描述符描述了HID设备的功能和数据格式,如输入、输出和特性报告。

  3. 注册USB gadget驱动:在嵌入式系统启动时,通过配置文件或程序代码,注册HID gadget驱动(f_hid)并指定相关的报告描述符。

  4. 配置HID gadget:使用configfs接口,动态创建和配置HID gadget设备。设置设备的标识符、报告描述符和其他属性。

  5. 处理HID请求:HID gadget驱动(f_hid)负责处理来自主机的HID请求。这包括获取设备描述符、设置报告描述符、处理报告数据等。

  6. 数据交互:HID gadget驱动通过与gadget核心的交互,接收来自主机的报告数据并传递给应用程序或处理器;同时,也可以发送报告数据给主机。

通过以上步骤,USB gadget成功地将嵌入式系统模拟为一个USB HID设备,实现了HID功能,并能与主机进行通信和交互。主机可以使用标准的USB HID驱动程序与模拟的HID设备进行数据传输和交互。

5.USB HID 驱动 - windows

在Windows中,使用hidsdi.h头文件可以实现USB HID(Human Interface Device)驱动的开发。hidsdi.h提供了一组函数和数据结构,用于与USB HID设备进行通信和操作。

下面是使用hidsdi.h实现USB HID驱动的基本步骤:

  1. 与设备建立连接:使用SetupDiGetClassDevs函数获取与USB HID设备相关的设备信息集合。然后使用SetupDiEnumDeviceInterfaces函数遍历设备信息集合,找到所需的USB HID设备。接着,使用CreateFile函数打开与设备的连接。

  2. 获取预定义的USB HID功能:通过调用HidD_GetPreparsedData函数,获取USB HID设备的预定义数据。该数据包含了设备的功能和报告描述符。

  3. 解析报告描述符:使用HidP_GetCaps函数解析报告描述符,这样就可以了解设备的输入报告、输出报告和特征报告等信息。

  4. 读取和写入报告数据:使用HidD_GetInputReport和HidD_SetOutputReport函数,分别读取输入报告和写入输出报告。这样可以与USB HID设备进行双向数据交互。

  5. 关闭设备连接:最后,使用CloseHandle函数关闭与USB HID设备的连接。

在linux中则不需要额外编写驱动,插入设备将直接显示节点如/dev/hidrawX 

6.USB CDC 简介 

USB CDC(USB Communications Device Class)是一种USB设备类别,旨在将嵌入式系统模拟为通信设备,如串口。相比于USB HID(Human Interface Device)驱动,USB CDC驱动在通信领域有其独特的优势和缺点。

USB CDC的优势:

  1. 标准化通信协议:USB CDC定义了标准的通信协议,使得与USB CDC设备进行通信的软件和驱动程序更易于开发和兼容。各种操作系统和应用程序可以通过标准接口与USB CDC设备进行通信。

  2. 简化驱动程序开发:USB CDC设备类别提供了标准的通信接口和协议,减少了驱动程序的开发工作量。开发人员可以基于通用的USB CDC驱动程序开发自定义的应用程序和功能。

  3. 多平台兼容性:USB CDC驱动程序具有良好的跨平台兼容性。这意味着无论是在Windows、Linux还是Mac等操作系统上,USB CDC设备都可以得到良好的支持和兼容。

  4. 多种通信方式:USB CDC支持多种通信方式,包括串口通信(Virtual COM Port)、以太网通信、无线通信等。这使得USB CDC设备可以灵活适应各种通信需求。

USB CDC的缺点:

  1. 相对复杂的协议:与USB HID相比,USB CDC的协议相对复杂。这意味着在开发和实现USB CDC驱动程序时,需要更多的技术和开发经验。

  2. 通信速率限制:USB CDC的通信速率相对较低,不适用于高速数据传输场景。如果需要高速数据传输,可能需要考虑其他的通信方案。

  3. 设备驱动需求:使用USB CDC设备时,需要安装相应的设备驱动程序。在某些情况下,特别是在需要在不同的操作系统上使用设备时,驱动程序的安装和配置可能会带来一些麻烦。

综上所述,USB CDC驱动具有标准化通信协议、简化驱动程序开发和多平台兼容性等优势,但相对复杂的协议和通信速率限制是其缺点之一。根据具体的应用需求和通信需求,选择合适的USB驱动类别。

7.usb cdc 模拟串口 - linux驱动

重要说明:

在Linux中,USB gadget子系统提供了一种通用的框架和接口,用于实现各种USB设备功能,包括USB CDC和USB HID等。使用USB gadget子系统可以更方便地管理和配置USB设备,并通过统一的接口与主机进行通信。

USB HID协议相对简单,并且通常使用单一的报告描述符来描述设备功能。因此,实现USB HID设备时,并不需要像USB CDC那样复杂的功能配置和管理,所以可以在Linux系统中单独实现USB HID驱动,而不依赖于USB gadget子系统。

USB HID设备可以直接使用HID类驱动程序进行描述和操作,而不需要像USB CDC那样需要在USB gadget子系统中进行配置。因此,在Linux中,可以通过使用HID类驱动程序和相关的API(如hidsdi.h)来实现USB HID设备的功能,而不需要依赖于USB gadget子系统。

实现步骤:

在Linux内核中,USB CDC模拟串口功能的实现依赖于以下关键文件:

  1. usb/gadget/cdc.h:这个头文件定义了用于USB CDC模拟串口的相关数据结构和函数接口。

  2. drivers/usb/gadget/function/f_serial.c:这个文件实现了USB Function Serial(CDC模拟串口)驱动代码。它是用于USB CDC模拟串口功能的关键文件。

  3. drivers/usb/gadget/configfs.c:这个文件实现了使用configfs接口动态配置USB gadget相关功能。它负责解析和处理USB CDC模拟串口设备的配置。

下面是USB CDC模拟串口在Linux内核中的基本实现步骤:

  1. 配置内核:在编译Linux内核时,确保启用了USB gadget和CDC模块。确保相关的驱动程序(如f_serial)被编译为内核模块或者静态编译进内核。

  2. 注册USB Function Serial驱动:在嵌入式系统启动时,通过配置文件或者程序代码,注册USB Function Serial驱动(f_serial)并指定相关设置和属性。

  3. 创建USB CDC模拟串口设备:使用configfs接口,动态创建和配置USB CDC模拟串口设备。设置设备的标识符、端口参数和其他相关属性。

  4. 处理串口读写操作:USB Function Serial驱动负责处理来自主机的串口读写操作。它提供了相应的接口,以便开发人员可以在应用程序中进行串口数据读取和写入。

  5. 设备连接和应用程序交互:在Linux系统中,USB CDC模拟串口设备将在/dev目录下被创建为一个字符设备。应用程序可以通过打开该设备文件并进行读写操作,与模拟的串口进行数据交换和通信。

8. USB CDC串口 驱动 - windows

在Windows系统中实现USB CDC模拟串口, 可以使用Windows Driver Frameworks (WDF) 和Serial Communications (SerCx) 驱动框架及相关的API。

以下是实现USB CDC模拟串口的一般步骤:

  1. 定义USB CDC设备描述符:在设备驱动程序中定义USB CDC设备的描述符,包括Vendor ID (VID),Product ID (PID),设备类别,接口描述符等信息。

  2. 创建驱动程序:使用Windows驱动开发工具 (如Visual Studio) 创建WDF驱动程序。

  3. 配置设备:在驱动程序中使用WDF API (如WdfUsbTargetDeviceSelectConfig) 配置USB设备。

  4. 注册驱动程序回调函数:注册WDF回调函数,以响应设备的插拔事件和串口数据传输事件。

  5. 打开设备:在驱动程序的插拔事件回调函数中,使用WDF API (如WdfUsbTargetDeviceCreateWithParameters) 打开设备。

  6. 配置串口:在设备打开后,使用SerCx API (如SerCx2InitializePort) 配置串口相关参数,如波特率、数据位、停止位等。

  7. 接收和发送数据:使用SerCx API (如SerCx2ReadDataAvailable、SerCx2WriteData) 来接收和发送串口数据。

  8. 关闭设备:在设备拔出或需要关闭设备时,使用WDF API (如WdfObjectDelete) 关闭设备。

在linux中则不需要额外编写驱动,插入设备将直接显示节点如/dev/ttyusb*  

9.USB存储设备驱动 - linux(内置) 

在Linux内核已经内置了对USB存储设备(如U盘)的支持,并提供了相应的USB存储驱动。

以下是Linux中实现USB存储设备驱动的一般步骤:

  1. 插入USB存储设备:将USB存储设备(如U盘)插入Linux系统的USB接口。

  2. 内核识别设备:Linux内核会自动识别插入的USB存储设备,并为其分配一个设备节点(如/dev/sdX)。

  3. 挂载文件系统:使用挂载命令(如mount)将USB存储设备上的文件系统挂载到Linux系统的目录中。

  4. 访问文件:一旦文件系统被挂载,您可以通过常用的文件操作命令(如cpls等)或使用文件浏览器在USB存储设备上进行读写操作。

  5. 卸载设备:在结束使用USB存储设备后,使用卸载命令(如umount)卸载文件系统,并安全地将USB存储设备从系统中拔出。

大多数常见的USB存储设备(如U盘、移动硬盘)遵循通用的USB存储协议(USB Mass Storage Class),并且Linux内核已经内置了对这些设备的支持,因此不需要额外的驱动程序。

  • 7
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值