程序项目代做,有需求私信(小程序、网站、爬虫、电路板设计、驱动、应用程序开发、毕设疑难问题处理等)

linux驱动移植-USB驱动基础

 一、USB总线介绍

1.1 简介

我们之前接触过的通信协议有串口、I2C、SPI以及CAN总线,这里我们又去学习USB总线,那USB和之前我们介绍过那些总线有什么区别呢。

通用串行总线(英语:Universal Serial Bus,缩写:USB)是连接计算机系统与外部设备的一种串口总线标准,也是一种输入输出接口的技术规范,被广泛地应用于个人电脑和移动设备等信息通讯产品,并扩展至摄影器材、数字电视(机顶盒)、游戏机等其它相关领域。

在USB总线出现之前,计算机与键盘、鼠标、扫描仪、打印机等的设备连接都使用专用的接口连接,不同的设备的接口不能互用,扩展性很差,每次插拔设备都要关闭计算机,不支持热插拔,且通信速率很低。

为了解决上述问题,USB总线诞生了。USB总线就好像一条管道,管道里流过的东西只要符合USB协议,至于具体流的是什么东西,USB总线并不关心。对应具体的设备上,只要是支持USB协议的设备,都可以连接计算机,如USB键盘、USB鼠标、USB摄像头、USB音箱等。USB的出现简化了计算机与外围设备的连接,增强了扩展性,支持热插拔,且通信速度很快。

1.2 USB协议版本

从USB协议诞生至今,出现了多个USB协议版本,如USB1.0、USB1.1、USB2.0、USB3.0、USB3.1、USB3.2。最新的是USB4.0协议,可直连CPU的PCIe总线,最大速度可达40Gbps,使用Type-C接口,兼容DP视频协议、PD快充协议等,最高支持100W供电。

USB协议版本速率称号最大速率电源类型推出时间
USB1.0 低速(Low-Speed) 1.5Mbps 5V/500mA 半双工 1996年1月
USB1.1 全速(Full-Speed) 12Mbps 5V/500mA 半双工 1998年9月
USB2.0 高速(High-Speed) 480Mbps 5V/500mA 半双工 2000年4月
USB3.0(USB3.2 Gen1) 超高速(SuperSpeed USB) 5Gbps 5V/900mA 全双工 2008年月11月
USB3.1(USB3.2 Gen2) SuperSpeed USB 10Gbps 10Gbps 20V/5A 全双工 2013年月7月
USB3.2(USB3.2 Gen2×2) SuperSpeed USB 20Gps 20Gbps 20V/5A dual-lane 2017年月9月
USB4.0(Gen3×2) ---- 40Gbps 100瓦 single-lane或dual-lane,兼容Thunderbolt3 2019年月8月

注:USB3.2推出时,USB-IF公布了新的命名规范,将USB3.0改名为USB3.2 Gen1,USB3.1改名为USB3.2 Gen2,而将能够使用两个USB Type-C Rx/Tx针脚的USB3.2改名为USB3.2 Gen2×2。

下图是各个版本USB协议使用的标志及接口,USB3.2以后,只使用Type-C接口,包括图中未画出的USB4.0和Thunderbolt3。

伴随着USB的版本迭代,USB又产生了多种连接器类型规范,比如Type A、Type B、Type-C。

下图是USB3.2协议使用的标志,此标志是USB-IF网站上最新的。

下图是USB4.0协议使用的标志,USB4.0使用Gen3 lane,single-lane可达到20Gps,dual-lane为40Gps。USB4™ 20Gbps使用single-lane,USB4™ 40Gbps使用dual-lane。

 

二、USB总线特点

2.1 主从模式

USB是主从模式的总线,主机称为Host,丛机称为Device(设备)。从机与从机之间、主机与主机之间(不包括USB4.0),不能互联。每次通信都是由主机发起,从机不能主动发起通信,只能被动的应答主机的请求。

USB3.0及以后的USB协议,主机也可以和集线器(Hub)通信。为了增加灵活性,又出现了USB OTG(On The Go),USB OTG支持主从切换,同一个设备,在不同场合下,可以在主机和从机之间切换。

