Linux驱动(3)- LInux USB驱动层次

news2024/11/18 15:33:18

在Linux系统中,提供了主机侧和设备侧USB驱动框架。

从主机侧,需要编写USB驱动包括主机控制器驱动,设备驱动两类,USB

主机控制驱动程序控制插入其中的USB设备。

USB设备驱动程序控制该设备如何作为从设备与主机进行通信。

1.主机侧与设备侧USB驱动

USB采用树状拓扑结构,主机侧和设备侧的USB控制器分别为主机控制器和USB

设备控制器,每条总线上只有一个主机控制器,负责协调主机与设备间的通讯,而设备不能主动向主机发送任何数据。

从主机侧看,要实现的USB驱动包括两类:USB主机控制器驱动和USB设备驱动。

USB设备驱动MASS storage/CDC/HID控制USB设备如何与主机通信
USB核心

负责USB驱动管理和协议处理的主要工作。

1.通过定义一些数据结构,宏和函数功能,向上为设备驱动提供编程接口,向下为USB主机控制器驱动提供编程接口。

2.维护整个系统的USB设备信息。

3.完成设备热插拔控制,总线数据传输控制

USB主机控制器驱动OHCI/EHCI/UHCI控制插入其中的USB设备
主机控制器只有一个主机控制器,负责协调主机与设备间的通讯

从设备上看,

Gardget Function 驱动(Mass storage/serial...)具体控制USB功能的实现,使设备表现出“网络连接”,“打印机”或者“USB Mass Storage”
Gadet Function APIUDC驱动函数的简单包装
UDC驱动(omap/pxa2xx)直接访问硬件,控设备和主机间的地层通信
USB设备控制器
2.设备,配置,接口,端点

 在USB设备逻辑中,包含设备,配置,接口和端点4个层次。

 

接口       

1.代表一个节本功能,是USB设备驱动程序控制对象,一个复杂的USB设备可以有多个接口。

2.每个配置有多个接口,而设备接口是端点的汇集。

一个配置中所有接口都可以同时有效,并且被不同的驱动程序连接。

端点

是USB通信的最基本形式,每个USB设备接口在主机看来就是一个端点的集合。

主机只能通过端点与设备进行通信,以使用设备功能。

每个端点都有一定的属性,包括传述方向,总线访问频率,贷款,端点好,数据包的最大容量等。

一个端点只能一个方向上成在数据,从主机到设备(输入端点),或者从设备到主机(输出端点),因此端点可看作一个单向的管道。

 设备通常有一个或者多个配置

配置通常有一个或者多个接口

接口通常有一个或者多个配置

接口有0个或者多个端点。


这种层次花配置信息在设备中通过一组标准的描述符来描述。

设备描述符

1.关于设备的通用信息,例如供应商 ID,产品ID,修订ID,支持设备类,自类和适合协议以及默认端点的最大包大小。

2.在LInux内核中,USB设备用usb_device结构体来描述,USB

设备描述符定义为usb_device_descriptor结构体。

配置描述符

此配置中的接口,支持的刮起和恢复的能力以及功率的要求。USB配置在内核中使用usb_host_config接口体描述,USB配置描述定义为结构体usb_config_descriptor

接口描述符

接口类,子类和使用的协议,接口备用配置的数目和端点数目。

USB接口在内核中使用usb_interface结构体描述。

端点描述符端点地址,方向和类型,支持的最大报打包大小,如果是中断类型的端点侧包括轮询频率。使用usb_host)endpoint接口体来描述。

 

设备描述符定义为usb_device_descriptor结构体

/* USB_DT_DEVICE: Device descriptor */
struct usb_device_descriptor { //usb设备描述符
    __u8  bLength;//长度
    __u8  bDescriptorType;//描述符类型

