张 聪,张 涛
(1.中国科学院空间应用工程与技术中心,北京100094;2.中国科学院光电研究院,北京100094;3.中国科学院大学,北京100049)
在高速数据采集领域常常需要将前端设备采集到的高速数据通过高速接口实时传输给计算机,目前主要使用PCI 总线接口传输数据,但这种方式成本高昂、结构复杂、便携性差,若采用新一代的USB3.0 接口则可以解决这些问题。USB3.0 接口在保留其固有优势的基础上极大的提高了数据传输带宽,十分适合应用于高速数据采集领域。USB3.0 设备控制器的固件设计是开发USB3.0 接口的关键,本文重点介绍了USB3.0 接口设备控制器的固件设计原理和方法。
EZ-USB FX3(CYUSB3014)是Cypress 公司生产的符合USB 3.0 标准的设备控制器,利用EZ-USB FX3 可以很容易的把USB 3.0 通信端口集成到任何电子系统中,使得系统能够与计算机实现高速连接。由于USB 3.0 传输带宽大、效率高,很适合应用于对数据传输的速度和实时性要求较高的场合,例如高速图像数据采集、高速光纤数据采集等领域。
FX3 拥有一个高性能的32 bit 的微处理器内核ARM926EJS,该内核的工作频率可达200 MHz,使得FX3 能够用在对数据处理要求较高的地方。芯片内部还集成了一个512 Kbyte 容量的内部系统存储器(SRAM),用来存储代码、配置参数,同时作为芯片内部DMA 通道的缓冲区。FX3 支持多种外围接口,包括高速的USB 接口、第二代通用可编程接口GPIFII,除此之外还有常用的UART 接口、SPI 接口、I2C 接口、I2S 接口以及普通的GPIO 接口。
FX3 的USB 模块集成了符合USB3.0 规范1.0版的USB3. 0 和USB2. 0 外设、符合PIPI3. 0 的5 Gbit/s 带宽的USB3.0 PHY、符合OTG 补充标准2.0 版的高速OTG 主机和外设、32 个物理端点,另外它还支持充电电池规范1.1 和辅助充电适配器检测功能。其中的OTG 功能使得FX3 不仅仅能工作在设备模式还能工作在主机模式,工作在设备模式时支持超速、高速和全速速率,工作在主机模式时支持高速和全速速率,对主机模式的支持实现了在没有PC 机的情况下设备之间数据的传输,方便了设备之间的连接。
固件是在USB 控制器芯片加电后,由其他设备加载到USB 控制器中并在其中运行完成接口数据传送功能的一段程序,其作用是辅助或者说控制硬件来完成预期的设备功能。固件的主要功能包括:初始化工作;辅助硬件完成设备的重新枚举(ReNumeration)过程,对主机做出适当响应;对中断的处理;数据的接收与发送;对外围电路的控制。EZUSB FX3 的固件设计不需要设计者过分关注底层硬件设置,而只需调用相应的库函数,这些库函数隐藏了硬件设备,降低了固件的开发难度。EZ-USB FX3的固件设计主要涉及到对固件数据流的理解以及对GPIFII 接口、DMA 通道、回调函数的设计。
FX3 的固件相对复杂,理解固件的各种数据流向有利于设计出好的固件,如图1 所示为固件的数据流结构图,从图中可以清楚的看出设备控制器中固件数据流的相互联系,除了ARM9 微处理器核外控制器的外围接口、GPIFII 状态机引擎、DMA 系统引擎都具有相应的固件管理模块。不同外围接口之间通过DMA 系统引擎实现数据的路由。各个固件管理模块都可以向微处理器核发送特定的中断信号,微处理器核通过对中断信号的监视实现对数据流的管理。通过配置接口间的DMA 数据传输方式,既可以实现自动传输也可以实现在微处理器的干预下传输。有些低性能接口像UART、SPI、I2C、I2S,既可以利用DMA 模式实现数据传输,也可以由CPU 直接向这些接口传输数据,但具有较高性能的GPIFII 接口和USB 接口只能通过DMA 模式进行数据传输。每个固件模块都可以向微处理器发送中断信号,微处理器收到中断信号后可以通过固件的回调函数机制执行相应的功能。DMA 系统引擎会向微处理器发送DMA 事件中断信号,该信号用来通知微处理器有特定的DMA 事件发生,当微处理器接收到特定的DMA 事件时,就会调用相应的回调函数来处理这些DMA 事件。
图1 EZ USB-FX3 固件数据流结构图
GPIFII 接口是FX3 的重要组成部分,利用该接口可以完成与任何外部设备的高速并行数据传输。GPIFII 具有一个完全可编程的状态机,提供多达256 个可编程状态,可实现各种具体的接口时序或协议,可实现与任何处理器、ASIC、DSP 或FPGA 等设备的无缝连接。GPIFII 能够在100 MHz 的频率下实现32 bit 数据的并行传输,最高有效数据的传输速率为400 Mbyte/s。该接口通过配置能工作在主模式或从模式,而且数据总线的位数可以在8 bit、16 bit、32 bit 之间灵活选择。当数据总线配置为32 bit 时,该接口支持14 根可配置的控制信号,所有这些控制信号可以是输入、输出或者双向的;当数据总线配置为8 bit 或16 bit 时,该接口可以支持16 根可配置的控制信号,所有这些控制信号也可以是输入、输出或者双向的。
本设计将该接口配置为一个32 bit 的同步FIFO,并且工作在从模式,由外部的时钟信号PCLK作为接口状态机的工作时钟。外部设备通过检测标志信号FLAGA 和FLAGB 来判断FIFO 缓冲区的空或者满。对外部设备而言,USB3.0 设备控制器就如同它的一个存储区,可以向该存储区随意地读写数据。配置为同步从模式FIFO 的GPIFII 接口与外部设备的信号连接如图2 所示。
图2 GPIFII 接口信号连接图
FX3 利用内部的DMA 网络把不同外围接口连接起来,以实现不同接口之间的数据传输。DMA 数据通道是一种软件结构,该软件结构封装了3 种硬件元素:套接口(Sockets)、缓冲区(Buffers)、描述符(Descriptors)。套接口是存在于外部接口中的硬件模块,一个外部接口可以包含多个套接口,在固件系统中套接口处于DMA 数据通道的两个终端,一个套接口用于输入数据,另一个用于输出数据。数据通过套接口可以流入或流出已经建立好的DMA 数据通道。缓冲区是设备控制器系统内存中数据缓冲区,相当于DMA 数据通道的中转站,流入套接口的数据首先被存放到缓冲区中,然后才能被输出数据的套接口将缓冲区中的数据读出。描述符作为一种数据结构把与数据流相关的套接口和缓冲区关联起来。
固件设计一个很重要的工作就是建立DMA 数据通道,利用高层的DMA 管理函数可以大大降低DMA通道编程的复杂性,通过调用和配置相应的DMA 管理函数,可以很容易地建立任意两个套接口间的DMA 数据通道并能实现对数据流的监控或修改。
为了适应不同的应用需要,FX3 提供了多种DMA 通道模式,大体可分为2 种,一种是自动DMA通道,另一种是手动DMA 通道。自动DMA 通道在通道建立起来并开始运行后,固件就不再干预数据流的传输,数据将连续不断的流过自动数据通道,由于不需要固件干预,这种通道模式能提供最大的数据效率;手动DMA 通道在数据流动过程中需要CPU 干预,这样可以监视或者修改数据流,但可能会降低数据传输效率。
固件通过回调函数来完成对各种中断事件的处理,当设备控制器的某个接口模块产生了某种事件,它就会触发相应的中断,然后已经被注册的该事件对应的回调函数就会被调用,如图3 所示为固件函数调用结构图。回调函数由中断服务程序(ISR)调用,用户可在回调函数里实现具体的应用功能。任何一个接口模块都可以产生特定的中断信号通知应用逻辑以回调函数地方式进行处理。本设计采用了自动DMA 通道方式,没有注册DMA 回调函数,但USB 的setup 和event 事件都是通过回调函数处理的。
FX3 的固件开发需要2 个开发工具:固件集成开发环境和GPIFII Designer。固件集成开发环境集成了第三方工具链compiler、linker、assembler 和JTAG debugger,可帮助用户快速开发、构建和调试FX3 的固件应用程序,GPIFII Designer 是GPIFII 接口设计工具,它提供了一种图形化状态机的设计方式,可使用户直观的配置该接口的时序行为。
固件程序主要由两部分组成:RTOS(实时操作系统)和固件框架。RTOS 是固件工作的软件平台,设备控制器的所有硬件模块和软件模块都由RTOS管理控制。固件框架通用性比较强,它完成设备最初的初始化,其初始化流程如图4 所示。在初始化过程显示的调用main()函数之前,固件会先做一些必要的硬件初始化,为后面进一步初始化和RTOS的运行建立良好环境,CyU3PFirmwareEntry()函数负责这部分的初始化。RTOS 的入口函数CyU3PKernelEntry()主要用来初始化RTOS,该函数最后将调用CyFxApplicationDefine(),这个函数将创建与具体应用相关的用户线程。
图4 固件框架程序流程图
固件框架中的CyFxApplicationDefine 函数创建用户应用线程SlFifoAppThread_Entry,本设计中该应用线程建立了一条从GPIFII 端口到USB 端口的自动DMA 通道,一旦启动该通道,数据将自动的通过DMA 通道传输到USB 主机。由于GPIFII 端口被配置为同步FIFO 模式,GPIFII 的接口信号时序服从普通FIFO 的接口信号时序,因而在外部设备看来它只是在访问一个FIFO。
应用相关程序的流程图如图5 所示,在USB 事件回调函数中配置GPIFII 端口、配置USB 端口,建立DMA 通道。最后通过调用CyU3PConnectState(CyTrue,CyTrue)实现FX3 与USB 主机的硬件连接,该函数的第一个参数用于使能连接,第二个参数表示将FX3 枚举为超速设备。
图5 应用程序流程图
USB Setup 回调函数用来处理USB 主机发来的枚举请求,当USB 接口的驱动线程接收到枚举请求时就会调用该回调函数进行处理。这里采用快速枚举方式,除了制造商和未知的请求外,都不需要该函数处理,而由USB 接口驱动线程自动处理,因而该回调函数可以直接返回。USB Event 回调函数与USB Setup 回调函数有相似的处理方式,当USB 驱动线程检测到主机的USB 事件请求时就会调用该回调函数,来处理USB 主机的各种事件请求。本设计在USB Event 回调函数中配置USB 端点并建立DMA 通道。
(1)配置USB 端点
FX3 共有32 个USB 端点,USB 端口使用一个消费者端点,端点号为0x81,端点类型为bulk 类型。当采用超速传输时,端点数据包大小为1 024 byte,突发传输数据包数量为16。端点配置函数如下:
epCfg.enable=CyTrue;
epCfg.epType=CY_U3P_USB_EP_BULK;//bulk 类型端点
epCfg.burstLen=16;//突发传输数据包个数
epCfg.streams=0;
epCfg.pcktSize=size;//端点数据包大小1 024 byte
apiRetStatus=CyU3PSetEpConfig(CY_FX_EP_CONSUMER,
&epCfg);//配置消费者端点
if(apiRetStatus !=CY_U3P_SUCCESS)
{CyFxAppErrorHandler(apiRetStatus);}
(2)建立DMA 通道
通过设置DMA 配置数据结构并调用DMA 通道创建函数来建立DMA 通道,该DMA 通道发送数据的一端为GPIFII生产者套接口,接收数据的一端为USB 消费者套接口。
dmaCfg.size=16×1 024;//DAM 缓冲区大小16 kbyte
dmaCfg.count=CY_FX_SLFIFO_DMA_BUF_COUNT;//DMA
缓冲区个数
dmaCfg. prodSckId = CY _ FX _ PRODUCER _ PPORT _
SOCKET;//生产者套接口号
dmaCfg.consSckId=CY_FX_CONSUMER_USB_SOCKET;//消费者套接口号
dmaCfg. dmaMode = CY_U3P_DMA_MODE_BYTE;//DMA
模式
dmaCfg.notification=0;
dmaCfg.cb=NULL;
dmaCfg.prodHeader=0;
dmaCfg.prodFooter=0;
dmaCfg.consHeader=0;
dmaCfg.prodAvailCount=0;
/* 创建自动DMA 通道* /
apiRetStatus=
CyU3PDmaChannelCreate(&glChHandleSlFifoPtoU,CY_U3P_
DMA_TYPE_AUTO,&dmaCfg);
if(apiRetStatus !=CY_U3P_SUCCESS)
{CyFxAppErrorHandler(apiRetStatus);}
固件设计完成后需要从多方面对固件进行实际测试以验证其正确性,对固件测试首先要建立固件的测试系统,固件测试系统结构如图6 所示,该测试系统由激励源、USB3.0 控制器和主机组成,激励源产生激励数据通过GPIFII 接口传送给控制器,然后控制器按照USB3.0 协议将数据转发给主机。下面主要从两个方面验证固件设计的正确性。
(1)固件枚举测试
固件能够正常工作的一个重要标志是当USB3.0控制器连接到主机上时,主机能够成功的枚举设备控制器。使用主机测试软件USB Control Center 对固件枚举功能进行测试。经过测试,测试软件成功的接收了由固件发来的各种描述符,根据描述符中的各字段数值可以判断枚举的正确与否。其中的部分描述符字段如下:
VendorID =" 04 B4",ProductID =" 00 F1",BcdUSB="03 00"
根据供应商号字段VendorID 和产品号字段ProductID 的值可知主机已识别出设备控制器,根据BcdUSB=”03 00”字段可知设备控制器符合USB3.0协议、能够进行超速传输。
图6 固件测试系统结构
(2)数据传输测试
发送端:发送端使用FPGA(可编程逻辑控制器)作为测试系统的激励源,由FPGA 生成测试数据,按照FIFO 时序向GPIFII 接口写入数据,利用FPGA 在线调试工具抓取该接口的各个信号变化波形如图7 所示。
图7 GPIFII 接口信号实测波形
接口信号波形的时钟频率USB_PCLK 为25 MHz,数据总线USB_DQ 宽度为32 bit,易知发送端的数据发送速率为100 Mbyte/s。当USB_WR 和USB_CS 有效(低电平有效)时在时钟下降沿输出数据,第1 个发送字为AA0000BB(16 进制表示,高字节在前),之后从00000000 开始递增。
接收端:接收端使用主机测试软件USB Control Center 接收发送端的激励数据,图8 为实际接收的数据,接收到的数据的第1 个32 bit 字为AA0000BB(16 进制表示,高字节在前),之后数据从00000000开始递增,因而接收端与发送端的数据完全一样,数据接收正确。在接收数据的过程中使用速率测试软件测试数据传输平均速率为94 Mbyte/s,与实际发送的数据速率接近。
图8 实际接收数据显示
本文介绍了USB3.0 设备控制器FX3 固件的主要工作机制并概述了固件程序的运行过程,并且通过实验验证了所设计固件运行的稳定性和正确性。对固件工作机制的深入把握是设计高质量固件的前提,在设计过程中还应充分利用固件框架,在此基础上修改或增加具体应用相关的程序,以提高设计效率和正确性。另外,GPIFII 端口强大的可编程性使得FX3 能更加灵活的处理与其他设备的连接问题,因而有必要对该接口做进一步的研究以充分发挥该接口强大的灵活性。
[1] USB 3.0 Promoter Group,Universal Serial Bus 3.0 Specification[S].www.usb.org,2008.
[2] Cypress Semiconductor Corporation,EZ-USB FX3 SuperSpeed USBController[EB/OL].www.cypress.com,2011,1-35.
[3] Cypress Semiconductor Corporation,GPIFII Designer 1. 0[EB/OL].ww.cypress.com,2012,3-42.
[4] Cypress Semiconductor Corporation,FX3Programmers Manual[EB/OL].www.cypress.com,2011,3-161.
[5] Cypress Semiconductor Corporation,FX3 SDK Firmware API Guide Revision 1.1[EB/OL].www.cypress.com,135-285.
[6] Cypress Semiconductor Corporation,Designing with the EZ-USB FX3 Slave FIFO Interface[EB/OL].www.cypress.com,2011,1-11.
[7] 一种USB3.0 高速高清工业摄像机[P].中国:201210056565.2.
[8] 严石,杨定礼,张宇林.基于USB2.0 的数据采集系统设计[J].电子器件,2008,31(6):1959-1962.
[9] 曹玲芝,张恒. 视频处理系统高速USB 接口设计[J]. 电子器件,2007,30(4):1337-1340.
[10] 杨磊,郁道银,陈晓冬. 医用超声内窥镜高速成像系统的USB2.0 接口设计[J].传感技术学报,2006,19(3):621-624.
[11] 陈云飞,胡荣强,李伟.基于EZ-USB FX2 的固件程序设计[J].电子器件应用,2007,9(1):42-44.
[12] 刘延波,郑世强,王斌.USB 设备固件程序设计[J]. 信息工程大学学报,2004,5(2):56-60.