USB OTG线中增加了一根USB ID线,当USB ID线上拉时,处于从机模式,当USB ID线接地时,处于主机模式。

2.2 总线结构

在有些场景下,我们期望将一个USB接口扩展为多个USB接口,这时我们就会使用到一个装置,也就是USB Hub,如下图所示:

因此,USB总线可能呈现出树状的拓扑接口吗,USB标准上说USB总线拓扑是一种分层星型结构,如下图所示:

 

从树结构我们可以看到:

  • 树的根节点是USB Host控制器(上图没有画出来),连接在USB Host控制器上的是USB根集线器(Root Hub);
  • USB集线器(Hub)可以将一个USB接口扩展成多个USB接口,扩展出的USB接口又可以通过USB集线器(Hub)扩展,每个USB接口都可以接USB设备;
  • 集线器只能扩展出更多的USB接口,而不能扩展出更多的带宽,所有USB设备共享USB Host控制器的带宽,当有多个USB设备需要较大带宽时,可以考虑将他们接到不同USB Host控制器上的根集线器上,以避免带宽不足;
  • 集线器级联最多5层,因此最大为7层星型结构;这个最大7层星形结构,代表的是一条USB总线,一个USB分层星型结构有且仅有一个USB主机控制器,但并不是说一台计算机就只有一个USB总线;

比如我的计算机内部就是1个USB主控制器+Root Hub,从Windows设备管理器可以看到,下图是其中一条USB总线:

 

2.3 电气特性

下图是USB3.2线缆的示意图,同时兼容USB2.0:

USB使用差分信号传输数据,图中的D+和D-是一对差分线,SSTX+和SSTX-是一对差分线,SSRX+和SSRX-是一对差分线:

  • USB2.0只有一对差分线,即下图中的D+、D-,因此USB2.0是半双工的,不能同时收发数据;
  • USB3.2拥有两对差分线,即SSTX+和SSTX-及SSRX+和SSRX-,因此USB3.2是全双工的,可同时收发数据;

USB3.2和USB2.0使用不同的差分线传输数据,两者互不干扰,可同时工作。USB3.2线缆中保留了USB2.0的数据传输通道,实现了对USB2.0的兼容。USB主机可通过VBUS线向设备供电,最大可输出20V/5A,GND是地线。

2.4 热插拔

当一个USB设备插入PC机,PC机怎么知道有设备插入?

如下图所示,USB2.0接口只有4条线:VBUS(5V),GND,D-,D+。

           

                       USB低速设备硬件接线图        


                     USB全速(高速)设备硬件接线图            

注意:上图中VCC同VBUS

PC机的USB插孔的D-和D+数据线均连接15K欧姆的下拉电阻。而USB设备端的D-或D+数据线连接1.5K欧姆的上拉电阻。当设备插入PC机的时候,会将PC机的D-或D+端的电压拉高,当PC机在D-或D+端检测到高电平时,就知道有设备插入了。

如果是PC机D-端被拉高,接入的则是USB低速设备;如果是PC机D+端被拉高,接入的则是USB全速或高速设备,具体是全速设备还是高速设备,会由PC机和USB设备发包握手确定。

三、USB传输基础

3.1 传输类型

USB架构包含四种基本类型的数据传输:

  • 控制传输:控制传输用于配置设备、获取设备信息、发送命令到设备、获取设备的状态。每个USB设备都有端点0的控制端点,当USB设备插入到USB主机拓扑网络中时,USB主机就通过端点0与USB设备通信,对USB设备进行配置,便于后续的数据传输。USB协议保证控制传输有足够的带宽。控制传输可靠,时间有保证,但传输的数据量不大。如USB设备的枚举过程就采用的是控制传输;
  • 中断传输:当USB主机请求USB设备传输数据时,中断传输以一个固定的速率传送少量的数据。中断端点的数据传输方式为中断传输,数据传输可靠,实时性高,这里的中断并不是USB设备产生中断,而是USB主机每隔一个固定的时间主动查询USB设备是否有数据要传输,以轮询的方式提高实时性。如USB鼠标采用的是中断传输;
  • 批量传输:批量传输用于传输大量数据。USB协议不保证这些数据传输可以在特定的时间内完成,但保证数据的准确性。如果总线上的带宽不足以发送整个批量包,则将数据拆分为多个包传输。批量传输数据可靠,但实时性较低。如USB硬盘、打印机等设备就采用的是批量传输方式;
  • 等时传输:等时传输也可以传输大量数据,但数据的可靠性无法保证。采用等时传输的USB设备更加注重保持一个恒定的数据传输速度,对数据的可靠性要求不高。如USB摄像头就使用的是等时传输方式;