    __le16 bcdUSB;//usb SPEC的版本
    __u8  bDeviceClass;//设别类型
    __u8  bDeviceSubClass;//设备子类型
    __u8  bDeviceProtocol;//协议
    __u8  bMaxPacketSize0;//最大传输大小
    __le16 idVendor;//厂商ID
    __le16 idProduct;//设备ID
    __le16 bcdDevice;//设备版本号
    __u8  iManufacturer;//描述厂商字符串的索引
    __u8  iProduct;//描述产品字符串的索引
    __u8  iSerialNumber;//序列号
    __u8  bNumConfigurations;//设备当前速度模式下支持的配置数量。有的设备可以在多个速度模式下操作,这里包括的只是当前速度模式下的配置数目,不是总的配置数目
} __attribute__ ((packed));

 配置描述符:用结构体usb_config_descriptor描述。

struct usb_config_descriptor { //配置描述符
    __u8  bLength;//描述符长度
    __u8  bDescriptorType;//配置描述符的类型

    __le16 wTotalLength;//使用GET_DESCRIPTOR请求从设备里获得配置描述符信息时,返回的数据长度
    __u8  bNumInterfaces;//这个配置包含的接口数量
    __u8  bConfigurationValue;//对于拥有多个配置的设备来说,可以拿这个值为参数,使用SET_CONFIGURATION请求来改变正在被使用的 USB配置,
	                          bConfigurationValue就指明了将要激活哪个配置。咱们的设备虽然可以有多个配置,但同一时间却也只能有一个配置被激活。捎带着提一下,
	                          SET_CONFIGURATION请求也是标准的设备请求之一,专门用来设置设备的配置。
    __u8  iConfiguration;//描述配置信息的字符串描述符的索引值
    __u8  bmAttributes;//这个字段表征了配置的一些特点,比如bit 6为1表示self-powered,bit 5为1表示这个配置支持远程唤醒。
	                    另外,它的bit 7必须为1
    __u8  bMaxPower;//设备正常运转时,从总线那里分得的最大电流值,以2mA为单位。
	                 设备可以使用这个字段向hub表明自己需要的的电流,但如果设备需求过于旺盛,
	                 请求的超出了hub所能给予的,hub就会直接拒绝还记得struct usb_device结构里的bus_mA吗?它就表示hub所能够给予的。计算机的usb端口可以提供最多500mA的电流
} __attribute__ ((packed));

接口描述符:用usb_interface_descriptor结构体描述

/* USB_DT_INTERFACE: Interface descriptor */
struct usb_interface_descriptor {
    __u8  bLength;//接口描述符长度
    __u8  bDescriptorType;//接口描述符类型

    __u8  bInterfaceNumber;//接口号。每个配置可以包含多个接口,这个值就是它们的索引值。
    __u8  bAlternateSetting;//接口使用的是哪个可选设置。协议里规定,接口默认使用的设置总为0号设置。
    __u8  bNumEndpoints;//接口拥有的端点数量。这里并不包括端点0,因为端点0是控制传输,是所有的设备都必须提供的,
	                    所以这里就没必要多此一举的包括它了。对于hub,因为它的传输是中断传输,所以此值为1(不包括端点0)
    __u8  bInterfaceClass;//接口类型
    __u8  bInterfaceSubClass;//接口子类型
    __u8  bInterfaceProtocol;//接口所遵循的协议
    __u8  iInterface;//描述该接口的字符串索引值
} __attribute__ ((packed));

端点描述符:定义为usb_endpoint_descriptor结构体 

/* USB_DT_ENDPOINT: Endpoint descriptor */
struct usb_endpoint_descriptor {//USB 端点描述符(每个USB设备最多有16个端点)
    __u8  bLength;//描述符的字节长度
    __u8  bDescriptorType;//描述符类型,对于端点就是USB_DT_ENDPOIN

    __u8  bEndpointAddress;//bit0~3表示端点地址,bit8 表示方向,输入还是输出
    __u8  bmAttributes;//属性(bit0、bit1构成传输类型,00--控制,01--等时,10--批量,11--中断)
    __le16 wMaxPacketSize;//端点一次可以处理的最大字节数
    __u8  bInterval;//希望主机轮询自己的时间间隔

