USB模块培训大纲.doc_第1页
USB模块培训大纲.doc_第2页
USB模块培训大纲.doc_第3页
USB模块培训大纲.doc_第4页
USB模块培训大纲.doc_第5页
已阅读5页,还剩9页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

USB通信模型USB串口总线连接设备时必须使用集线器(Hub),这与局域网的设备连接类似。USB总线接口包括USB主控制器和根集线器,其中USB主控制器负责处理主机与设备之间电气和协议层的互连,根集线器提供USB设备连接点。USB系统使用USB主控制器来管理主机和USB设备之间的数据传输,另外它也负责管理USB资源,如带宽等。USB物理总线拓朴图如图1所示。 图1USB物理总线拓朴图每一个设备会有一个或者多个逻辑连接点在里面,每个连接点叫端点(EndPoint)。每个端点有四种数据传送方式:控制方式传送;同步方式传送;中断方式传送;批量传送。在主机控制器和设备的端点之间的连接叫作管道(Pipe)。对于同样性质的一组的端点的组合叫做接口(Interface),如果一个设备包含不止一个的接口就可以称之为复合设备(Composite Device)。 所有USB设备都要求实现用端点0作为输入和输出端点的默认控制方式。USB系统软件用该默认控制方式对逻辑设备进行初始化和一般的操作。USB通信流图如图2所示,它显示了通信流在端点与主机端的存储器缓冲区之间的管道传输。端点是主机与设备之间通信流的终点。每个USB逻辑设备由 一个独立的端点集组成。在设备连接时系统为每个逻辑设备分配了惟一的地址。设备的每个端点由设备给定一个惟一的端点号。每个端点由设备决定数据流的方向。设备地址、端点号和方向的组合支持一个方向的数据流的输入/输出。 图2USB通信流图端点、接口和配置是USB通信的几个基本要素,分别说明如下:端点USB通信的是通过端点(endpoint)所形成的管道进行的。一个USB端点只能在一个方向上传输数据, 与主机的buffer之间形成一个单向的管道。Linux内核用结构usb_host_endpoint描述端点。所有USB设备都以端点(endpoint)为0的管道作为默认控制管道,0端点在设备连接、上电和收到总线复位信号时就可以访问。管道分为流管道和消息管道,流过流管道的数据无USB定义的结构,消息管道中的数据是有USB定义的消息结构。主机先向USB设备发送一个请求,然后是数据传输,最后,会是一个状态阶段。USB定义了4种传输类型:控制(Control)、同步(isochronous)、中断(interrupt)、大量(bulk)。所有的传送方式下的主动权都由主机控制器决定。4种传输类型说明如下:(1)控制(Control)方式传输控制传输是双向传送,数据量通常较小。主要用来进行查询、配置和给USB设备发送通用的命令。控制传送方式可以包括8、16、32和64字节的数据,这依赖于设备和传输速度。(2)同步(isochronous)方式传输同步传输提供了确定的带宽和间隔时间(latency)。它被用于时间严格并具有较强容错性的流数据传输,或者用于要求恒定的数据传送率的即时应用中。(3)中断(interrupt)方式传输中断方式传输主要用于定时查询设备是否有中断数据要传送。设备的端点模式器的结构决定了它的查询频率,在1ms到255ms之间。这种传输方式典型的应用在少量分散的、不可预测数据的传输。键盘、操纵杆和鼠标就属于这一类型。(4)批量(bulk)传输批量传输主要应用在数据大量传送和接收上,同时又没有带宽和间隔时间要求的情况下,要求保证传输。打印机和扫描仪属于这种类型。接口USB 接口通常是物理硬件上的一个USB插口,一个USB接口包含多个USB端点。USB接口只处理一类 USB 逻辑连接, 如一个鼠标、一个键盘或者一个音频流。接口的初始化的状态是第一个设置, 0号. 预备的设置可用来以不同方式控制单独的端点, 例如来保留不同量的 USB 带宽给设备. 每个有同步端点的设备使用预备设备给同一个接口.USB 接口在内核中使用 struct usb_interface 结构来描述. 这个结构是 USB 核传递给 USB 驱动的并且是 USB 驱动接下来负责控制的.配置USB设备用描述符报告它们的属性,描述符是一个有规定格式的数据结构,与关系数据库的各条数据记录相似。使用描述符可以简洁地保存各个配置的属性,每个配置可以再使用有相同特性的其他配置中的描述符或描述符的部分。一个 USB 设备可以有多个配置,多个配置之间可以转换以便改变设备的状态. 例如, 一些允许固件被下载到它们的设备包含多个配置,一个配置只能在一个时间点上被使用。每种配置有一个或多个接口,每个接口有0或多个端点。总线枚举当USB设备插拔时,主机会使用称为总线枚举的过程来识别和管理设备。当USB设备插入端口时,主机所做的操作是:(1)USB设备通过所连接的集线器向主机报告连接事件,此时,设备处于上电状态,而连接的端口处于禁止状态。(2)主机通过查询集线器端口确定变化的类型。(3)主机等待100ms让设备的电源变得稳定,然后向端口发出复位命令。(4)集线器在该端口执行复位处理,复位完成后激活该端口。此时,USB设备处于默认状态。(5)主机给设备分配一个惟一的地址,使设备进入寻址状态。(6)在USB设备接收到惟一的地址前,主机仍可以默认控制管道和默认的地址访问设备。主机读出设备描述符,确定设备默认管道的实际最大数据有效负载。(7)通过读从0到n-1个配置,主机可查找到设备的配置。(8)主机给设备分配一个配置,设备处于配置状态,设备每个端点有配置的特性,设备已准备好。USB OTG设备类型(1)A Device:此时设备处于Host模式,IDpin被拉低(2)B Device:此时设备处于Device模式,IDpin处于悬空状态A/B Device之间的切换通过HNP协议USB OTG协议(1)SRP(Session Request Protocol)协议:由B Device发起,主要是用来向A Device设备申请打开Vbus,并提供一个Session。Session为Vbus从打开到关闭的这段时间。(2)ADP(Attach Detection Protocol)协议:提供设备检测是否有对端设备插入。(3)HNP(Host Negotiation Protocol)协议:OTG设备通过HNP来切换Host/Device角色。当前的USB Host通过HNP Polling轮询GetStatus()命令返回的数据中的Host request flag查询对端设备是否请求变为Host, Polling间隔为1-2秒。当当前的USB Host决定允许B Device转变为Host以后通过SetFeature()打开b_hnp_enable,本次session结束后Host回到A Device手里。OTG Device /Embedded Host 与 仅作为外设的B-device(带A插头型)Host端检测到A插头插入,停止ADP,打开VBus,因为B-Device的A插头与设备作为一体,此时B-Device必定与A插头连接,Host检测到外设连接,开始枚举。 OTG Device/Embedded Host 与 仅作为外设的B-device(A插头为线缆连接)Host段检测到A插头插入,停止ADP,打开VBus,如果B-Device是线缆连接完毕在将A插头插入则整个连接过程与上面无异,因为此时B-Device可能还没有插入插头,则设备连接超时,VBus再次关闭,等待下一次ADP的改变(线缆连接完毕),再次打开VBus,此时开始正常总线枚举。OTG Device 与 OTG DeviceHost端检测到插头插入,则打开VBus,如果没有外设检测到,则关闭VBus,打开ADP Probing,Device端检测到插头插入,则打开SRP,如果线缆没有插入,则SRP超时,Device端开始进行ADP Probing,当线缆连接完毕,Device端侦测到ADP变化,发送SRP请求Host打开VBus,Host回应SRP并且打开VBus,完成设备连接。下图为PMIC中USB应用图解:该图中与USB相关的有USB Conn.,88PM8606,和USB PHY三个部分。其中可以看到除了VBUS外,D+,D-,ID三根线将USB Conn和USB PHY直接相连。当PXA955做为USB从设备时,ID是悬空的,此时VBUS首先产生高电平,并通过此时88PM8606检测到VCHG电压,并产生VBUS中断,在VBUS的中断处理程序中开始使能USB控制器,而此VBUS电压也会通过88PM8606一路的传给USB PHY,该路电压一方面会通过VLDO5给USB PHY本身供电(保证USB PHY能够正常工作),另一方面给VBUS管脚供电(USB协议要求);另外一路会传给88PM8607当成VSYS电压,而VSYS电压除了给系统供电外,还会产生VBAT电压给电池供电。当PXA955做为USB主设备时,此时ID首先会被拉低,如果从硬件电路图来看,此管脚是直接接在88PM8606 GPADC2上面的,此时88PM8606通过ID Pin的电压产生中断,在中断处理程序,USB PHY内部提供VBUS电压输出给88PM8606,此时88PM8606产生VBUS中断,并将此电压输出到USB Conn的VBUS上。Marvell PXA955 USB Gadget Device驱动分析PXA955 USB的代码均放在内核的drivers/usb/gagdet下面,其中关键文件如下表所示:文件名说明mv_gadget.cUSB Device端代码的核心部分。包括Gadget驱动的初始化,USB充电,USB连接状态的处理,USB相关服务的注册,USB中断处理,USB设备端的电源管理。android.c原生的Android USB代码。用来管理Android下USB复合设备,不同接口的功能函数的绑定的实现composite.cUSB复合设备相关代码。包括根据功能的不同,为配置添加接口函数,为设备添加配置,为不同的接口分配唯一的接口ID,组装配置描述符等,这个文件中包含了USB枚举的实现代码。USB复合设备切换的实现代码。f_adb.cUSB复合设备功能之ADB实现代码f_mass_storage.cUSB复合设备功能之U盘实现代码f_rndis.cUSB复合设备功能之以太网实现代码f_acm.cUSB复合设备功能之USB转串口实现代码f_diag.cUSB复合设备功能之DIAG通信实现代码一、USB Battery相关二、USB Gadget初始化USB的初始化首先是控制器的初始化,这个过程是在pxa9xx_otg.c中完成的。1. mv_gadget.c - mv_usb_gadget_probe()代码流程如下所示:在这个接口中,首先是创建了一个设备结构体:/* alloc, and start init */ mv_dev = kmalloc (sizeof(struct mv_usb_dev), GFP_KERNEL); if (mv_dev = NULL) printk(KERN_ERR mv_dev_load: malloc failedn); return -ENOMEM; 而这个函数的工作主要也是给这个结构体进行初始化,包括以下几个方面:(1)gadget驱动接口的初始化,Gadget驱动通过这些接口来访问硬件层代码(2)时钟的初始化(3)中断的初始化(4)底层设备控制器芯片的初始化(5)通信传输描述符(dTD和XD)队列的初始化(6)设定当前USB Gadget的状态(自给供电,并禁止远程唤醒)(7)注册各种操作服务(总线复位,设备休眠唤醒,端点数据传输等)(8)Vbus状态检测初始化(9)初始化设定充电电流等待队列(10)创建uevent节点并在sys文件系统中创建相关节点。2. android.c android_probe()代码流程如下所示:这里主要是对此复合设备进行初始化。 struct android_usb_platform_data *pdata = pdev-dev.platform_data;struct android_dev *dev = _android_dev;。dev-products = pdata-products;dev-num_products = pdata-num_products;dev-functions = pdata-functions;dev-num_functions = pdata-num_functions;if (pdata-vendor_id)device_desc.idVendor =_constant_cpu_to_le16(pdata-vendor_id);if (pdata-product_id) dev-product_id = pdata-product_id;device_desc.idProduct = _constant_cpu_to_le16(pdata-product_id);if (pdata-version)dev-version = pdata-version;return usb_composite_register(&android_usb_driver);在这段代码中,给出了一个很重要的结构体_android_dev,它保存了USB复合设备的基本信息,包括VID,PID,复合设备功能组合编号,当前所用到的功能搭配。当初始化完毕后,就正式的将此复合设备进行注册。3. composite.c usb_composite_register()代码流程如下所示:if (!driver-name)driver-name = composite;composite_driver.function = (char *) driver-name;composite_ = driver-name;composite = driver;driver-class = class_create(THIS_MODULE, usb_composite);if (IS_ERR(driver-class)return PTR_ERR(driver-class);return usb_gadget_register_driver(&composite_driver);这个函数主要通过复合驱动框架来注册一个复合设备,然后将此设备再以gadget的形式进行注册,如果注册成功的话,gadget驱动将会准备好接收来自主机端的请求。4. mv_gadget.c - usb_gadget_register_driver()代码流程如下所示:首先对mv_dev结构体的driver成员变量进行赋值,并将此设备添加到sys设备体系中。 /* first hook up the driver . */ mv_dev-driver = driver; mv_dev-gadget.dev.driver = &driver-driver;retval = device_add (&mv_dev-gadget.dev);if (retval) mv_dev-driver = NULL; mv_dev-gadget.dev.driver = NULL;return retval;再通过调用bind函数,将接口添加到当前的配置当中去。 retval = driver-bind (&mv_dev-gadget); if (retval) dev_dbg(mv_dev-dev, bind to driver %s - %dn, , retval); mv_dev-driver = 0; mv_dev-gadget.dev.driver = 0; return retval;注册中断,用来处理OTG控制器产生的中断。/* request_irq */if (request_irq (IRQ_USB_CTRLdev_no, mv_usb_dev_irq, IRQF_SHARED, driver_name, mv_dev) != 0) printk(KERN_ERR %s register: request interrupt %d failedn, , IRQ_USB_CTRLdev_no); return -EBUSY; 使能PMIC VBUS电平检测,并注册电平变化处理函数。#ifdef CONFIG_PLAT_PXA#if defined(ENABLE_CABLE_DETECT)if (mv_dev-info-vbus_detect) mv_dev-info-vbus_detect(mv_usb_vbus_change, 1);pxa3xx_pmic_set_pump(1);#else_usb_device_start(mv_dev-mv_usb_handle);mv_usb_start_ep0(mv_dev);#endif#endif最后将USB状态设为设备态。#ifdef CONFIG_USB_OTG if (mv_dev-transceiver) otg_set_peripheral(mv_dev-transceiver, &mv_dev-gadget);#endif二、USB复合设备功能目前USB设备功能包括以下五种:ADB, RNDIS, DIAG, USB_MASS_STORAGE, ACM其各自的实现代码分别在:f_adb.c f_rndis.c f_diag.c f_mass_storage.c f_acm.c虽然他们的功能不尽相同,但是从代码结构来讲,大同小异,下面就以f_diag.c为例,讲一下USB复合设备功能的代码。在这份代码中,需要注意以下几个接口函数:首先看下DIAG的初始化:static int _init init(void)printk(KERN_INFO f_diag initn);android_register_function(&diag_function);return 0;在这里有一个很关键的结构体:static struct android_usb_function diag_function = .name = diag,.bind_config = diag_function_bind_config,;int diag_function_bind_config(struct usb_configuration *c)int ret = diag_bind_config(c, 0);if (ret = 0)diag_serial_setup(c-cdev-gadget, 1);return ret;在函数diag_function_bind_config()中,首先调用diag_bind_config这个函数,目的就是为当前配置添加一个接口,并注册一些功能回调函数。(1)static int diag_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl)在USB枚举过程中,主机会向设备发送一些标准请求,要求设备返回指定的数据包或执行相应的动作,在这个过程中,根据设备类型的不一样,除了公有的setup处理函数以外,每一个接口可能需要单独进行setup,此时就会调用到这个函数。(2)static int diag_set_alt(struct usb_function *f, unsigned intf, unsigned alt)在USB设备枚举过程中,当设备收到主机发送的USB_REQ_SET_CONFIGURATION标准请求后,就会依次调用每个接口各自的set_alt接口函数,完成每个接口的初始化,在diag接口中,主要是根据当前设备的速度,为接口选择不同的端点描述符,并使能端口。(3)static void diag_disable(struct usb_function *f)取消diag功能,并断开端口。(4)static void diag_set_first_interfrace(struct usb_function *f, unsigned intf)在USB枚举过程中,每一个接口都需要分配一个ID,但如果接口ID为动态分配的话,此接口才会有效,会根据当前处于激活状态接口的个数来分配ID,否则此函数将不会被调用,

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论