下表是这四类传输在不同速度模式下支持的最大包长度:

速度模式 低速 全速 高速
控制传输 8 8/16/32/64 64
同步传输 不支持 1023 1024
中断传输 0~8 0~64 0~1024
批量传输 不支持 8/16/32/64 512

3.2 传输要素

USB2.0主机控制器通过把时间在低速、全速模式下分成1毫秒宽的帧(frame),在高速模式下分成125微妙宽的微帧(microfranme),以此来管理传输。主机控制器将每个帧或微帧的一部分分配给各个传输。每个帧(或微帧)以带有时序参考的帧(Start-of-Frame,SOF)开始。超高速总线不使用SOF,但主机控制器仍可以在125微妙的总线时间内安排超高速传输。

USB传输可以安排在1个或多个帧或微帧中,每个传输包含多个事务,每个事务又进一步含有多个信息包(packets)。信息包必须在一个帧或微帧中传输完毕,不能跨帧或微帧。信息包分为4类,令牌类信息包确认事务类型,数据类信息包携带数据和状态代码,握手类信息包携带状态代码,最后一种是特殊类信息包。
USB传输由一个或多个事务(transaction)组成,这些事务可将数据载入端点或从端点取出。USB2.0事务开始于主机在总线上发送的令牌信息包(token packet)。令牌信息包含有目标端点号和方向。IN令牌信息包表示向端点请求数据信息包。OUT令牌信息包则是主机派发数据信息包的先行信息。除了数据,每个数据包还含有错误检查位和一个带有数据顺序值的信息包ID(PID)。许多事务还拥有握手信息包(handshake packet),数据的接收端用它来报告事务成功或失败。对于超高速传输事务,信息包类型和协议有所不同,但却含有相同的地址、错误检查和与数据相配合的数据顺序值。

信息包类型PID名字取值(二进制)传输类型来源说明
令牌 OUT 0001 全部 主机 IN事务中需要的设备和端点地址
令牌 IN 1001 全部 主机 IN事务中需要的设备和端点地址
令牌 SOF 0101 帧开始 主机 SOF标识符和帧号
令牌 SETUP 1101 控制 主机 用于Setup事务的设备和端点地址
数据 DATA0 0011 全部 主机、设备 数据交替或数据PID序列
数据 DATA1 1011 全部 主机、设备 数据交替或数据PID序列
数据 DATA2 0111 等时 主机、设备 数据PID序列
数据 MDATA 1111 等时、分割事务 主机、设备 数据PID序列
握手 ACK 0010 控制、批量、中断 主机、设备 接收端接收到正确的数据信息包
握手 NAK 1010 控制、批量、中断 设备 接收端不能接收数据,或者发送端无法发送数据或无数据要发送
握手 STALL 1110 控制、批量、中断 设备 控制请求不被支持或端点被停止
握手 NYET 0110 控制写、批量、OUT、分割事务 设备 正确的接收了数据信息包,但还没准备好接收下一个,或集线器还没有将数据信息包分割完成
特殊 PRE 1100 控制、中断 主机 主机发出的先行信号
特殊 ERR 1100 全部 集线器 由集线器返回的错误
特殊 SPLIT 1000 全部 主机 分割事务
特殊 PING 0100 控制写、批量、OUT 主机 PING测试
特殊 EXT 0000 主机 扩展,未使用

更多细节参考:USB协议详解

