Linux USB驱动框架分析

来源:互联网 发布:电子商务php 编辑:程序博客网 时间:2024/04/28 13:43

一 引言

随着微电子技术的不断创新和发展,嵌入计算系统(简称嵌入系统),作为计算机应用的一个重领域,已深入到社会的方方面面,越来越为人们关注。我们为某煤矿企业开发的监控系统作为一个智能分站,其系统就是采用嵌入式操作系统Windows CE.NET。

二 嵌入式操作系统

嵌入式系统是以应用为中心、以计算机技术为基础、软件硬件可裁剪、适应应用系统对功能、可靠性、成本、体积、功耗严格要求的专用计算机系统。嵌入式系统是面向用户、面向产品、面向应用的,它必须与具体应用相结合才会具有生命力、才更具有优势[2]。嵌入式系统以其小型、专用、易携带、可靠性高的特点,已经在工业控制领域得到了广泛的应用,如工业过程控制、远程监控、智能仪器仪表、机器人控制器、数控系统等。此外,由于嵌入式系统本身所具备的网络和人机交互的能力,使得它有可能取代以往基于微控制器的控制方式。我们所设计的这种智能分站主要运行在高温、高湿度震动较强的环境。普通PC体积大、工作温度范围较小、抗震性差,不能生产的特殊环境。单片机体积小巧,是一种可编辑部件。但是由于目前芯片集成水平的限制,单片机的功能十分单一,不能满足复杂工业控制的要求。嵌入式系统具有实时性、低成本和小型化,克服了传统的基于单片机控制系统功能不足和基于PC的控制系统非实时性的缺点,因此选用嵌入式系统来实现监控监测的智能分站。
Windows CE.NET 是微软推出的功能强大的嵌入式操作系统,该系统是一种紧凑、高效、可伸缩的32位的操作系统,主要面向各种嵌入式系统和产品。它所具有的多线程、多任务、完全抢占式的特点是专为各种有很严格资源限制的硬件系统所设计的。
由于此煤矿系统需要长时间运行,而其内部的应用程序随需求的不同以及环境的变化,需要定期更换,一般的大型系统要求更换应用程序时不能关掉系统,因此应用即插即用的USB设备是必须的,开发USB驱动就在所难免。
以下就通过开发Windows CE.NET 的USB驱动程序,来介绍如何开发嵌入式操作系统中的USB驱动程序。

三 驱动程序开发

1 Windows CE.NET 的USB系统软件结构
Windows CE.NET 的USB系统软件分为两层: USB Client设备驱动程序和底层的Windows CE实现的函数层。USB设备驱动程序主要负责利用系统提供的底层接口配置设备,和设备进行通讯。底层的函数体本身又由两部分组成,通用串行总线驱动程序(USBD)模块和较低的主控制器驱动程序(HCD)模块。HCD负责最最底层的处理,USBD模块实现较高的USBD函数接口。

2 利用USBD接口函数实现驱动程序和外围设备的交互
USB设备驱动主要利用USBD接口函数和他们的外围设备打交道。USB接口函数主要包括传输、管道、框架和配置函数,同时也包括执行其他功能的多任务函数。

主要的传输函数有: AbourtTransfer、IssueControlTransfer、CloseTransfer、IssueInterrupTransfer、GetIsochResult、IssueIsochTransfer、transferComplete、GetTransferStatus、IsIssueBulkTransfer、IssueVendorTransfer
取得设置设备配置函数:ClearFeature、SetDescriptor、GetDescriptor、SetFeature、GetInterface、SyncFrame、SetInterface、GetStatus

传输函数主要处理USB设备数据发送和接收,它是最重要的一类函数。所有的传输函数都有一个对应可选的回调函数。应当注意的是USBD模块调用回调函数有可能会影响其他的USB操作,解决这一问题的主要方法就是设置一些状态变量和标志,通过上述方法的处理就可以采用多线程来处理所有滞后的处理过程。

上面列出了用到的主要函数,在编程过程中可能还会用到其他函数进行传输、设置等操作,采用何种函数以及具体函数的用法可通过帮助文件获得。

