周惠坤,张 鑫,梁金宝,牟 欢
(中国科学院 国家空间科学中心,北京 100190)
USB(Universal Serial Bus)通讯具有传输速度快、可靠性高、支持即插即用等优点,已经逐步成为现代数据传输的主流方式,获得了广泛的应用。
然而,在USB应用技术越来越成熟的同时,开发人员对于USB技术的运用越来越倾向于顶层使用,对于USB的底层原理与基础协议关注的很少,这会导致在实际开发过程中,遇到问题之后不知从何处着手解决。只有了解了USB的传输协议或者是底层传输通讯原理,才能很好的找出解决途径。
文中基于作者多年的USB开发使用经验,并且结合目前研究与生产中广泛使用的几种USB控制芯片,包括Cypress公司的enCoRe系列芯片、EZ-USB芯片以及Netchip公司的NET2888芯片等等,总结了它们在开发使用中最容易遇到而又非常重要的几个问题:USB设备与主机建立通讯过程中枚举和重枚举的区别[1],这个区别体现在不同的USB控制芯片当中,它对于设备的启动以及连接主机都有深刻影响;重枚举与重置的区别[1-3],很多把这个概念混淆,导致在应用中出错;固件程序控制多种启动方式的区别,同样的代码控制着不同的启动方式,理解了这个过程才能很好地控制芯片的工作。
在USB通讯协议中,有一个重要的概念是检测设备,也可称为枚举,它是主机在应用程序与USB设备通信之前,了解该设备的设置与能力并且给该设备指定一个驱动程序的过程,它是任何USB设备正常工作所必须的部分。
对于普通的USB设备,主机通过枚举的过程获取设备的描述符,了解设备并根据设备描述符中的PID(产品识别码)与VID(供应商识别码)值选择合适的驱动程序安装,这样就与设备建立了USB连接,之后就可以进行正常USB通讯,枚举的过程[4]如图1所示。
然而,对于目前很多USB设备来说,它们与主机建立USB通讯的过程并不完全与上述过程一致,其原因在于当前各型号的USB功能芯片启动固件程序的方式有很大的区别,这些启动方式大致可以分为两种类型[3-5]:
1)固件程序从非易失存储器中启动:每次启动直接从程序内存中读取固件代码,然后在枚举时直接启动运行,这样的程序内存包括 ROM (read-only memory)、EPROM(Erasable Programmed ROM)、EEPROM (Electrically Erasable Programmed ROM)、OPT(One-Time Programmable)PROM 或是 Flash EPROM(闪存);
图1 枚举过程图Fig.1 Process of enumeration
2)固件程序从随机存储器中启动:每次启动后,从外部非易失存储器中读取固件程序并存储在RAM (Random-Access Memory)中,然后启动运行。RAM可以任意删减和重写数据,并且关机后RAM内的数据即告消失,所以在每次开机时,都需要从外部加载固件代码。
正因为多了加载固件代码这个步骤,使得第二类芯片在启动时,如果从主机读取固件程序,那么建立USB通讯的过程与上述枚举有很大区别,它的流程如图2所示。
图2 从主机下载程序方式下重枚举过程图Fig.2 Process of re-enumeration downloading program from host computer
从图2可以看出,第二类USB功能芯片启动方式每次都需要从主机下载固件程序,相比上述第一种类型,它具有两个明显的优势:
1)用户可根据需求自己编写固件程序,适应性很广;2)开发中调试非常方便,断电即可重新下载固件代码。
因此,这种方式工作的USB功能芯片在工程中的应用越来越广泛,这样的方式下,芯片与主机建立通讯的过程我们称之为“重枚举”。
重枚举和枚举的最重要区别在于,重枚举需要两次读取设备的描述符,获取两次不同的PID/VID值然后安装不同的驱动,而枚举只需要读取一次描述符并只安装一次驱动[4]。这其中,第一次是读取的是设备默认的描述符,用于建立默认状态下的USB通讯,然后下载固件程序,第二次读取的是根据需求自己编写或者从厂家下载而来的描述符,使得设备实现项目所需的通讯功能。
在使用不同的芯片或者不同的程序下载方式时,开发人员往往会遇到驱动安装不对导致通讯不上、设备描述符编写错误导致设备工作效率低下、固件程序无法正常启动等突发状况,例如,作为数据传输系统的USB设备在使用中,经常会遇到USB设备与数据源设备以及主机接收软件在不同的启动顺序下产生不同效果、甚至导致通讯错误的情况,如果不能深刻理解枚举与重枚举的过程和意义,这些问题很难得到根本的解决。
需要特别指出的是,“重枚举”与枚举过程中的“重置”有重要区别,很多USB开发人员对这两个概念理解混淆,认为枚举中的“重置”就是我们所称的“重枚举”,但它们除了在现象上有点相似外,过程与意义上是有本质区别的:
1)“重枚举”指的是有些USB芯片或者外围设备在初次枚举后,通过某种方式更改了其提交给主机的描述符(包括VID/PID值)以及固件程序,从而引起了主机对设备的再次枚举,通过新的描述符再次识别设备的过程;
2)而“重置”是每次枚举过程中主机在设备刚连接后要求集线器将USB电缆中D+和D-两个信号都置为逻辑低位(正常时,这两信号有相反的逻辑状态),这个过程中主机与设备也类似断开再连接,与“重枚举”在现象上有点相似,但是它只是枚举中的一部分,它是为了确认设备与主机准备好了下一步配置通信而做的操作,不涉及描述符的变化也就不会使得设备请求再次枚举。
固件程序是CPU要执行的程序代码,是USB芯片的核心部分,它不仅控制着设备的数据传输,同时控制着重枚举的实现。Cypress公司的EZ-USB系列芯片是使用RAM来存储固件程序的第一批芯片,也是目前市场上使用最广泛的一种USB功能芯片。在此,我们以这种芯片为例深入研究芯片对于不同的启动方式下重枚举与枚举的控制[4-6]方法。
如图3流程图所示,固件程序的一个重要工作在于对重枚举的控制,在EZ-USB芯片的固件程序中,都需要以下代码来控制芯片的重枚举:
图3 EZ-USB芯片通用固件程序流程图Fig.3 Process of universal firmware program of EZ-USB
重枚举的控制主要依靠USBCS寄存器中的RENUM位和DISCON位[6],这两位的功能与作用分别如下:
1)RENUM位代表的是EZ-USB芯片使用默认状态或者固件程序来处理枚举过程,可用于判断这一位的值,来确定是否需要重枚举,RENUM位为0时,使用默认方式进行枚举,等待固件程序的下载,这一位为1时,使用固件程序与下载的设备描述符处理枚举过程;
2)DISCON位用来控制USB的断开与再连接,每次DISCON位的值变化为1时,芯片会自动与主机断开连接(其实是一种模拟断开的状态),这一位变成0的时候,芯片又会与主机进行重新连接。
这些RAM存储固件程序的芯片,包括EZ-USB,除了使用RAM外,也都是可以使用其他程序内存的,这种特性在芯片的开发过程与工程应用中非常完美的起到了互补作用。开发中,我们使用RAM每次下载固件程序便于调试,而应用中,又可将固件程序固化到例如Flash EPROM或者EEPROM等存储器。
然而,这种模式下,两种不同的下载固件程序方法对于固件程序的调用却不完全一样,许多开发人员很长一段时间内都没有理解清楚它们之间的区别,导致程序编写和运行中有时会出现各式错误,例如在重枚举的时候读取设备描述符的位置错误,或者多次通电、断电重复操作后部分控制重枚举的寄存器的值没有按照预期变化,导致突发状况。
了解固件程序对于枚举、重枚举的控制方式,有利于我们追踪错误并解决这些问题。在EZ-USB系列芯片中,固件程序对从主机下载固件程序和EEPROM存储程序的两种方式的控制区别,就主要体现在RENUM位的控制上:
1)从主机下载固件程序时,芯片通电后因为没有从任何方式读取到固件程序,所以RENUM位默认为0,使用默认方式进行枚举,然后通过主机下载固件程序,运行后,上述代码控制芯片与主机的模拟断开与再连接实现重枚举;
2)而EEPROM存储程序时,芯片通电后从它的SCL与SDA两个管脚读取到存储在EEPROM中的固件程序,触发USBCS寄存器中的RENUM位由默认值变化为1,在执行上述程序时,不满足判断条件,不执行EZUSB_Discon()的模拟断开部分,并直接由现有固件程序和设备描述符进行枚举,一次枚举即可识别设备然后正常工作,此时不需要重枚举。
正是通过控制这些寄存器的值,各式USB功能芯片利用固件程序实现了对枚举或者重枚举的管理。开发者在固件程序的编写中,需要特别留意对于这样一些寄存器的控制,深刻理解USB功能芯片启动以及工作方式,这样才能避免或者解决在USB通信中出现的一些错误和缺陷。
文中深入探讨了USB传输当中几个非常重要而又容易被人忽视或者混淆的概念,针对枚举和重枚举的区别,重枚举和重置的区别进行了对比分析,并详细讲述了枚举与重枚举的流程和控制,有助于开发人员在USB项目中更好的理解并掌握开发流程。大量应用结果表明,USB传输的底层原理与概念,对于解决传输中的问题以及提升数据系统的效率有很大的帮助,值得开发者真正的重视。
[1]Universal Serial Bus Specification Revision 2.0[M].USB Organization,2000.
[2]Axelson J.USB大全[M].陈逸,译.北京:中国电子出版社,2001.
[3]陈启美,丁传锁.计算机USB接口技术[M].南京:南京大学出版社,2003.
[4]萧世文,宋延清.USB2.0硬件设计[M].北京:清华大学出版社,2006.
[5]薛园园.USB应用开发技术大全 [M].北京:人民邮电出版社,2007.
[6]钱峰.EZ-USB FX2单片机原理、编程及应用[M].北京:北