四、USB驱动分析

4.1 驱动分类

USB的驱动可以分为3类:

  • USB主机控制器驱动,主要包括:
    • usb主机控制器驱动的创建;
    • 根hub设备的创建和注册;
  • 主机端USB设备驱动(更准确的说是usb接口驱动);
  • 设备端USB Gadget驱动(专业术语,用于描述连接到计算机的USB的设备的驱动);

通常,对于USB这种标准化的设备,内核已经将USB主机控制器驱动编写好了,设备端Gadget驱动通常只运行固件程序而不是基于Linux, 所以驱动工程师的主要工作就是编写主机端USB设备驱动。

4.2 USB驱动框架

USB驱动框架结构图如下:

USB总线驱动程序包括USB Core和USB HCD两部分,其作用如下:

  • 识别USB设备:
    • 分配地址;
    • 并告诉USB设备;
    • 发出命令获取描述符;
  • 查找并安装对应的USB设备驱动程序(更准确的说是usb接口驱动);;
  • 提供USB读写函数;

USB总线上的所有通信都是由主机发起的,所以本质上,USB都是采用轮询的方式进行的:

  • 主机会使用轮询的方式不断检测总线上是否有设备接入,如果有设备接入相应的D+、D-就会有电平变化;
  • 然后USB总线就会按照USB规定的协议与设备进行通信,设备将存储在自身的设备信息依次交给主机;
  • 主机将这些信息组织起来,上报到内核,内核中的USB子系统再去匹配相应的设备驱动;

上面所说的主机具体指的是USB主机控制器。

4.3  USB Core

USB Core这个模块是纯软件部分,并不代表一个设备,是独立于硬件的协议栈,它是所有USB设备赖以生存的模块,即USB子系统的核心。代码位于kernel/driver/usb/core目录下。

USB核心层向上为USB设备驱动提供编程接口,向下为USB主机控制器驱动提供编程接口,维护整个系统的USB设备信息,完成设备热插拔控制、总线数据传输控制等。

USB核心层将用户的请求映射到相关的USB HCD,用户不能直接访问USB HCD,USB核心层就是USB HCD和USB设备的桥梁。

4.4 USB HCD(Host Controller Driver)

硬件主机控制器HOST Contrller之上运行的是USB HCD,是对USB主机控制器的一个抽象,实现USB核心层与主机控制器之间的对话接口。代码位于drivers/usb/host目录下,比如ohci-s3c2410.c文件。

USB主机控制器包含多种不同的类型,即OHCI和UHCI,EHCI,和xHCI,不同类型的USB主机控制器的区别和联系如下:

4.5 USB Devices Driver

USB设备驱动框架如下图所示:

 

为了更好地描述USB设备的特征,USB提出了设备架构的概念。从这个角度来看,可以认为USB设备是由一些配置(configuration)、接口(interface)和端点(endpoint)组成,即一个USB设备可以含有一个或多个配置,在每个配置中可含有一个或多个接口,在每个接口中可含有若干个端点。其中:

  • 配置和接口是对USB设备功能的抽象;
  • 实际的数据传输由端点来完成;
  • 每个USB设备,都可能有多个接口,每个接口都实现了一个功能。在linux,每个USB设备都是一个device(具体是struct usb_device)、每一个接口也是一个device(具体是struct usb_interface,代表一个逻辑上的设备)。不管是USB设备还是USB接口,都会被注册到同一个总线上,也就是usb_bus_type,其之间的区别会在match函数中区分,之后再去绑定不同的driver。
  • 所有的USB设备都会和usb_generic_driver设备驱动匹配,当一个USB设备被插入的时候,USB设备驱动,也就是usb_generic_driver会跟USB设备交互,得到其所有的各种描述符,并为每个接口都定义成为一个device,之后再加载到usb_bus上,让其去匹配其对应的接口驱动程序。

任何USB设备都包含设备描述符,主要用与说明设备树形(设备描述符,配置描述符,接口描述符,端点描述符之间的关系),通常都被固话在设备内部,当主机检测到有设备插入的时候,就会通过控制传输模式将设备描述信息读出来,这个步骤一般是在设备接入主机时设备进行枚举时完成的。

