Linux USB驱动详解
发布日期:2021-09-29 04:02:20 浏览次数:14 分类:技术文章

本文共 13504 字,大约阅读时间需要 45 分钟。

分享一下我老师大神的人工智能教程!零基础,通俗易懂!

也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!

               

 

原文地址:

1.Linux usb设备驱动框架

USB是通用串行总线的总称,Linux内核几乎支持所有的usb设备,包括键盘,鼠标,打印机,modem,扫描仪。Linux的usb驱动分为主机驱动与gadget驱动。前者是设备连接到计算机上,通过主机驱动扫描usb设备,控制所连接的设备。而gadget驱动一般用于嵌入式设备,gadget驱动用于控制嵌入式设备。Linux的usb驱动两种类型图如下:

  

左侧是usb的主机驱动,右侧是gadget驱动。下面着重介绍一下usb的主机驱动:

(1)usb主机控制器-直接与硬件设备交互。

(2)usb core-向usb设备驱动提供API以及usb主机控制器驱动的程序。使用usb core所提供的函数,宏来完成数据处理的功能。

(3)usb设备驱动,即usb接口驱动,一般所说的usb驱动指的是usb接口驱动

  

2.usb系统的组成部分

usb系统一般由三个部分组成,主机,一个或多个usb hub,以及与之些hub连接的usb设备。

(1)主机

在任何的usb系统中仅有一个主机,主机系统中的usb接口即上图中的主机控制器,主机控制器可由硬件,软件或固件组成。主机主要负责:

a.检测usb设备的连接与拆除

b.管理主机与usb设备之间的控制流

c.管理主机与usb设备之间的数据流

d.收集状态和活动的统计

e.为连接的usb设备提供电源

 

 

(2)usb设备

所有的usb设备都是通过地址来存取的,这个地址在连接或枚举时分配。usb设备对usb系统来说是端点的集合,一组端点实现一个接口。设备端点是usb设备中唯一可寻址的部分。它是主机与设备之间通信流的结束点。一系列的相互独立的端点构成了usb逻辑设备。每个端点支持流进设备或者是流出设备。

主机与设备端点上的usb数据传输是通过管道的方式。

 

(3)hub

所有的usb device都连接在hub端口上。

 

 

 

3. usb传输模式

 

(1)控制传输模式(Control)

控制传输模式支持双向传输,用来处理从usb主机端口到usb设备端口的数据传输,用于控制指令,设备状态查询以及确认命令。

 

(2)等时传输方式(lsochronous)

等时传输是一种周期性的连续性的意向传输模式,通常用于对时间有着密切关系的信息的传输,对准确性要求不高,但对时间要求极为敏感的设备,如视频,音频的传输。

 

(3)中断传输模式(Interrupt)

中断传输模式用于非周期性的,自然发生的,数据量小的传输,数据传输的方向是从设备到主机。如usb键盘和鼠标

 

(4)批量传输模式(bulk)

批量传输模式是一种单向的,用于大量数据传输的模式,该方式用来传输正确无误的数据。通常打印机,扫描仪,数码相机以这种方式与主机连接

 

 

4. usb设备组成

(1)一个usb设备由可以有一个或多个配置

(2)一个配置通常可以有一个或多个接口

(3)一个接口通常可以有一个或多个端点

通常所尽的usb设备驱动是指接口驱动,即一个接口对应一个驱动。

所以Linux usb设备有四大描述符,分别为设备描述符,配置描述符,接口描述符,端点描述符。下面看一个这几个描述符的相关数据结构:

 

 

struct usb_device_descriptor

{

      _u8 bLength;  //此描述符的字节数
      _u8  bDescriptorType; //描述符的种类为设备
      _u16 bcdUSB;  //此设备与描述符兼容的usb设备说明版本号(BCD码)
      _u8   bDeviceClass; //设备类码
      _u8   bDeviceSubClass; //设备子类码
      _u8   bDeviceProtocol; //协议码
      _u8   bMaxPacketSize0; //端点0的最大包大小
      _u16 idVendor; //厂商标志
      _u16  idProduct; //产品标志
      _u16 bcdDevice; //设备发行号
      _u8   iManufacturer; //描述厂商的字串索引

