本文共 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 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!