    /* NOTE:  these two are _only_ in audio endpoints. */
    /* use USB_DT_ENDPOINT*_SIZE in bLength, not sizeof. */
    __u8  bRefresh;
    __u8  bSynchAddress;//对于同步传送的端点,此域必须为1
} __attribute__ ((packed));

可以通过lsusb -v查看usb节电信息

Bus 004 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Couldn't open device, some information will be missing
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               3.10
  bDeviceClass            9 Hub
  bDeviceSubClass         0 
  bDeviceProtocol         3 
  bMaxPacketSize0         9
  idVendor           0x1d6b Linux Foundation
  idProduct          0x0003 3.0 root hub
  bcdDevice            6.05
  iManufacturer           3 Linux 6.5.0-35-generic xhci-hcd
  iProduct                2 xHCI Host Controller
  iSerial                 1 0000:03:00.4
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength       0x001f
    bNumInterfaces          1
    bConfigurationValue     1
    iConfiguration          0 
    bmAttributes         0xe0
      Self Powered
      Remote Wakeup
    MaxPower                0mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass         9 Hub
      bInterfaceSubClass      0 
      bInterfaceProtocol      0 Full speed (or root) hub
      iInterface              0 
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0004  1x 4 bytes
        bInterval              12
        bMaxBurst               0

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

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

相关文章

文件夹打开出错?这里有你需要的数据恢复与预防指南

在日常使用电脑时,我们有时会遇到文件夹打开出错的情况。当你尝试访问某个文件夹时,系统可能会弹出一个错误提示,告诉你无法打开该文件夹。这种情况不仅会影响我们的工作效率,还可能导致重要数据的丢失。接下来,我们将…

Flutter-自定义折叠流布局实现

需求 在 Flutter 开发中,常常需要实现自定义布局以满足不同的需求。本文将介绍如何通过自定义组件实现一个折叠流布局,该组件能够显示一系列标签,并且在内容超出一定行数时,可以展开和收起。 效果 该折叠流布局可以显示一组标签…

ROCm上运行Transformer

10.7. Transformer — 动手学深度学习 2.0.0 documentation (d2l.ai) 代码 import math import pandas as pd import torch from torch import nn from d2l import torch as d2l#save class PositionWiseFFN(nn.Module):"""基于位置的前馈网络""&qu…

【uni-best+UView】使用mitt实现自定义错误对话框

痛点 目前在设计一个uni-best的前端全局的异常提示信息,如果采用Toast方式,对微信支持的不友好。微信的7中文长度连个NPE信息都无法完整显示,更不用提Stacktrace的复杂报错了。如果使用对话框,必须在页面先预先定义,对…

C/C++ 进阶(2)多态

个人主页:仍有未知等待探索-CSDN博客 专题分栏:C 目录 一、多态的概念 二、多态的定义及其实现 1、多态的构成条件 2、虚函数 3、虚函数重写 a.常规 b.两个例外 1、协变(基类与派生类虚函数返回值类型不同) 2、析构函数重…

10G UDP协议栈 (9)UDP模块

目录 一、UDP协议简单介绍 二、UDP功能实现 三、仿真 一、UDP协议简单介绍 UDP协议和TCP协议同位于传输层,介于网络层(IP)和应用层之间:UDP数据部分为应用层报文,而UDP报文在IP中承载。 UDP 报文格式相对于简单&am…

单工无线发射接收系统

1 绪论 随着无线电技术的发展,通讯方式也从传统的有线通讯逐渐转向无线通讯。由于传统的有线传输系统有配线的问题,较不便利,而无线通讯具有成本廉价、建设工程周期短、适应性好、扩展性好、设备维护容易实现等特点,故未来通讯方式将向无线传输系统方向发展。同时,实现系…

leedcode【203】. 移除链表元素——Java解法

Problem: 203. 移除链表元素 题目思路解题方法复杂度Code效果 题目 给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val val 的节点,并返回 新的头节点 。 示例 1: 输入:head [1,2,6,3,4,5,6], val…