      _u8   iProduct; //描述产品信息的字串索引

      _u8  iSerialNumber; //描述设备序列号信息的字串索引

      _u8  bNumConfigurations;//此设备支持的配置数

  }_attribute_ ((packed));

 

设备类码的典型值如下:

 

#define USB_CLASS_PER_INTERFACE 0

#define USB_CLAS_AUDIO 1     //声音设备

#define USB_CLASS_COMM 2   // 调制解调器,网卡,ISDN连接

#define USB_CLASS_HID  3    //HID设备,如鼠标,键盘

#define USB_CLASS_PHYSICAL 5 //物理设备

#define USB_CLASS_STILL_IMAGE 6 //静止图像捕捉设备

#define USB_CLASS_PRINTER 7//打印机

#define USB_CLASS_MASS_STORAGE //8 批量存储设备

#define USB_CLASS_HUB 9   //USB HUBS

#define USB_CLASS_CSCID 0x0B  //智能卡

#define USB_CLASS_VIDEO 0X0E //视频设备,如网络摄像头

#define USB_CLASS_VENDOR_SPEC 0xFF //厂商自定义的设备

 

  struct usb_config_descriptor{

 

 _u8 bLength ;//此描述符的字节数

_u8 bDescriptorType; //配置描述符类型

_u16 wTotalLength; //此配置信息的总长(包括配置,接口,端点和设备类型及厂商定义的描述符)

_u8 bNumInterfaces; //此配置所支持的接口数

_u8 bConfigurationValue ;//在setConfiguration()请求中用作参数来选定此配置

_u8 iConfiguration; //描述此配置的字串描述符索引

_u8 bmAttributes; //电源配置特性

_u8 bMaxpowe;r //此配置下的总线电源耗电量

}_attribute_ ((packed));

 

 

配置描述符给出了usb设备配置信息,以及此配置下的接口数。每个接口可能的独立操作。

 

 

 

struct usb_interface_descriptor{

 

_u8 bLength ;//此描述符的字节数

_u8 bDescriptorType;//接口描述符类

_u8 bInterfacNumber;//接口号,当前配置所支持的接口数组索引,从0开始

_u8 bNumEndpoints ;//此接口用的端点数量,如果是0,说明此接口只有缺省控制通道

_u8 bAlernateSetting;//可选设备的索引值

_u8 bInterfaceClass;// 类值,0值作为将来保留使用如果是0FFH,此接口由厂商说明

_u8 bInterfaceSubClass;//子类码

_u8 bInterfaceProtocol;//协议码

_u8 iInterface;//描述此接口的字串描述符索引

 

}_attribute_ ((packed));

 

struct usb_endpoint_descriptor{

_u8 bLength ;//此描述符的字节数

_u8 bDescriptorType;//端点描述符类

_u8 bEndpointAddress;此描述符所描述的端点的地址

_u8 bmAtrributes;//所指定的端点的特性,如果是00=控制传送,01=等时传送,10=批传送,11=中断传送

_u8 wMaxPacketSize;//当前配置下端点能够发送与接收的最大数据包大小

_u8 bInterval;//轮询数据传送端点的时间间隙

_u8 bRefresh

_u8 bSynchAddress

}_attribute_ ((packed));

 

以上给出了usb中的设备描述符,配置描述符,接口描述符和端点描述符。

 

 

5. usb设备驱动的几个重要的数据结构

 

usb_driver,usb_device,usb_bus.

 

 

