业界动态

USB接口技术在嵌入式系统中的应用研究

作者:余修武1,2, 刘 岚2
发布日期:2009-04-13

  摘  要: 简单介绍了USB接口技术的原理及其优点。基于嵌入式系统与USB设备等不能直接传输数据及嵌入式系统大容量存储难等问题的现状,提出了在嵌入式系统中集成USB Host功能以解决这一问题。
  关键词: USB接口; 嵌入式系统; USB—Host;SL811HS

 

  随着测控技术及嵌入式系统应用的迅速发展,数据量越来越大,对数据传输速度要求越来越高,并且要求高可靠性、稳定性和极好的移动性,能够方便快捷地将数据传送至处理中心进行处理控制等。而通用串行总线(USB)具有即插即用、热插拔、易扩展和高传输速率等优点,人们希望USB能应用在移动数据交换等没有PC机的领域中。而在非PC机应用领域,这正是USB的一个致命弱点。USB的拓扑结构中居于核心地位的是主机(Host),任何一次USB的数据传输都必须由主机来发起和控制,所有的USB设备都只能和主机建立连接,任何两个外设之间或是两个主机之间都无法直接通信[1]。目前,大量扮演主机角色的是个人电脑(PC),所买到和使用的USB移动设备都是USB的设备,如USB的移动硬盘、USB接口的数码相机等等。所有这些设备都只能在PC机上使用,只能通过PC机来进行相互的文件和数据交换。没有PC机,这些设备就“失灵”了(就数据交换的功能而言)。因此,USB接口技术在嵌入式领域中的应用就成了USB领域新的研究焦点。解决这一问题的根本办法就是在嵌入式系统中集成USB Host功能,使之具有与USB Slave设备进行数据传输的能力。具有主机功能的嵌入式设备可读写U盘,对于数据采集、存储更加方便,更适合野外设备或长期运行设备的数据采集。
1 USB接口硬件设计
1.1 系统硬件的总体结构

  USB技术规范将使用USB进行数据传输的双方划分为两种角色[2]:Host机和Slave机,并且规定,数据传输只能发生在Host机和Slave机之间。要将实现USB Slave 的USB 接口的数字设备应用于嵌入式系统中,就要在嵌入式系统中集成USB Host 功能模块,使之具有与USB Slave 设备进行数据传输的能力,图1所示为系统总体结构。

 

 

1.2 USB Host模块硬件连接
  USB Host 功能模块硬件连接如图2所示。CPU选用与MCS-51系列单片机完全兼容的Dalla 8公司的80C320 单片机,而且运行速度在同样晶振频率下比80C32平均高2.5倍,最高工作频率可达33MHz。USB主机接口芯片选用SL811HS。

 


1.3 SL811HS
  SL811HS[3]是Cypress公司推出的遵从USB1.1协议的专用于嵌入式系统USB主控制器(Host /Slave)芯片,由主/从控制器模块、RAM缓存及控制寄存器模块、串行接口引擎SIE等模块组成。其中,SIE模块负责完成USB总线与主机之间数据的串、并转换等功能;RAM缓存用于数据缓存,它和控制寄存器(占前16B)的空间为00H~FFH,共256B。SL811HS的功能框如图3所示。

 


  该芯片既能与USB低速设备进行通信,也能与USB高速设备进行通信[4]。由于提供了8bit 宽数据总线及中断支持,使得该芯片能方便地与一般的单片机、DSP等控制器进行通信,并受到CPU的控制。其特点主要有:能通过硬件设置或软件设置的方法使该芯片工作在Host或Slave模式;自动探测所连接的设备是低速设备还是高速设备;8bit双向数据总线;片上SIE、USB收发器;自动产生SOF令牌包,以及自动生成令牌包、数据包中所需要的CRC5/CRC16数据;内部256B RAM,支持乒乓操作;支持SUSPEND/RESUME、WAKE UP、LOW-POWER模式。
