建立阶段结束后,主机就会执行数据阶段。PDIUSBD12等待接收控制输入包。单片机首先需要读取最后处理状态寄存器清零中断标志位。确认PDIUSBD12处于传输模式后,进行数据包的发送。
当下一个控制输入标志来到时,单片机将确定剩余的字节是否为零。如果已经没有数据要发送,单片机需要发送一个空的包以指示主机数据已经发送完毕。如果建立包的为获得描述符请求,那么建立包中的控制传输将指示此包为控制写类型。在执行完获得描述符请求过程后,单片机处于等待数据阶段。主机发送一个控制输出的标志,单片机从PDIUSBD12缓冲区内减去数据。此时单片机确认PDIUSBD12是否处于USB接收模式,然后单片机通过检查选择控制输出端点确认缓冲区是否已满,并将数据从缓冲区内读出。
4.6 标准请求处理程序
标准设备请求是由USB协议决定的,由主机发出,以数据包的形式传送到单片机。当单片机接收到这些标准设备请求时就转入相应的处理程序。其过程包括:①获取状态。②清除特性。③设置特性。④设置地址。⑤获取设备描述符。⑥设置配置。⑦获取配置信息。⑧获取接口信息。⑨设置接口。⑩同步帧。其中同步帧用来设置和报告一个端点的同步帧,在同步传输中才使用,如果设备不支持这个请求,返回停止标志。
4.7 主循环程序
主循环程序主要功能是设置单片机的初始化,以及设定各个相关子程序的入口。由于使用了中断服务程序和一系列的命令接口子程序,主循环程序中涉及USB接口的部分只是设定相关的寄存器。
5 USB驱动程序上位机部分
5.1 驱动程序基本概念
主机驱动程序的功能是将硬件与用户应用程序连接起来。编写的方法有多种,可以直接与硬件相连接,在应用程序中直接读写系统应将,或者将与硬件直接交换数据的底层工作交给操作系统自动完成,应用程序象读写普通文件一样完成对硬件设备的操作。前一种方法的代码开销少,但是编写的工作量非常大,移植性也较差。后一种方法需要大量库函数支持,但编写较为简单,且移植性好,甚至只需少许修改就可以完成对另一种硬件的支持。在本系统中使用的是由厂商提供的驱动程序,为了充分说明USB系统的工作,还是有必要对主机驱动程序的工作方式做一个介绍。
从驱动程序的角度出发,每个设备都被看成若干个设备对象,这些设备对象的来历各不相同,每个对象都有驱动程序与之对应。它们根据一定的规则组成设备对象堆栈,也就是对应的驱动程序堆栈。处于最底层的是物理设备对象,它一般由总线生成,驱动程序到达这里的时候,总线只是按照标准作一些动作,即可完成对设备物理上的操作。一个设备只能有一个物理设备对象,但可以有若干个其它的设备对象。功能设备对象是由所编写的驱动程序生成的,它负责从逻辑上操作设备。其它的层次设备对象可以处于功能设备对象的上面或下面,它由另一些驱动程序或者其它的系统组件生成,可以记录一些设备信息,但层次设备对象不是必须的。由于驱动程序的这种层次结构,在编写驱动程序的时候不必考虑内存分配、IO端口配置、DMA申请等。Windows将资源申请全部自动化,由总线完成,编写驱动程序时只要考虑控制设备本身即可。
5.2 即插即用设备状态及它们之间的转换
USB接口设备的一个显著特点就是接入或者拔出时不需要关闭主机和重新启动系统,而是可以在系统运行时直接插入或者拔出。这与USB接口的硬件设置有关,USB接口是通过检测接口上拉电阻来判别是否有设备存在的。当然,还必须有相应的驱动程序来完成对此功能的支持。下面就将简要描述一个设备完成即插即用的过程。
用户将设备插入计算机,此时设备还没有被系统检测到。要开始对设备进行软件配置,必须由即插即用管理器以及总线驱动对设备进行枚举。即插即用管理器,有时还可能要在用户模式下的组件工作,检测出设备的驱动程序,包括功能驱动程序以及其它的层次驱动程序。如果此时驱动程序尚未调入,则即插即用管理器调用设备插入例程。驱动程序完成初始化之后,接着必须对设备进行初始化。即插即用管理器调用驱动程序中添加设备的例程来初始化该驱动程序控制的每个设备。当一个驱动程序从即插即用管理器中收到开始设备的请求时,驱动程序使设备启动并且做好处理IO操作。在Windows2000及更高版本的操作系统中,和停止有关的请求只有在重新分配硬件资源的时候才会使用。意外卸载时是指硬件在物理上被卸载(热拔出),驱动程序处理这个请求使系统的损失尽可能降低。硬件卸载时,调用相应的卸载请求,使得该设备在软件上也不可用。如果不对意外卸载进行处理,就有可能造成硬件在物理意义上已不存在,但在系统逻辑中依然存在,造成系统访问该设备的时候出现错误,严重的情况可能会造成处理器进入死循环。当在软件意义上对设备进行停止时,需要等其它请求都操作完毕后才能进行。