![]() 图3两种U盘的Mode sense命令返回参数 以上两种方式均在硬件平台上成功实现。比较可知,方案一采取简单的破坏数据输出的方式,实现起来相对容易,但输出失败的数据势必会在下次自动重新试传,这样弹出错误窗口会有时间延迟,且对配置稍低的PC机而言,这种延时比较明显;方案二采取修改Mode sense返回参数的方式,直接将U盘设定为禁止写入的设备,这样在后续的数据传输时反应较快。考虑到实际使用效果,本设计选取第二种方案,本文也主要介绍基于该方案的实现。 2.2传输过程分析 USB总线采用差分传输方式,USB2.0共有4条线,分别是 ![]() 2.2.1 包和事务 USB2.0协议规定了四种传输类型,分别是控制传输、同步传输、批量传输和中断传输。数据在USB总线上传输的基本单位是包。不论何种包,都以同步域开始,紧跟着一个8位包标识符PID,最终以包结束符EOP结束。以数据包为例,它由一个同步域开始,紧跟着是PID,后面跟着n个字节的数据,然后是16位CRC校验码,最后是EOP。 ![]() 图4 数据包的结构 一个事务通常由两个或者三个包组成:令牌包、数据包和握手包。令牌包用来启动一个事务,总是由主机发送;数据包用于在主机和设备之间传输数据,传输方向由令牌包来指定;当接收方正确接收数据后,发送握手包。控制传输包括三个过程:建立过程、数据过程和状态过程,其中建立过程和状态过程分别是一个事务,数据过程则可能包含多个事务。 2.2.2 仅批量传输 在仅批量传输协议中,规定了数据传输的结构和过程,共分成三个阶段:命令阶段、数据阶段和状态阶段。命令阶段由主机通过批量端点发送一个CBW(命令块封包)的结构,在CBW中定义了要操作的命令以及传输数据的方向和数量。CBW的结构参见文献[4],其中dCBWSignature为CBW的标志,长度为32位,即0x55、0x53、0x42、0x43。当检测到一个包的起始序列为0x55、0x53、0x42、0x43时,即表明该包为CBW;另外,CBW中CBWCB表示需要执行的命令,若为0x1a,即表示Mode sense命令。 与CBW类似,命令状态封包CSW的结构参见文献[4],其标志dCSWSignature为0x55、0x53、0x42、0x53。 一次完整的仅批量传输过程如下:
对全速模式的USB2.0传输而言,每个包都由同步域开始,即连续的“00000001”二进制字符串,在数据传输中同步字符串是独特的,因此利用序列检测即可确定每个包的开始时刻。由于同步字节后即为一个字节的PID,同样利用序列检测到的PID即可确定该PID的类型,从而确定该包的作用。当确定该包为主机发送的令牌包后,则对下一个包的起始序列进行检测。若为CBW的起始序列0x55、0x53、0x42、0x43,则表明该包即为CBW。继续检测其第15字节的CBWCB,若为0x1a,即为Mode sense命令。在数据阶段的数据包开始后,从PID结束开始的第24位起将两根差分总线全部取反,直至包结束(EOP不能取反)。 2.3 Verilog HDL程序模块 利用Verilog HDL编程实现上述功能,首先按模块搭建框图。由于篇幅所限,在此仅给出程序框图,如图5所示。 ![]() 图5 Verilog HDL程序框架 3 测试 按图2所示,将一个原本可读写的普通U盘经USB总线控制器后转接到PC机USB接口上进行测试发现,对U盘中的文件均能够进行正常读取,且无法对U盘进行任何写入操作,说明该USB总线控制器很好的实现了其功能,达到了设计目的。将PC机文件数据输出的U盘涉及到的操作主要有:将PC机中文件复制到U盘中、修改U盘盘符、在U盘中创建新的文件、修改或重命名U盘中的文件、删除U盘中的文件等。 4 结语 基于CPLD的USB总线读写控制器从硬件上实现了数据从U盘向PC机的单向拷贝,同时自动阻止PC机中的文件以任何方式输出到U盘。对涉密单位而言,采用此设备,与传统的依靠光盘传递数据相比,不仅省去了刻盘的麻烦,也节约了成本。 |