/**

* stru ctusb_driver - identifiesU SB interface driver tou sbcore
* @name: The driver name shou ld beu niqu e amongU SB drivers,
*      and shou ld normally be the same as the modu le name.
* @probe: Called to see if the driver is willing to manage a particu lar
*      interface on a device.  If it is, probe retu rns zero andu ses
*     u sb_set_intfdata() to associate driver-specific data with the
*      interface.  It may alsou seu sb_set_interface() to specify the
*      appropriate altsetting.  Ifu nwilling to manage the interface,
*      retu rn -ENODEV, if genu ine IO errors occu red, an appropriate
*      negative errno valu e.
* @disconnect: Called when the interface is no longer accessible,u su ally
*      becau se its device has been (or is being) disconnected or the
*      driver modu le is beingu nloaded.
* @u nlocked_ioctl:U sed for drivers that want to talk tou serspace throu gh
*      the "u sbfs" filesystem.  This lets devices provide ways to
*      expose information tou ser space regardless of where they
*      do (or don't) showu p otherwise in the filesystem.
* @su spend: Called when the device is going to be su spended by the system.
* @resu me: Called when the device is being resu med by the system.
* @reset_resu me: Called when the su spended device has been reset instead
*      of being resu med.
* @pre_reset: Called byu sb_reset_device() when the device
*      is abou t to be reset.
* @post_reset: Called byu sb_reset_device() after the device
*      has been reset
* @id_table:U SB driversu se ID table to su pport hotplu gging.
*      Export this with MODU LE_DEVICE_TABLE(u sb,...).  This mu st be set
*      or you r driver's probe fu nction will never get called.
* @dynids:u sed internally to hold the list of dynamically added device
*      ids for this driver.
* @drvwrap: Driver-model core stru ctu re wrapper.
* @no_dynamic_id: if set to 1, theU SB core will not allow dynamic ids to be
*      added to this driver by preventing the sysfs file from being created.
* @su pports_au tosu spend: if set to 0, theU SB core will not allow au tosu spend
*      for interfaces bou nd to this driver.
* @soft_u nbind: if set to 1, theU SB core will not killU RBs and disable
*      endpoints before calling the driver's disconnect method.
*
*U SB interface drivers mu st provide a name, probe() and disconnect()
* methods, and an id_table.  Other driver fields are optional.
*
* The id_table isu sed in hotplu gging.  It holds a set of descriptors,
* and specialized data may be associated with each entry.  That table
* isu sed by bothu ser and kernel mode hotplu gging su pport.
*
* The probe() and disconnect() methods are called in a context where
* they can sleep, bu t they shou ld avoid abu sing the privilege.  Most
* work to connect to a device shou ld be done when the device is opened,
* andu ndone at the last close.  The disconnect code needs to address
* concu rrency issu es with respect to open() and close() methods, as
* well as forcing all pending I/O requ ests to complete (byu nlinking
* them as necessary, and blockingu ntil theu nlinks complete).
*/
stru ct{
         const char *;
         int (*) (stru ct *,
                       const stru ct*);
         void (*) (stru ct *);
         int (*u nlocked_ioctl) (stru ct*,u nsigned int,
                         void *);
         int (*) (stru ct *,);
         int (*) (stru ct *);
         int (*reset_resu me)(stru ct*);
         int (*)(stru ct *);
         int (*post_reset)(stru ct*);
         const stru ct*;
         stru ctdynids;
         stru ctdrvwrap;
        u nsigned int no_dynamic_id:1;
        u nsigned int su pports_au tosu spend:1;
        u nsigned int soft_u nbind:1;
};

 

usb_driver中的probe函数扫描连接到主机上的usb设备,并且注册usb接口驱动。

 

disconnect函数是当usb设备移除时调用。

 

 

/*

* Allocated per bu s (tree of devices) we have:
*/
stru ctu sb_bu s {
         stru ctdevice *controller ;     /* host/master side hardware */
         int bu snu m;                    /* Bu s nu mber (in order of reg) */
         const char *bu s_name;          /* stable id (PCI slot_name etc) */
        u 8u ses_dma;                   /* Does the host controlleru se DMA? */
        u 8u ses_pio_for_control;       /*
                                         * Does the host controlleru se PIO
                                         * for control transfers?
                                         */
        u 8 otg_port;                   /* 0, or nu mber of OTG/HNP port */
        u nsigned is_b_host:1;          /* tru e du ring some HNP roleswitches */
        u nsigned b_hnp_enable:1;       /* OTG: did A-Host enable HNP? */
        u nsignedsg_tablesize ;         /* 0 or largest nu mber of sg list entries */
         int devnu m_next;               /* Next open device nu mber in
                                         * rou nd-robin allocation */
         stru ctu sb_devmap  devmap;      /* device address allocation map */
         stru ctusb_device * root_hu b;   /* Root hu b */
         stru ctu sb_bu s *hs_companion;  /* Companion EHCI bu s, if any */
         stru ctlist_head bu s_list;     /* list of bu sses */
         int bandwidth_allocated;       /* on this bu s: how mu ch of the time
                                         * reserved for periodic (intr/iso)
                                         * requ ests isu sed, on average?
                                         *U nits: microseconds/frame.
                                         * Limits: Fu ll/low speed reserve 90%,
                                         * while high speed reserves 80%.
                                         */
         int bandwidth_int_reqs;        /* nu mber of Interru pt requ ests */
         int bandwidth_isoc_reqs;       /* nu mber of Isoc. requ ests */
#ifdef CONFIG_USB_DEVICE FS
         stru ctdentry *u sbfs_dentry;   /*u sbfs dentry entry for the bu s */
#endif
#ifdefined (CONFIG_U SB_MON) ||(CONFIG_U SB_MON_MODU LE)
         stru ctmon_bu s *mon_bu s ;       /* non-nu ll when associated */
         int monitored;                 /* non-zero when monitored */
#endif
};

 

 

