目前,许多嵌入式系统的开发平台采用串行口作为调试和下载目标代码的接口。通用串行口的优点是简单易用,几乎所有嵌入式处理器都有1~2个串口。但是最大的缺点是速度太慢,这个缺点在开发小系统的时候还不太明显,随着代码尺寸的增加,串口的速度已经不能满足需要了。典型的如开发嵌入式Linux,编译后内核大小为400K~1M字节,通常还要制作一个ROM盘存放文件系统,采用115kbps波特率,下载1M字节数据就需要几分钟,在调试阶段还是太慢了,而且容易出错。虽然更新的开发系统可以采用JTAG等接口进行调试和下载,但下载大尺寸的文件依然是件耗时的工作。
考虑高速的数据接口,可采用以太网和USB。从速度上讲,10Mbps以太网和USB1.1(12Mbps)差不多。但使用以太网需要配置目标板的IP地址,需要连接集线器接入局域网,还需要PC机上运行TFTP的服务软件。相比之下,使用USB接口就简单多了:即插即用、自动识别设备、在Windows下使用浏览器就可直接传送文件。目前,新一代的嵌入式处理器很多都带有USB控制器。
采用USB接口的主要难点在于要求PC机上有相应的驱动程序的支持,USB的驱动程序以WDM(Windows驱动程序方式)为基础。这个问题对Windows98的确是个问题,由于Windows98只提供少数几种设备的驱动,对于大多数设备都要求USB设备的开发者自己编制。而编写驱动程序是件相当麻烦的工作。Windows2000 解决了这个问题,它提供各种USB设备的标准驱动程序,只要接入的设备符合标准,Windows2000可以自动识别设备类型并自动安装相应的驱动程序。开发者只需要编写USB设备的程序就可以了。
USB协议将设备分为几大类,每一大类又分为若干子类,分别满足不同场合的应用。每一大类都用一个类型号标识。如音频设备为01,人机界面设备为03,海量存储类为08。由于我们的目的是用USB传输大文件,可以将USB控制器配置为标准的海量存储类型,将嵌入式开发系统中的部分RAM虚拟为一个磁盘,在RAM盘开始的512字节按FAT表的格式填入数据。在PC机端利用Windows2000下的标准驱动程序,这样,我们的目标板将显示为Windows2000浏览器中的一个驱动器。驱动器的大小由RAM盘FAT表中的信息决定。用拷贝、粘贴命令可直接传送大文件。笔者用此方法开发基于ARM的嵌入式Linux,下载1M字节的Linux内核几乎感觉不到延时,下载6M字节的ROM 盘也只需要3秒,大大加快了开发速度。笔者的USB控制程序中还包括一段FLASH擦写程序,当下载文件结束后,可将下载内容写入FLASH中,重新启动系统后,就可以调试新下载的代码了。
图1 USB接口部分的原理图
硬件平台
笔者所用的开发系统硬件平台处理器为摩托罗拉公司的MC9328MX1(以下简称MX1),它是基于ARM核心MCU,主要面向高端嵌入式应用。内部采用ARM920T核,并集成了SDRAM、Flash、LCD、USB1.1、蓝牙、多媒体闪存卡、CCD摄像头等控制器。在笔者的系统中采用了两片16Mx16位的SDRAM和两片4Mx16位的同步Flash存储器,分别接入数据线的低16位和高16位。MX1的USB模块需要外接一片USB总线接口芯片完成电平转换和总线驱动,如飞利浦公司的PDIUSBP11AD。USB接口部分的原理图如图1所示。
软件平台
笔者的USB下载程序是为开发嵌入式Linux而设计的,程序用C编写。编译器采用GNU软件系统的ARM交*编译器。编译器、汇编器和连接器分别为arm-linux-gcc、arm-linux-as 和arm-linux-ld。编译环境可以用Red Hat Linux。如果觉得另外配置Linux服务器不方便,也可以用Windows下的虚拟Linux环境CYGWIN,这样所有的工作都可以在Windows下完成,但需要在CYGWIN中重新编译ARM交*编译器。有关GNU工具的使用请感兴趣的读者参考相关资料。
USB设备的工作原理
各种USB设备的工作过程在USB标准1.1中有详细的描述,在此简述如下:USB的传输方式分为4种:控制传输,批传输,中断传输和等时传输。控制传输用来传输设备控制指令、设备状态查询及确认命令。批传输主要用于完成主机和设备之间的大块数据传输,支持两个方面的数据传输(即主机到设备和设备到主机)。中断传输用来完成设备到主机的少量数据传输,只支持设备到主机方向数据传输。等时传输主要用来完成主机和设备之间实时数据的传输(如麦克风、音箱以及电话等)。USB传输事务均由主机启动,总线采取主从式结构,实际的通信过程由主机和设备的端点来完成。一个USB设备有多个端点,其中端点0专门用于设备的控制。端点被定义为单向的数据通道:只能为接收端点或发送端点。具有相同传输方式的多个收发端点组成通信界面。所有的通信过程都由主机控制,USB设备通过接收端点接收主机的各种请求,如读写数据、请求状态,通过发送端点对请求做出应答。在本例中,由于将USB设备配置为海量存储方式,只使用了两种传输方式:控制传输和批传输,定义了三个端点:除了端点0外,还定义了批传输的接收端点和发送端点。
不同类型的USB设备有不同的配置信息。主机将根据设备报告的初始化信息加载不同的驱动程序。通过初始化请求包,主机可要求设备报告五种配置信息:1. 设备描述表,2. 配置描述表,3. 界面描述表,4. 端点描述表,5.字串描述表。
USB设备必须向主机报告一个设备描述表和至少一个界面描述表。USB协议对不同设备类型的各种配置信息都有具体的规定,开发者可参考相应的文档。具体编程时,当收到主机的配置请求包后,只要将设备描述表和配置描述表发给主机就完成了配置过程。当配置过程完成后,主机和设备就可以传输数据了。
作为海量存储类设备的SCSI类,主机将以访问磁盘的方式来访问设备。所以,在使用前,我们需要按磁盘分区表(FAT表)的格式对一片RAM进行格式化。在本例中采用了FAT16的格式。本例中支持四种对RAM盘的操作:读/写磁盘扇区、查询磁盘大小和弹出设备。对于读/写操作,只需要将主机请求读/写的扇区数转换成为RAM盘的地址,将数据写入或读出就可以了。文件发送完毕后,在Windows 2000下选择弹出设备操作,设备收到后会终止USB连接。
图2 下载程序流程图
USB控制器
MX1的USB1.1控制器提供了6个端点,分别是端点0到5。除了端点0保留作控制外,端点1~5都可配置为中断、等时或批传输方式,支持全速12Mbps的传输速度和8、16、32、64字节的包长度。工作方式可选择查询、中断或DMA传输方式。
USB下载程序流程
用USB接口的下载程序流程如图2所示。
首先的工作是初始化USB控制器,包括设定USB时钟,配置端点0、1、2分别为控制、批传输接收、批传输发送端点。1、2端点数据包长度64字节。接下来需要对RAM盘进行格式化,填充引导扇区和FAT表。在笔者的系统中,划分了14M字节RAM作为RAM盘,共28672个扇区,可满足一般应用。配置过程结束后,主机会发命令要求设备报告容量,以扇区为单位,并读出RAM盘的引导扇区。拷贝过程结束后,在资源管理器的驱动器图标处击右键,选择弹出设备,设备收到命令后会终止USB连接,将RAM盘中的数据写入FLASH中,完成了程序代码下载和写入的过程。