【图解IO与Netty系列】IO多路复用

IO多路复用 为什么要使用IO多路复用Linux的IO多路复用接口selectpollepoll 为什么要使用IO多路复用 我们常用的IO模型是BIO,我们Java里的IO流大多数都是BIO,也就是同步阻塞式IO,这种IO操作的好处是简单方便,但是缺点也很明显——…

【技术实操】银河高级服务器操作系统实例分享,TCP长连接与短连接详细说明

1.服务器环境以及配置 物理机/虚拟机/云/容器 物理机 处理器: HUAWEI Kunpeng 920 具体操作系统版本 Kylin-Server-10-SP1-Release-Build20-20210518- aarch64 内核版本 kernel-4.19.90-23.8.v2101.ky10.aarch64 2.问题现象描述 对TCP长连接有疑问 1、如何…

Yolov8训练自己的数据集(脱离ultralytics库)

最近在整理关于yolov8的相关内容,有个很大的问题,抛开yolov8性能不谈,yolov8代码的使用灵活性不如yolov5,尤其是对于一些新手或者对yolo框架不是很熟悉的人(这也是因人而异,有些人可能会喜欢v8代码的使用方式)。比如在…

牛客网刷题 | BC94 反向输出一个四位数

目前主要分为三个专栏,后续还会添加: 专栏如下: C语言刷题解析 C语言系列文章 我的成长经历 感谢阅读! 初来乍到,如有错误请指出,感谢! 描述 将一个四位数&…

1.int 与 Integer 的简单区别

蓝桥杯刷题从此开始: 第一题就是两个数的和,个人看来主要考察 int与integer 的区别; 这是我提交的答案,竟然会报错: import java.util.*; //输入A、B,输出AB。 class add {public static void main(String …

MT7628原厂Uboot修改交互串口

工作中,遇到用户用Skylab的SKW92A模组,在参考设计时,将UART接口预留错的情况,对于这种情况,需要将原厂SDK默认的交互串口UART0,改为UART1。在开发过程中,经常需要在Uboot阶段升级固件&#xff0…

5.25机器人基础-空间描述和变换1

参考资料:《机器人学导论》John.J.Craig 彻底搞懂“旋转矩阵/欧拉角/四元数”,让你体会三维旋转之美_欧拉角判断动作-CSDN博客 机器人操作的定义是指通过某种机构使零件和工具在空间运动。因此,对于坐标系的定义显得尤为重要,相…

【docker】Docker的基本指令和HTML/PYTHON/C++的简单创建示例

目录 🌊1. 什么是 Docker? 🌊2. Docker 安装 🌊3. Docker基本指令 🌊4. Docker 创建示例【联网情况】 🌍4.1 示例:HTML 🌍4.2 示例:Python 脚本 🌍4.3…

log4j2远程代码执行

漏洞复现 漏洞复现2 这个框架不是web框架了,不是服务器web网站框架了,是java日志框架,就是记录日志信息,每一个程序都有一个日志文件,这个就是java里面记录日志的一个框架,它存在的点也是日志框架那几个代…

Python语法(全)

前言: 下面是Python基本的语法,大家耐心观看! 1.基础语法 1.1字面量 字面量:在代码中,被写下来的的固定的值,称之为字面 1.2字符串 字符串(string),又称文本&#xff…

防火墙——域网络、专用网络、公用网络

在防火墙设置中,域网络、专用网络和公用网络是指计算机连接到网络时所处的不同环境。每种环境都有不同的安全级别和配置。 1、域网络(宽松) 域网络是指计算机加入了一个Windows域(Domain)环境,这通常在企业…

v-rep---script-function

作用,实现,参数讲解。 script-function标签 作用 问题:如何在插件的接口中调用lua脚本中定义的函数? 用于声明一个函数,这个函数的作用是通过v-rep提供的接口sim::callScriptFunctionEx()调用脚本的函数&#xff0…