新闻中心

EEPW首页 > 嵌入式系统 > 设计应用 > VxWorks实时操作系统的USB驱动程序原理与分析

VxWorks实时操作系统的USB驱动程序原理与分析

作者:时间:2012-03-27来源:网络收藏


4.5 client回调(callback)任务

  USB操作是严格遵守时序的。例如为使中断传输和同步传输正确工作.需要依靠时钟中断。在一个有几个不同client出现的主系统中.总是有可能出现一个client打断其它client传输事件的发生。WindRiver USBD建议用client callback任务来解决这个问题。许多USB事件可以导致一个USB client的callback任务。例如, 每当USBD 完成USB IRP后,client的IRP callback函数被激活。同样,当USBD识别出一个动态连接事件后,会激活一个或更多的动态attach callback操作。但不是马上激活这些回调操作, 而是安排合适的相应的USBD client的回调任务来执行callback。

  一般的情况下,每一个client的callback任务处于“休眠”态(阻塞态)。每一个client的callback,继承了 usbdClientRegister()产生的任务优先级。这确保了每一个callback按其client的任务优先级来执行,而且可以利用优先级来写client,保证对时间要求严格的USB传输。由于每一个client有它自己的callback任务,因此在callback期间,它们有很大的灵活性决定可以做什么。例如,允许在不破坏USBD或其它USBD client性能的条件下,使callback执行代码运行至阻塞态。
  Client callback task有任务名:tUsbdCln。

4.6 USBD内部Client

  当第一次初始化USBD时,由USBD产生并注册一个内部client,以跟踪USB请求。

  USBD 可以产生什么类型的USB请求呢? 所有USBD与USB设备的传输,均利用调用USBD client的形式来完成。例如,当一个设备第一次连接到系统时.USBD用一个控制管道(control pipe) 自动地创建设备需要的所有的control pipe,即USBD client要用usbdPipeCreate()来创建一个与USB endpoint0通话的通道,然后所有USBD 内部、外部client通过这个管道来发送诸如usbdDescriptorGet()或usbdFeatureGet()等的函数,进行操作。

  所以,USBD 的一个机制就是USBD 循环利用它自己的entry point,而内部chent跟踪这些请求。

4.7 动态连接的注册

  每当一个特定类型的设备插入或拔出时,USBD client都通知上一层。利用调用usbdDynamicAttachRegister()操作,client可以指定一个callback操作,以便可以获取这样的通知。

  USB设备类型用class,subclass,protocol来区别。标准的USB 类在usb.h 中定义为USB_CLASS_XXXX。Subclass和protocol根据class来定义, 因此这些常数根据特定的class在头文件中定义。

  有时,一个client当利用usbdDynamicAttachRegister()进行注册时,只对特定的 class,subclass,protocol 感兴趣。例如,USB键盘类驱动usbkeyboardLib, 注册了Human Device Interface (HID) 类,subclass 是USB_SUBCLASS_HID_ BOOT,protocol是USB_PROTOCOL_HID_BOOT _KEYBOARD。通过callback机制的响应,每当一个设备完全符合这样的标准, 从设备上插入或拔出时,SBD便通知给keyboard class driver。而在其它情况下,client关注的范围更广泛了。常量USBD_NOTIFY(定义在usbdLib.h)可以替代任意的class, subclass,protocol。例如,USB打印机,usbPrinterLib,其class等于 USB_CLASS_PRINTER,subclass 等于USB_SUBCLASS_PRINTER (usbPrinter.h),protocol等于USBD_ NOTIFY_ ALL。典型的,当一个client只调用一次usbdDynamicAttachRegister()时,对一个client能拥有的并发通知请求数目没有限制。

4.8 Node ID

  USB设备一般用USBD_NODE_ID来区别。从其作用来看, USBD_ NODE_ ID 是USBD 用来跟踪一个设备的句柄。它与USB设备真正的USB地址无关。这表明client并不真正关心想要了解设备是物理上与哪一个USB主控制器相连。应用为每个设备抽象定义的Node ID, 使client可以不用考虑物理设备的连接细节以及USB地址分配, 并允许USBD 在其内部对这些进行详细的管理。

  当一个client通知有一个设备连接或断开时,USBD经常通过USBD_NODE_ID来定位设备。同样,当一个client想通过USBD与一个特定的设备通信时,它必须向USBD传递那个设备的USBD_NODE_ID。

4.9 总线编号(bus enumeration)操作

  usbdLib模块提供了usbdBusCountGet(),usbdRootNodeldGet(),usbdHubPortCountGet (),usbdNodldGet()操作。它们被一起称作总线编号操作。它们使USBD Client对连接到每一个主控制器上的设备进行编号。

  这些操作对于诊断程序和测试工具很有用,例如usbTool(WindRiver提供的一个测试工具)。但是,利用它们编号之后,调用者无法知道USB的拓扑结构是否变化。因此, 建议USB class driver的开发者不要用这些操作。

4.10 数据传输

  一旦client配置完成一个设备,就开始利用USBD提供的管道和传输功能与设备进行数据交换。传输种类(分为控制、块、中断和同步传输)用一个 USB_IRP数据结构来描述。 USB_IRP 的具体描述请参见HCD_FUNC_IRP_SUBM1T。USB数据传输被定位于每一个设备的特定endpoint。在USBD client和特定的设备endpoint之间的通道被称作管道(pipe)。每一个管道有以下若干特性:
  USBD_NODE_ID;
  设备的endpoim 数目;
  数据传输方向;
  带宽需求;
  延时需求。


  为了和设备交换数据,client必须先创建管道。作为结果,USBD得到了一个USBD_PIPE_HANDLE,它被用于随后对这个管道的所有client操作。

  当client企图创建一个管道时,USBD会检查是否有足够的可用带宽。对于中断和同步传输,带宽限制是必需的。USBD不允许把90%以上的可用带宽分配给中断和同步管道;而对于控制和块传输,则没有带宽的限制。同时,保证至少10%的带宽用于控制传输,对块传输则不保证会提供任何可用带宽。
数据传输的具体过程:

  (1)创建pipe :usbdPipeCreate(usbdClient Handle,nodeld,endpoint,configvalue,interface,  USB_XFRTYPE_BULK,USB_ DIR_OUT,maxPacketSize,0,0,outPipeHandle);
  (2)定义callback:ourlrpCallback(pvoid P);
  (3)初始化IRP的数据结构;
  (4)发送IRP:usbdTransfer(usbdChentHandle,outPipeHandle,&irp)。

5 、小结

  USB在VxWroks下的从下至上驱动栈分为HC、UCD、USBD和Client Module四层,每一层都相对独立,并为上一层提供了屏蔽该层次具体特征的接口。作者所说的,实际上主要在USBD这一层次上完成。具体分为 Chent注册,注销,创建pipe ,配置,数据发送,以及各回调函数。当正确地依次调用时,会根据回调函数的状态和返回值,按正确的时序进行完整的数据传输。

  上述设计思想构成了下USB设备应用的基础。作者的研究详细地分析了VxWorks的USB协议栈,证明了该方案的可行性,同时又给出了合理的实现方法。作为实践成果,作者已在VPN网关证书读取系统中,利用该思想编写的驱动,顺利读出存储在USB设备中的设备证书和管理员证书,且运行情况良好。作者认为,文中提到的模型完全可以胜任解决 USB设备在VxWorks下的应用所面临的技术难题。

linux操作系统文章专题:linux操作系统详解(linux不再难懂)

上一页 1 2 3 下一页

评论


相关推荐

技术专区

关闭