|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
如果您觉得本篇CentOSLinux教程讲得好,请记得点击右边漂浮的分享程序,把好文章分享给你的好朋友们!USB是主机和核心设备之间的一种毗连。USB最后是为了替换林林总总的分歧的接口的低速总线而计划的。(比方:串口,并口,键盘毗连等)。它以单一范例的总线毗连各类分歧范例的设备。
USB拓扑机构不是以总线体例的。而是一棵由几个点对点的毗连组成的树。毗连线由4根电缆构成(电源,地线,两个数据线)
USB主把持器(HostController)卖力扣问每个USB设备是不是无数据必要发送。也就是说:一个USB设备在没有主把持器请求的情形下是不克不及发送数据的。
USB协定标准界说了一套任何特定范例的设备都能够遵守的尺度。假如一个设备遵守该设备,就不必要一个特别的驱动步伐。这些分歧的特定范例称之为类(class).比方:存储设备,键盘,鼠标,游戏杆,收集设备等。关于不切合这些类的其他设备。则必要对此设备编写特定driver.
USB设备组成:
LinuxKernel供应了USBCore来处置年夜部分USB的庞大性。写USB驱动,Sam以为就是把USB硬件设备和USBCore之间给相同起来。
USB协定把一个硬件USB设备用以下各个界说勾勒出来。
观点一.USB端点(endpoint)
USBendpoint只能往一个偏向传送数据。从主机到设备(输入Endpoint)或从设备到主机(输出Endpoint)。一个Endpoint能够看做一个单向的管道。
有四品种型Endpoint,他们的区分在于传送数据的体例:
把持Endpoint:
用来把持对USB设备分歧部分的会见。他们一般用于设置设备,猎取设备信息,发送死令到设备,大概猎取设备的形态呈报。每一个USB设备都有一个名为:Endpoint0的把持Endpoint。USBCore利用该Endpoint0在拔出时举行设备的设置。
中止Endpoint:
每当USB主把持器请求设备传输数据时,中止Endpoint就以一个流动的速度来传送大批的数据。
USBKeyboard和Mouse一般利用中止Endpoint。
请注重,中止Endpoint和中止分歧,它仍是没法自动向USB主把持器发送数据。二是必要守候USB主把持器轮询。
批量Endpoint:
BulkEndpoint用来传输多量量的数据。USB标准不包管数据能在划定工夫内传输完成。但包管数据完全性。一般打印机,存储设备和收集设备利用之。
等时Endpoint:
用来传输多量量数据,但数据是不是可以抵达,怎没法包管。
一般数据搜集设备会利用之。
Sam以为,实在一个设备有几个和甚么范例的Endpoint。实际上是硬件设备在打造阶段已定好的。USBCore只是往读取了这些信息,并把这些信息传送给USBdriver.
LinuxKernel中利用structusb_host_endpoint来形貌USBEndpoint。但实在个中的structusb_endpoint_descriptor才是真实的形貌Endpoint的。
structusb_endpoint_descriptor
{
__u8bLength;
__u8bDescriptorType;
__u8bEndpointAddress;
__u8bmAttributes;
__le16wMaxPacketSize;
__u8bInterval;
__u8bRefresh;
__u8bSynchAddress;
}__attribute__((packed));
bEndpointAddress:
//此EndpointUSB地点。它还包括了Endpoint偏向信息。经由过程掩码USB_DIR_OUT和USB_DIR_IN判别是输入Endpoint仍是输出Endpoint。
bmAttributes;
EndpointType,也能够经由过程掩码:USB_ENDPOINT_XFER_ISOC等判别此Endpoint是中止,等时,把持仍是批量Endpoint。
wMaxPacketSize;
该Endpoint一次能够处置的最年夜字节数。固然driver能够传送更年夜的数据,但实践传送时,仍是会支解成这个巨细。
bInterval:
假如是中止Endpoint,它就是Endpoint的距离设置。也就是说,中止哀求距离工夫。以毫秒为单元。
观点二:接口(Interface)
数个Endpoint被***为一个USBInterface。
一个USBInterface只对应一个逻辑毗连,比方鼠标,键盘大概音频流。一个USB设备能够对应多个Interface。比方Sam见过的鼠标键盘一同的设备,就有2个Interface,一个键盘,一个鼠标。
别的,有些USB扬声器有2个Interface,一个键盘,一个音频流。
注重:每一个USBdrver只处置一个USBInterface。以是,一个设备大概会对应多个driver.
以是,USBCore在处置USB设备拔出时,会针对分歧的Interface叫醒它以为符合的driver。并以参数的情势把interface传送给drver.
LinuxKernel利用structusb_interface来形貌USBInterface。但Interface参数按例是个中的usb_interface_descriptor。
structusb_interface
{
structusb_host_interface*altsetting;
structusb_host_interface*cur_altsetting;
unsignednum_altsetting;
structusb_interface_assoc_descriptor*intf_assoc;
intminor;
enumusb_interface_conditioncondition;
unsignedis_active:1;
unsignedneeds_remote_wakeup:1;
structdevicedev;
structdevice*usb_dev;
intpm_usage_cnt;
};
structusb_host_interface*altsetting;
Interface布局体数组,包括了一切大概用于该Interface的可选设置。
structusb_host_interface*cur_altsetting;
可选设置数
unsignednum_altsetting;
指向altsetting的指针。以后的Active设置。
usb_interface_descriptor:Interface形貌符
structusb_interface_descriptor{
__u8bLength;
//形貌符的字节长度。协定里划定,每一个形貌符必需以一个字节打头来标明形貌符的长度。接口形貌符的bLength应当是9
__u8bDescriptorType;
//形貌符的范例。各类形貌符的范例都在ch9.h,*Descriptortypes...USB2.0spectable9.5
__u8bInterfaceNumber;
//接标语。每一个设置能够包括多个接口,这个值就是它们的索引值
__u8bAlternateSetting;
__u8bNumEndpoints;
//接口具有的端点数目。这里其实不包含端点0
__u8bInterfaceClass;
//此Interface所属Class。比方:HID=0x03
__u8bInterfaceSubClass;
//此值基于bInterfaceClass之上。标明在某个Interfaceclass中的子class。比方:HID中有:USB_INTERFACE_SUBCLASS_BOOT
__u8bInterfaceProtocol;
//同上,HID中就有USB_INTERFACE_PROTOCOL_MOUSE
__u8iInterface;//字符串形貌符,放一些形貌性厂商信息。
}__attribute__((packed));//__attribute__,意义就是告知编译器,这个布局的元素都是1字节对齐的,不要再增加添补位了。
观点三:设置
一个或多个USBInterface被***为设置。一个USB设备能够有多个设置,而且能够在多个设置之间切换。
设置:structusb_host_config
USB设备:usb_device.
综上所述:
1个USB设备有一个或多个设置
1个设置有一个或多个Interface
一个Interface有一个或多个设置
Interface没有或有多个Endpoint
USB URB
LinuxKernel中的USB代码经由过程urb(USB哀求快)与一切的USB设备通讯。
urb被用来以异步体例从特定的USB设备的特定USBEndpoint上吸收数据,或往特定的USB设备的特定USBEndpoint上发送数据。
urb是由USBdriver创立的。并分派给特定USB设备的特定Endpoint。并由USBdriver提交给USBCore。
一:创立urb.
urb不克不及在driver中静态的界说。由于如许会损坏USBCore对urb的计数机制。以是必需利用:
usb_alloc_urb函数来创立。
structurb*usb_alloc_urb(intiso_packets,gfp_tmem_flags)
第一个参数是:等时数据包的数目。
如果您觉得本篇CentOSLinux教程讲得好,请记得点击右边漂浮的分享程序,把好文章分享给你的好朋友们! |
|