控制输出入口 读端点处理状态 清中断标志 NO NO 建立包? 处于接收状态 Yes Yes 读取断电数据并保 读取端点数据并保存 NO NO 接收完接收数据出错 Yes 毕 ? Yes 设置为等待状态 对控制输入端点和控制输设置建立包标志 出断电进行建立数据对应设置发送NO 状态,设置读取要求? 建立包标志标志 Yes NO 设置等待带数据的要求: 状态,设置建立包标Yes 停止控制端点 NO 志标志 数据长度出错 设置为等待状态 Yes 设置等待状态 设置等待状态 子程序结束 图12 控制输出处理流程
数据的长度并把数据读出,然后设置收到数据标志位bEPPflag。
21
对于普通输入端点的中断,只要读取端点号的最后处理状态寄存器来消除中断寄存器的相应位,把状态清零就可以了。Generic_ In标志是在发送完数据后才产生的,当还有数据要发送时可以在中断程序里接着继续发。注意:这里的数据发送完成标志是指在主机的一个有效的IN事务后才发生的。当主机发出IN事务而设备没有送出数据时,是不会产生中断的。
4.1.6 主循环--MAINLOOP.C
MCU一旦上电就需要初始化其所有端口、存储区、定时器和中断服务程序。之后MCU将重新连接USB,包括将Soft_ Connect寄存器设置为ON。这些过程是很重要的,因为它确保了在MCU准备好服务D12之前D12不会进行操作。
在主循环程序中MCU对键盘进行轮询。如果任何一个特定的按键被按下,键处理命令将执行子程序并返回主循环。增加该子程序的目的仅仅是为了调试。1ms定时器用于激活该子程序以检测在评估板上的任何按键。当轮询到了检测建立包时,它确认建立标志在之前是否被中断服务程序所置位。如果建立标志置位,它将向协议层发送一个器件请求进行处理。下面所示的流程图13是主程序在前台执行的流程。
4.1.7 PDISBD12固件编程的关键注意事项
(1)在编写PDIUSBDI2固件程序时需要注意:
[1]单片机的中断应设置为电平触发:中断后一定要读上次传输状态寄存器(命令40-45H),以清除中断寄存器中的中断标志。这样,PDIUSBD12的中断输出才能变回高电平。这一点非常重要。 [2]在接收到Setup包后,一定要调用ACK setup命令重新使能端口0。 [3]在向IN端点写完数据后,一定要调用Vali date Buffer(命令FAH ), 指明缓冲区中的数据有效,可以发送到主机。
[4]读完数据后,一定要调用Clear Buffer(命令F2H),以保证可以接收新 的包。
[5]可以通过调用Read Chip ID(命令FDH)检查PDIUSBDI2是否工作。该 命令要读两个字节数据。
22
Main Loop 初始化I/O口、定时器和中断,重新连接到USB总线 循环 No 定时器事件标志? Yes 更新LED状态采集按键状态 No 总线复位? No 挂起改变? No 建立包? Yes 总线复位处理 Yes 挂起改变处理 Yes 调用协议处理程序
图13 主循环流程图
(2)USB初始化过程为: [1] Set Address Enable;
[2] Set Endpoint Enable(此时LED亮); [3] Disconnect; [4]delay(1-2 s);
[5] Connect(即用43h参数调用Set Mode,此时LED灭); [6]Read Interrupt Register;
完成初始化工作后就可作其它的前台工作了,并在前台判断是否有Setup包(通过一个变量,当中断服务程序检测到有Setup包时,设置该变量),然后执 行响应的控制传输。
23
4.2 USB设备驱动程序的开发
USB总线设备驱动程序必须遵循由Microsoft为Windows 98及其以后版本所定义的Win32驱动程序模型。这些驱动程序就是WDM(Windows Driver Model),
其扩展名一般为.sys(当然其他文件类型也可以使用.sys扩展名)。它与VXD和NT式的驱动程序不同,它是内核态程序,采用了分层处理的方式,不需要直接和硬件打交道。
与其它的低层驱动程序一样,WDM驱动程序负责在一个特权层实现应用程序与操作系统的通信。一个WDM驱动程序可以允许或者否定一个应用程序对一个设备提出的访问。例如,一个游戏杆的驱动程序可以允许任一个应用程序来使用个游戏杆,或者它可以为某个应用程序保留以供独立使用。Windows为其他低层设备驱动程序和WDM驱动程序所保留的能力还包括对硬件中断的响应和DMA传输。
设计WDM设备驱动程序模型是为了给运行在Win 98及其以后版本(包括
Windows 2000系统)下的任一设备提供一个通用的驱动程序模型。WDM定义了一个基本模型处理所有类型的数据。例如,USB总线类驱动程序为所有USB总线设备提供了一个抽象的模型,并具有由所有客户驱动程序预先定义的接口。有了对所有设备类型都相同的核心驱动程序模型,驱动程序开发就可以更容易地从一种类型的设备转移到另一种类型的设备上去,这也意味着驱动程序模型的内核实现可以是固定的。如果每一种类型的设备都具有不同类型的驱动程序模 型,那么开发工作无疑会变的很繁琐。
WDM驱动程序由两种工作模式,即内核模式和用户模式。
(1)内核模式:当CPU运行于内核模式时,一切程序的指令都可以运行,即所
运行的程序没有任何操作系统的限制。任务可以运行特权级指令,对任何I/O设备有全部的访问权,还能够访问任何虚地址和控制虚拟内存硬盘。这种模式对应于Intel 80x86处理器上0级环。
(2)用户模式:在这个模式中,硬件可以防止特权级指令的执行,并进行内存和I/空间引用的检查,这就需要操作系统限制执行的任务对各种I/O操作进行访问,并捕捉违反系统完整的行为。在用户模式中,如果运行的代码不通过操作系统中的某种机制,就不能进入内核模式。在Intel 80x86处理器上,该模式对应于3级环。
USB驱动程序的设计实现了类设备驱动程序,它把一类有相似属性和提供相似
功能服务的设备都定义到一个给定的设备类中,这些常用的设备类拥有一个通用的类设备驱动程序,该驱动程序为所有这个类别的设备提供驱动,这个类定义为主机和客户软件提供了使用的信息,以确定一个设备如何被访问和控制。常见的设备类有:HID设备类、通信设备类、监视设备类、物理反
24
馈设备类、打印机类、集线器类、海量存储设备类和音频设备类等。
USB总线设备驱动程序使用标准Windows系统USB类驱动程序访问USBDI(USB驱动程序接口)。USBD.sys文件就是Windows系统中的USB类驱动程序,它使用UHCD.sys来访问通用的主控制器接口设备,或使用OHCI.sys访问开放式主控制器接口设备。USBHUB.sys是根集线器和外部集线器的USB总线驱动程序。
4.2.1 驱动程序开发工具的介绍
Windows DDK Windows DDK是Microsoft公司提供的一个开发Windows驱动程序的工具,是Microsoft出品的设备驱动程序开发工具包DDK(Device Developer Kit),它有Windows98 DDK和Windows2000 DDK两个版本。前者能够开发Windows95/98/Me/NT下的VxD, KMD和WDM驱动程序,后者可以开发Windows98/Me/NT/2000下的KMD和WDM驱动程序。利用DDK开发Windows驱动程序是一种比较传统的方法。
它要求设计者必须对Windows的体系结构、设备驱动程序的结构、虚拟机管理器(VMM)以及Intel CPU体系结构有深入的了解,而且需要保护模式的汇编语言编程经验。因此,在实际的开发过程中,DDK一般不常被人们所使用,取而代之的是另外两种工具:DriverStudio和WinDriver
DriverStudio是由Compuware公司提供的驱动程序开发工具,简化了Windows驱动程序的开发、调试和测试,完整的版本是由SoftICE , DriverWorks ,
DriverNetWorks、VtoolsD, BoundsChecker, TrueTime Driver, TrueCoverage Driver等工具组成。 WinDriver是美国KRFTech公司出品的用于编写驱动程序的另一种工具包。它包括代码生成器WinDriver Wizard, WinDriver Debugging Monitor, WinDriver发行包和一些公用程序和实例。WinDriver支持ISA, EISA, PCI, Plug&Play和DMA,它能自动地发现硬件并产生驱动程序,不需要牵涉到很低层的东西即可在很短的时间里编出驱动程序。使用WinDriver的优点是:开发者并不需要熟悉任何内部操作系统或kernel programming或DDK及任何驱动程式。WinDriver同时允许开发者能在自己所熟悉的开发环境下,利用使用者模式(User Mode)来开发出所需的驱动程序,如使用MSDEV Visual C/C++, Borland C++Builder, Delphi或任何Win32编译器。使用WinDriver所开发的驱动程式均可用于Windows XP, Windows 9x, NT/2000, CE, Linux and Solaris等平台。
4.2.2 驱动程序中的基本概念
驱动程序的五层模型
25