2 USB接口软件设计
2.1 接口固件设计

  USB Host模块设计中最困难的就是固件(Firmware)设计,固件编程要遵循复杂的USB规范,所以比硬件设计工作量大得多。该模块固件程序主要由如下部分组成:对SL811HS进行设置的初始化程序,这部分程序在系统复位后就立刻执行;发现USB设备接入的子程序,并判断该设备是高速还是低速设备;对该USB设备进行Enumerate,即枚举,并指定其USB地址的子程序;其他数据通信子程序利用该部分程序完成指定的应用要求[5]。USB传输函数usbXfer程序流程如图4所示。

 


  以包为基础,USB定义的4种数据传输类型所能达到的传输速度、占用USB总线的带宽、传输数据的总量和应用场合等都是不同的。每种传输方式都由很多个事务来完成。USB事务处理一般由三个阶段组成:令牌阶段、数据阶段和握手阶段。令牌阶段定义了事务处理的类型,包括SETUP、IN 和OUT;数据阶段负责运送和传输相关的数据,Data0 和Data1两种数据包交替使用,以支持双方的传输同步;握手阶段由接收方向发送方提供反馈,告知数据是否正确接收。
  在USB Host 模块中,固件的核心部分是USB传输函数usbXfer。usbXfer管理着USB的事务处理,其入口参数有:设备地址UsbAddr 、端点地址Endpoint、令牌包类型PID、端点最大负荷Payload、传输数据总长度Length 、数据缓存区指针Buffer。
  USB主机检测到设备连接好后要对其进行配置,称为设备的枚举,该部分固件的核心是设备请求函数VendorCmd。VendorCmd构建在usbXfer函数之上,通过调用usbXfer进行若干次的控制传输来实现。控制传输的实现是固件程序中一个比较复杂的部分。控制传输由三个阶段组成:建立阶段、数据阶段和状态阶段。建立阶段,主机进行SETUP事务处理,向目标设备发送标准设备请求;数据阶段,由若干个IN事务处理或OUT事务处理组成;状态阶段,主机则完成与数据阶段相反的事务处理,结束本次控制传输。
  设备的枚举过程主要包括以下几个步骤:(1)主机请求设备控制端点0,以确定缺省管道支持的最大数据量;(2)主机给USB设备分配1个唯一的地址;(3)主机从描述符中读取配置信息并加以执行;(4)主机验证设备所需要的资源是否可以获得;(5)主机USB设备发送1个配置值,指出如何使用该设备。枚举成功后,主机和设备就可根据设备接口类型,采用相应的接口协议进行数据控制和传输。USB设备类型主要划分为:音频设备、显示设备、人机接口、海量存储器等。特定的设备类型又划分为若干个子类,它们又有可能采用不同的接口协议传输指令和数据。以U盘为例,类代码08h(海量存储器类),子类代码06h(SCSI指令集子类),传输协议50h(Bulk—Only传输协议)。按照这些标准,U盘的操作过程可分为:指令、数据和状态三个阶段,也就是主机首先向设备Bulk—Out端点写包含SCSI的指令块(CBW);然后从Bulk—In读数据或向Bulk—Out端点写数据;最后从Bulk—In端点读取传输状态(CSW)。通过Mass Storage类的子类命令的实现,在建立了FAT文件系统后,该文件系统就可以直接调用子类命令对U盘进行各种操作,以实现对文件的管理。
2.2  驱动程序设计
  主机控制器驱动程序设计主要包括四个部分:主机控制器的初始化和管理、传输执行和资源的调配、中断处理以及根集线器操作和控制。主机控制器为USB总线驱动屏蔽了硬件操作,完成USB底层数据传输,它为上层驱动提供了简单的软件接口,定义了usb_ operation函数结构体供USB总线调度调用。
  Struct usb_ operations {
  int ( * allocate) (struct usb_device * );   
                     // 分配USB设备资源
  int ( * deallocae) (struct usb_device * );
                     // 收回USB设备资源
  int ( * get_frame_number)(struct usb_device * usb_dev); 
                      // 获得当前帧号
  int ( * submit_urb) (struct urb * purb);
                      // 提交URB请求块
  int ( * unlink_urb) (struct urb * purb);
                      // 撤销URB请求块
   };
  函数调用涉及两个不同数据结构的变量,其中,usb_device包含了对设备地址、描述表、配置、端点等基本设备信息;urb说明了USB总线请求的基本信息,包括USB通道信息、数据缓冲区、带宽和完成处理函数等。USB总线上所有的交易都是由函数submit_urb( )发起的。主机控制器驱动程序基本流程如图5所示。

 


  由于USB总线的通用操作如USB设备枚举、具体数据传输等已经由主机控制器驱动程序完成了,所以主机端设备驱动程序这部分的驱动程序只需要完成与具体设备相关的操作即可。USB设备驱动程序首先要做的是向Linux内核注册它自己,并告诉系统它所支持的设备类型以及它所支持的操作。这些信息通过usb_driver结构来传递。
  struct usb_driver usb_storage_driver = {
  name:  “usb-storage”,            // 驱动程序的名字
  probe: storage_probe,          // 函数指针
  disconnect:  storage_disconnect,   // 函数指针
  id_table:  storage_usb_ids,        // 保存设备厂商ID和产品ID
  };
  usb_device是程序中一个重要的数据结构,驱动程序在设备探测阶段可通过它获得设备的相关配置信息。当一个设备插入USB总线时,主机对设备进行总线枚举,完成对设备的配置并读入设备属性。相关属性如设备描述符、配置描述符等信息被主机控制器保存在usb_device结构中。然后,内核根据设备标志找到对应的驱动程序,并调用该驱动程序的storage_probe( )函数。usb_device结构被作为参数传入该函数。驱动函数的注册和注销都比较简单,注册时只需要将usb_storage_driver结构作为参数传递给usb_register( )函数即可,usb_register(&usb_storage_driver)注销类usb_deregister(&usb_storage_driver)、Storage_disconnect( )在设备被卸载时被调用。