4.6 USB设备地址和端点

每个USB设备都有唯一的设备地址,比如root hub的设备地址为1,设备地址是usb设备连接上主机时由usb主机控制器分配的,usb主机控制器主要依靠这个设备地址对usb设备进行访问。

但是在usb设备内部地址会被分的更细,设备会分出一些端点来,每个端点在设备都会有一个端点号,这个端点号是设备生产时给设定的。如端点0、端点1等,一个usb设备最多可以包含16个端点,每个端点的地址为0~15。

其中每个端点地址对应一个方向。例如端点3-IN,端点3-OUT,这另个含义不同。但是需要注意的是有一个特殊端点-端点0,每个usb必须要有一个端点0,其作用为对设备枚举和对设备进行一些基本的控制功能,端点0也被称作控制端点,并且它与其他的端点还有一个不同之处在于端点0的数据传输方向是双向的,即端点0既可以给主机发送数据,也可以接收主机发送过来的数据,而其他端点都是单向的。

虽然有16个端点,单通常我们只用到3个如下:

  • EP0:传输配置和控制信息;
  • EP1:数据输入IN_EP;
  • EP2:数据输出OUT_EP;

除了端点0,其余的端点在设备配置之前不能与主机通信,只有向主机报告这些端点的特性并确认后才能被激活。

 

五、USB设备驱动架构中的描述符

USB设备使用各种描述符来说明其设备架构,包括设备描述符、配置描述符、接口描述符、端点描述符。

5.1 端点

USB通信最基本的形式是通过端点的东西。USB端点只能往一个方向传送数据,从主机到设备(称为输出端点out)或者从设备到主机(称为输入端点in),端点可以看作是单向的管道。

USB端点有四种不同的类型,分别具有不同的传送数据的方式:对应着我们之前介绍的四种基本类型的数据传输:控制、中断、批量、等时。

内核中使用struct usb_host_endpoint结构体来描述USB端点,其定义在include/linux/usb.h:

复制代码
/**
 * struct usb_host_endpoint - host-side endpoint descriptor and queue
 * @desc: descriptor for this endpoint, wMaxPacketSize in native byteorder
 * @ss_ep_comp: SuperSpeed companion descriptor for this endpoint
 * @ssp_isoc_ep_comp: SuperSpeedPlus isoc companion descriptor for this endpoint
 * @urb_list: urbs queued to this endpoint; maintained by usbcore
 * @hcpriv: for use by HCD; typically holds hardware dma queue head (QH)
 *      with one or more transfer descriptors (TDs) per urb
 * @ep_dev: ep_device for sysfs info
 * @extra: descriptors following this endpoint in the configuration
 * @extralen: how many bytes of "extra" are valid
 * @enabled: URBs may be submitted to this endpoint
 * @streams: number of USB-3 streams allocated on the endpoint
 *
 * USB requests are always queued to a given endpoint, identified by a
 * descriptor within an active interface in a given USB configuration.
 */
struct usb_host_endpoint {
        struct usb_endpoint_descriptor          desc;
        struct usb_ss_ep_comp_descriptor        ss_ep_comp;
        struct usb_ssp_isoc_ep_comp_descriptor  ssp_isoc_ep_comp;
        struct list_head                urb_list;
        void                            *hcpriv;
        struct ep_device                *ep_dev;        /* For sysfs info */

        unsigned char *extra;   /* Extra descriptors */
        int extralen;
        int enabled;
        int streams;
};
复制代码

其中部分参数含义如下:

  • desc:端点描述符;
  • ss_ep_comp:超快速端点描述符;
  • urb_list:本端口对应的urb链表;
  • enabled:使能的话urb才能被提交到此端口;

usb_host_endpoint 结构体在另一个名为struct usb_endpoint_descriptor的结构体中包含真正的端点信息,其定义在include/uapi/linux/usb/ch9.h:

