USB设计
USB设计分硬件和软件两部分。硬件包括电路的设计和固件程序(Firmware)的编写,通常用汇编或C语言;软件分USB设备驱动程序和USB客户软件。
1.硬件
根据设备的需求和USB芯片的性能,设计出相应的电路在USB开发器的仿真板上进行仿真实验。固件的编写可采用分块的方法,比如Main模块、Interurrupt模块、Dtable模块、Vector模块、Timer模块、Declare模块等。通过编译进行连接以.hex文件的格式写到芯片里面去。仿真成功后即可直接应用于设备。
2.软件
(1)USB驱动程序接口
Windows98及2000通过允许USB设备驱动程序栈通信来支持USB。在USB驱动程序和USB驱动程序栈之间是USB驱动程序接口(USBDI),这种通信以WDM结构实现的。Usbhub.sys是USB集线器驱动程序。当Usbd.sys枚举每个USB主机控制器中的根结点集线器时被加载。Usbd.sys是类USB驱动程序。Uhcd.sys(通用主机控制驱动程序)以及Ohcd.sys(开放主机控制驱动程序)是USB主机控制器驱动程序。Hidclass.sys接收和发送到小驱动程序的HID报告。Hidusb.sys通过USB接收和发送HID报告。当检测到USB总线时,PCI枚举器加载USB栈驱动程序部分,并加载至少一个核心组件。
(2) USB驱动程序和USB客户程序
USB驱动程序的编写与硬件相关,属于核心模式。微软的DDK在这方面提供了较为详细的说明。比起VxD,WDM在硬件方面层次更为清楚和直观些。下面是一段驱动程序的入口函数:
NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath)
{
NTSTATUS status = STATUS_SUCCESS;
// Export other driver entry points...
DriverObject->DriverUnload = USBUnload;
DriverObject->MajorFunction[IRP_MJ_CREATE] = USBCreate;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = USBClose;
DriverObject->MajorFunction[IRP_MJ_READ] = USBRead;
DriverObject->MajorFunction[IRP_MJ_WRITE] = USBWrite;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = USBDeviceControl;
RegisterForPnpNotification(DriverObject);
return status;
}
USB的客户程序实际上是对客户端设备映像的操作,这些映像由USBD或HCD产生,属于用户模式。在DDK中存在着一组叫做USBDI函数的API函数集,该函数集包括了传输函数、管道(Pipe)函数、设备配置函数及其他函数。应用这些函数可编写支持任何USB兼容设备的USB驱动程序和客户程序。其中,管道(Pipe)是USB设备驱动程序建立的逻辑通信通道。
3.设计例程
笔者采用了原Anchor公司的EZ-USB AN2131-DK001,调试软件采用KeilPk51, 基于游戏操纵杆采用C语言和汇编语言相结合,创建一个关于HID设备的固件的工程,对其编译成功后进行连接/定位,用调试器调试后以16进制的形式加载在开发系统中进行仿真。控制方式上以中断方式为主,查询间隔为无穷大。由于是HID设备,不必去写相应的驱动程序,操作系统已经有了HID和Audio的驱动。
试验电路采用Anchor芯片的端口A进行LED的切换。
在主机方面,用VisualC++6.0写了一个应用程序,其访问设备通过GPD(General-purpose)和芯片进行通信。主要是以下三个函数:
·SetupDiGetClassDevs()
·SetupDiEnumDeviceInterfaces()
·SetupDiGetDeviceInterfaceDetail()
在固件方面,开发系统有两个固件文件PERIPH.C和FW.C包含了芯片的控制代码,笔者主要写了一些外设的查询代码。大部分情况下,采用汇编语言写固件要好一些。
将最后的编译好的.hex文件写到仿真板的EEPROM上进行测试,
达到预定的效果,为笔者下一步进行虚拟现实中的力反馈设备的研究提供了大量的经验基础。
USB设计是非常艰幸的一件事,需要设计者具有良好的软件和硬件知识。通常的设计周期为1年左右。