2.3 用户程序设计
  用户程序是系统与用户的接口,通过通用驱动程序来完成对外设的控制和通信。在编写用户程序时,首先建立与外设的连接,然后再实施数据的传输。本设计使用VisualC++6.0编译环境,将API函数包装成一个USB.DLL连接库程序文件,其编程方法与串口编程类似:首先查找设备,打开设备的句柄,然后进行读写和控制操作,最后关闭设备句柄。在VC动态链接库中需将以下函数进行封装:
  __declspec(dllexport)int__stdcall  EzBulk_ DataOut(uns I gned  char*DataOut,int  DataOutLen);
  __declspec(dllexport)int__stdcall  EzBulk_DataIn(unsig ned  char*DataIn,int *lpDataInLen);
  __declspec(dllexport)int__stdcall  EzOpenDevice();
  __declspec(dllexport)int__stdcall  EzClose Device();
  然后在VB中调用此USB.DLL做以下声明。这样就可以直接在VB中调用这些函数作相应的开发了。
  Private Declare Function EzInit Lib “USB.DLL” (ByVal PipeIn As Byte, ByVal PipeOut As Byte, ByRef lpVoid As Any)As Long
  Private Declare Function EzBulk_ DataOut Lib “USB.DLL”(ByRef DataOut As Byte, ByVal DataOutLen As Long)As Long
  Private Declare Function EzBulk_ DataIn Lib “USB.DLL” (ByRef DataIn As Byte, ByRef DataInLen As Long)As Long
  有了嵌入式主机后,脱离PC机的数据传输不再是梦想了。在MP3播放器、数码相机里嵌入USB主机模块,使其由传统的USB外设成为USB主机。这样,这些嵌入式的主机就可以直接与移动硬盘、打印机等USB设备相连接,实现特定的功能。例如:江苏某企业生产的提花毛皮机控制系统中就实现了USB Host模块功能,用户系统可以直接读写作为Slave的U盘,将花型准备系统设计的花型以文件的方式存储到U盘中,在用户需要时,可读取U盘中的花型文件进行分析、处理,效果良好。
  目前USB主机的研究与应用已得到国内外的广泛重视和迅速发展,正在推广使用的USB3.0标准能提供4.8Gb/s的高速数据传输性能(USB1.1和USB2.0分别是12Mb/s和480Mb/s),甚至支持光纤连接。这样其峰值速度就可达到20Gb/s,如此就可实现USB高速组网或广播电视节目信号在USB设备上的传输。USB3.0标准还可解决因USB2.0供电不足而无法支持大功耗USB移动设备的问题。随着移动数码产品的发展趋势,提出了USB2.0协议的补充协议USB OTG和无线USB传输规范,同时具备主从机功能的高速USB OTG设备和无线USB的应用将是未来开发者们研究的方向。充分利用USB简便的特性以及高速数据传输性能,扩大其支持设备的种类,这将给USB的应用带来广阔的市场,也将给人们的生产生活带来巨大的便利。

参考文献
[1]  王田苗. 嵌入式系统设计与实例开发[M]. 第二版. 北京: 清华大学出版社, 2003:141-145.
[2]  马伟.计算机USB系统原理及其主/从机设计[M].北京: 北京航空航天大学出版社, 2004: 93-98.
[3] Cypress Semiconductor Corporation. SL811HS  Datasheet [EB/OL]. http://www.uclinux.org/, 2005-02-05.
[4]  陈启美,丁传锁.计算机USB接口技术[M]. 南京:南京大学出版社,2003:73-89.
[5]  郑智.嵌入式Linux下USB驱动程序开发研究[J].武汉理工大学学报. 信息与管理工程版,2006,28(7):
 117-120.

本站内容除特别声明的原创文章之外,转载内容只为传递更多信息,并不代表本网站赞同其观点。转载的所有的文章、图片、音/视频文件等资料的版权归版权所有权人所有。本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如涉及作品内容、版权和其它问题,请及时通过电子邮件或电话通知我们,以便迅速采取适当措施,避免给双方造成不必要的经济损失。联系电话:010-82306116;邮箱:aet@chinaaet.com。
嵌入式系统 主机控制器 固件 令牌 子类