复制代码
/* USB_DT_ENDPOINT: Endpoint descriptor */
struct usb_endpoint_descriptor {
        __u8  bLength;
        __u8  bDescriptorType;

        __u8  bEndpointAddress;
        __u8  bmAttributes;
        __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;
} __attribute__ ((packed));
复制代码

其中部分参数含义如下:

  • bLength:描述符长度;
  • bDescriptorType:描述符类型, 端点描述符类型值是5;
  • bEndpointAddress:端点地址:位[3:0]表示端点号,第7位是方向:0位输出、1为输入;
  • bmAttributes:端点属性:位[1:0]值00表示控制、01表示等时、10表示批量、11表示中断;
  • wMaxPacketSize:本端点接受或发送的最大信息包的大小;
  • bInterval:轮询数据传输端点的时间间隔,用在中断传输上,比如间隔时间查询鼠标的数据;

5.2 接口

USB端口被捆绑为接口,USB接口只处理一种USB逻辑,一个USB接口代表一个逻辑上的设备,比如声卡驱动,就有两个接口:录音接口和播放接口。

内核使用struct usb_interface结构体来描述USB接口。USB核心把该结构体传递给USB设备驱动程序,之后由USB设备驱动程序来负责控制该结构体,该结构定义在include/linux/usb.h:

复制代码
/**
 * struct usb_interface - what usb device drivers talk to
 * @altsetting: array of interface structures, one for each alternate
 *      setting that may be selected.  Each one includes a set of
 *      endpoint configurations.  They will be in no particular order.
 * @cur_altsetting: the current altsetting.
 * @num_altsetting: number of altsettings defined.
 * @intf_assoc: interface association descriptor
 * @minor: the minor number assigned to this interface, if this
 *      interface is bound to a driver that uses the USB major number.
 *      If this interface does not use the USB major, this field should
 *      be unused.  The driver should set this value in the probe()
 *      function of the driver, after it has been assigned a minor
 *      number from the USB core by calling usb_register_dev().
 * @condition: binding state of the interface: not bound, binding
 *      (in probe()), bound to a driver, or unbinding (in disconnect())
 * @sysfs_files_created: sysfs attributes exist
 * @ep_devs_created: endpoint child pseudo-devices exist
 * @unregistering: flag set when the interface is being unregistered
 * @needs_remote_wakeup: flag set when the driver requires remote-wakeup
 *      capability during autosuspend.
 * @needs_altsetting0: flag set when a set-interface request for altsetting 0
 *      has been deferred.
 * @needs_binding: flag set when the driver should be re-probed or unbound
 *      following a reset or suspend operation it doesn't support.
 * @authorized: This allows to (de)authorize individual interfaces instead
 *      a whole device in contrast to the device authorization.
 * @dev: driver model's view of this device
 * @usb_dev: if an interface is bound to the USB major, this will point
 *      to the sysfs representation for that device.
 * @reset_ws: Used for scheduling resets from atomic context.
 * @resetting_device: USB core reset the device, so use alt setting 0 as
 *      current; needs bandwidth alloc after reset.
 *
 * USB device drivers attach to interfaces on a physical device.  Each
 * interface encapsulates a single high level function, such as feeding
 * an audio stream to a speaker or reporting a change in a volume control.
 * Many USB devices only have one interface.  The protocol used to talk to
 * an interface's endpoints can be defined in a usb "class" specification,
 * or by a product's vendor.  The (default) control endpoint is part of
 * every interface, but is never listed among the interface's descriptors.
 *
 * The driver that is bound to the interface can use standard driver model
 * calls such as dev_get_drvdata() on the dev member of this structure.
 *
 * Each interface may have alternate settings.  The initial configuration
 * of a device sets altsetting 0, but the device driver can change
 * that setting using usb_set_interface().  Alternate settings are often
 * used to control the use of periodic endpoints, such as by having
 * different endpoints use different amounts of reserved USB bandwidth.
 * All standards-conformant USB devices that use isochronous endpoints
 * will use them in non-default settings.
 *
 * The USB specification says that alternate setting numbers must run from
 * 0 to one less than the total number of alternate settings.  But some
 * devices manage to mess this up, and the structures aren't necessarily
 * stored in numerical order anyhow.  Use usb_altnum_to_altsetting() to
 * look up an alternate setting in the altsetting array based on its number.
 */