3 设置驱动程序要求的入口点
入口点的设置是为了实现USB驱动程序和USBD之间的交互,我们在动态连接库中设置入口点。入口点主要有两个作用:
(1) 使得USBD模块能与外部设备交互;
(2) 使得驱动程序能创建和管理任何可能需要的注册键。
      USB设备驱动程序要求的入口点的相关函数有:
(1)USBDeviecAttach
    当USB设备连接到计算机上时,USBD模块就会调用此函数,这个函数主要用于初始化USB设备,取得USB设备信息,配置USB设备,并且申请必需的资源。
USBDeviceAttach()函数的基本定义如下:

USBDeviceAttach(
USB_HANDLE hDevice, // USB设备句柄
LPCUSB_FUNCS lpUsbFuncs, // USBDI的函数集合
LPCUSB_INTERFACE lpInterface, // 设备接口描述信息
LPCWSTR szUniqueDriverId, // 设备ID描述字符串。
LPBOOL fAcceptControl, // 返回TRUE,标识我们可以控制此设备,反之表示不能控制

(2)USBInstallDriver
主要用于创建一个驱动程序加载所需的注册表信息,例如读写超时,设备名称等。一些基本定义如下:

const WCHAR gcszRegisterClientDriverId[]= L"RegisterClientDriverID";
const WCHAR gcszRegisterClientSettings[]= L"RegisterClientSettings";
const WCHAR gcszUnRegisterClientDriverId[]= L"UnRegisterClientDriverID";
const WCHAR gcszUnRegisterClientSettings[]= L"UnRegisterClientSettings";
const WCHAR gcszMouseDriverId[]= L"Generic_Sample_Mouse_Driver";

(3)USBUninstallDriver
主要用于释放驱动程序所占用的
资源,以及删除USBInstallDriver函数
创建的注册表等。 一些代码如下:

DriverSettings.dwDeviceClass= USB_NO_INFO;
DriverSettings.dwDeviceSubClass= USB_NO_INFO;
DriverSettings.dwDeviceProtocol= USB_NO_INFO;
DriverSettings.dwInterfaceClass= 0x03; // HID
DriverSettings.dwInterfaceSubClass = 0x01; // boot device
DriverSettings.dwInterfaceProtocol = 0x02; // mouse

上述的三个函数接口是所有的USB驱动程序必须提供的,缺一不可。

4 设置驱动程序的注册键
      此外比较重要的是USB设备驱动程序的注册表配置,一般的USB设备驱动程序的注册表配置在HKEY_LOCAL_MACHINE/Drivers/USB/LoadClients下,每个驱动程序的子键都有Group1_ID/Group2_ID/Group3_ID/DriverName格式,如果注册表信息与USB设备信息符合,USBD就会加载此驱动程序。
      主要的任务函数有:

RegisterClientDeviceId、
RegisterClientSettings、
RegisterNotificationRoutine、OpenClientRegisterKey、
UnRegisterNotificationRoutine、RegisterClientDriverID

注册键主要控制驱动程序的加载方式。USBD通过跟踪注册键来加载正确的驱动程序,这种依赖于设备控制范围的驱动程序加载方法,提供了灵活的结构,它使得在不同情形下加载相应驱动程序称为可能。需要注意的是:USB设备驱动程序不使用标准的注册表函数,而是使用RegisterClientDriverID()和RegisterClientSettings来注册相应的设备信息。

另外的函数有USBUninstallDriver()函数,此函数主要用于删除USBInstallDriver()时创建的注册表信息,同样的它使用自己的函数接口UnRegisterClientDriverID()和UnRegisterClientSettings()来做相应的处理。

最后一个需要处理的是注册监控通知函数USBDeviceNotifications()。主要包含删除相关的资源,中断处理函数,数据接受缓冲区等的编写。

5 USB驱动程序的加载
驱动程序编写完以后,需要正确的安装USB驱动设备,这就要求正确的设置HKEY_LOCAL_MACHINE/Drives/USB/LoaClients下的子键,然后就可以正确的加载USB驱动程序了。

四 结束语

随着嵌入式操作系统越来越被广泛应用,在嵌入式系统中编写驱动受到重视。USB设备的控制、管理和信息交换完全是由系统软件按USB协议进行传输的,不占用主机的硬件资源(如I/O地址、内存、中断、DMA等),具有很高的传输可靠性和兼容性。USB的这些特性使得它在嵌入式系统领域将会得到更广泛的应用。