**

* stru ctusb_device - kernel's representation of aU SB device
* @devnu m: device nu mber; address on aU SB bu s
* @devpath: device ID string foru se in messages (e.g., /port/...)
* @rou te: tree topology hex string foru se with xHCI
* @state: device state: configu red, not attached, etc.
* @speed: device speed: high/fu ll/low (or error)
* @tt: Transaction Translator info;u sed with low/fu ll speed dev, highspeed hu b
* @ttport: device port on that tt hu b
* @toggle: one bit for each endpoint, with ([0] = IN, [1] = OU T) endpoints
* @parent: ou r hu b,u nless we're the root
* @bu s: bu s we're part of
* @ep0: endpoint 0 data (defau lt control pipe)
* @dev: generic device interface
* @descriptor:U SB device descriptor
* @config: all of the device's configs
* @actconfig: the active configu ration
* @ep_in: array of IN endpoints
* @ep_ou t: array of OU T endpoints
* @rawdescriptors: raw descriptors for each config
* @bu s_mA: Cu rrent available from the bu s
* @portnu m: parent port nu mber (origin 1)
* @level: nu mber ofU SB hu b ancestors
* @can_su bmit:U RBs may be su bmitted
* @persist_enabled: U SB_PERSIST enabled for this device
* @have_langid: whether string_langid is valid
* @au thorized: policy has said we canu se it;
*      (u ser space) policy determines if we au thorize this device to be
*     u sed or not. By defau lt, wiredU SB devices are au thorized.
*      WU SB devices are not,u ntil we au thorize them fromu ser space.
*      FIXME -- complete doc
* @au thenticated: Crypto au thentication passed
* @wu sb: device is WirelessU SB
* @string_langid: langu age ID for strings
* @produ ct: iProdu ct string, if present (static)
* @manu factu rer: iManu factu rer string, if present (static)
* @serial: iSerialNu mber string, if present (static)
* @filelist:u sbfs files that are open to this device
* @u sb_classdev:U SB class device that was created foru sbfs device
*      access fromu serspace
* @u sbfs_dentry:u sbfs dentry entry for the device
* @maxchild: nu mber of ports if hu b
* @children: child devices -U SB devices that are attached to this hu b
* @qu irks: qu irks of the whole device
* @u rbnu m: nu mber ofU RBs su bmitted for the whole device
* @active_du ration: total time device is not su spended
* @connect_time: time device was first connected
* @do_remote_wakeu p:  remote wakeu p shou ld be enabled
* @reset_resu me: needs reset instead of resu me
* @wu sb_dev: if this is a WirelessU SB device, link to the WU SB
*      specific data for the device.
* @slot_id: Slot ID assigned by xHCI
*
* Notes:
*U sbcore drivers shou ld not setu sbdev->state directly.  Insteadu se
*u sb_set_device_state().
*/
stru ct{
         int             devnu m;
         char            devpath[16];
                     rou te;
         enu m  ;
         enu m  ;
         stru ct   *tt;
         int             ttport;
        u nsigned int[2];
         stru ct*;
         stru ct*;
         stru ctep0;
         stru ct;
         stru ct;
         stru ct*;
         stru ct*actconfig;
         stru ct*ep_in[16];
         stru ct*ep_ou t[16];
         char **rawdescriptors;
        u nsigned short bu s_mA;
        portnu m;
        level;
        u nsigned can_su bmit:1;
        u nsigned persist_enabled:1;
        u nsigned have_langid:1;
        u nsigned au thorized:1;
        u nsigned au thenticated:1;
        u nsigned wu sb:1;
         int string_langid;
        /* static strings from the device */
         char *;
         char *;
         char *;
         stru ctfilelist;
#ifdef CONFIG_USB_DEVICE _CLASS
         stru ct*u sb_classdev;
#endif
#ifdef CONFIG_USB_DEVICE FS
         stru ct*u sbfs_dentry;
#endif
         int maxchild;
         stru ct*children[];
        ;
        u rbnu m;
        u nsigned long active_du ration;
#ifdef
        u nsigned long connect_time;
        u nsigned do_remote_wakeu p:1;
        u nsigned reset_resu me:1;
#endif
         stru ct*;
         int slot_id;
};
#define()(, stru ct,)
static inline stru ct*(stru ct*)
{
         retu rn(->.);
}

 