struct usb_interface {
        /* array of alternate settings for this interface,
         * stored in no particular order */
        struct usb_host_interface *altsetting;

        struct usb_host_interface *cur_altsetting;      /* the currently
                                         * active alternate setting */
        unsigned num_altsetting;        /* number of alternate settings */

        /* If there is an interface association descriptor then it will list
         * the associated interfaces */
        struct usb_interface_assoc_descriptor *intf_assoc;

        int minor;                      /* minor number this interface is
                                         * bound to */
        enum usb_interface_condition condition;         /* state of binding */
        unsigned sysfs_files_created:1; /* the sysfs attributes exist */
        unsigned ep_devs_created:1;     /* endpoint "devices" exist */
        unsigned unregistering:1;       /* unregistration is in progress */
        unsigned needs_remote_wakeup:1; /* driver requires remote wakeup */
        unsigned needs_altsetting0:1;   /* switch to altsetting 0 is pending */
        unsigned needs_binding:1;       /* needs delayed unbind/rebind */
        unsigned resetting_device:1;    /* true: bandwidth alloc after reset */
        unsigned authorized:1;          /* used for interface authorization */


        struct device dev;              /* interface specific device info */
        struct device *usb_dev;
        struct work_struct reset_ws;    /* for resets in atomic context */
};
复制代码

其中部分参数含义如下:

亲爱的读者和支持者们,自动博客加入了打赏功能,陆陆续续收到了各位老铁的打赏。在此,我想由衷地感谢每一位对我们博客的支持和打赏。你们的慷慨与支持,是我们前行的动力与源泉。

日期姓名金额
2023-09-06*源19
2023-09-11*朝科88
2023-09-21*号5
2023-09-16*真60
2023-10-26*通9.9
2023-11-04*慎0.66
2023-11-24*恩0.01
2023-12-30I*B1
2024-01-28*兴20
2024-02-01QYing20
2024-02-11*督6
2024-02-18一*x1
2024-02-20c*l18.88
2024-01-01*I5
2024-04-08*程150
2024-04-18*超20
2024-04-26.*V30
2024-05-08D*W5
2024-05-29*辉20
2024-05-30*雄10
2024-06-08*:10
2024-06-23小狮子666
2024-06-28*s6.66
2024-06-29*炼1
2024-06-30*!1
2024-07-08*方20
2024-07-18A*16.66
2024-07-31*北12
2024-08-13*基1
2024-08-23n*s2
2024-09-02*源50
2024-09-04*J2
2024-09-06*强8.8
2024-09-09*波1
2024-09-10*口1
2024-09-10*波1
2024-09-12*波10
2024-09-18*明1.68
2024-09-26B*h10
2024-09-3010
2024-10-02M*i1
2024-10-14*朋10
2024-10-22*海10
2024-10-23*南10
2024-10-26*节6.66
2024-10-27*o5
2024-10-28W*F6.66
2024-10-29R*n6.66
2024-11-02*球6
2024-11-021*鑫6.66
2024-11-25*沙5
2024-11-29C*n2.88
posted @   大奥特曼打小怪兽  阅读(3697)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 实操Deepseek接入个人知识库
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
历史上的今天:
2019-05-04 Spring MVC -- MVC设计模式(演示4个基于MVC框架的案例)
2018-05-04 第十四节,TensorFlow中的反卷积,反池化操作以及gradients的使用
2018-05-04 第十三节,使用带有全局平均池化层的CNN对CIFAR10数据集分类
如果有任何技术小问题,欢迎大家交流沟通,共同进步

公告 & 打赏

>>

欢迎打赏支持我 ^_^

最新公告

程序项目代做,有需求私信(小程序、网站、爬虫、电路板设计、驱动、应用程序开发、毕设疑难问题处理等)。

了解更多

点击右上角即可分享
微信分享提示