以上三个结构体分别是usb_driver,usb_bus,usb_device设备结构体。

 

 

 

usb_interface结构体:

 

struct {

        /* array of alternate settings for this interface,
         * stored in no particular order */
         struct*;
         struct*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*intf_assoc;
         int;                     /* minor number this interface is
                                         * bound to */
         enumcondition;        /* 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 reset_running:1;
         unsigned resetting_device:1;   /* true: bandwidth alloc after reset */
         struct;             /* interface specific device info */
         struct*;
        pm_usage_cnt;         /* usage counter for autosuspend */
         structreset_ws;   /* for resets in atomic context */
};

 struct usb_host_interface *altsetting包含了usb interface的所有可选设置。

 struct usb_host _interface *cur_altsetting是usb interface的当前可选设置。

 

下面看一个struct usb_host_interface

 

 

/* host-side wrapper for one interface setting's parsed descriptors */

转载地址:https://blog.csdn.net/hddghhfd/article/details/84024333 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:IEEE802 11协议基础知识
下一篇:USB主机控制器 Host Controller --深入理解

发表评论

最新留言

关注你微信了!
[***.104.42.241]2024年02月29日 13时18分20秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章

五子棋c语言代码判定,c语言 五子棋危险判断 求大神解释啊 2019-04-21
c语言实现一个单向链表,C语言实现一个简单的单向链表list 2019-04-21
c语言怎么设置bmp图片,用c语言把bmp格式的彩色图片转换成黑白的 2019-04-21
c语言游戏人物结构buff,浅谈游戏中BUFF的设计要点 2019-04-21
c语言学生信息管理题目,求助,一道关于学生信息管理系统的题目 2019-04-21
随机迷宫 c语言,[原创]递归随机迷宫生成算法详解 2019-04-21
excel函数怎么用android,GitHub - huangting924/Android_Excel: 在android中生成excel 2019-04-21
android item倒计时功能,Android利用RecyclerView实现列表倒计时效果 2019-04-21
鸿蒙非手机系统,新系统正式定档,华为高管明确表态,鸿蒙不是安卓的替代品!... 2019-04-21
亚联发展和华为合作鸿蒙系统,亚联发展(002316)个股分析_牛叉诊股_同花顺财经... 2019-04-21
android studio atom插件,android-studio – Android Studio模拟器:Intel Atom x86与ARM 2019-04-21
android兼容tls版本,低版本Android上TLS版本导致的诡异握手失败问题 2019-04-21
android游戏中期检查表,课题中期检查填报表 2019-04-21
python动态类型的坑_Python学习笔记6——动态类型 2019-04-21
sequelize多条件_在服务器接收小程序的request请求,并对数据库进行多条件查询... 2019-04-21
wget 连接超时_wget 这玩意要超时重试多少次啊? 2019-04-21
湘潭python培训_对流-反应-扩散方程的有限元求解 2019-04-21
信度和效度经典例子_第四节个案研究的效度与信度 2019-04-21
matlab表白_数学也浪漫:程序员七夕表白攻略 2019-04-21
button点击后变色_HTML | 两只“变色龙”带你玩转色彩变幻 2019-04-21