网络技术在飞速的发展,网络接口的性能也在不断提高。由于以太网接口成本低,速度快,性能好,开发方便,越来越多的数据采集系统采用以太网接口作为最终的数据输出及控制端口。而在相应的嵌入式系统领域,越来越多的芯片,从单片机到DSP,也都逐渐开始支持以太网接口。TCP/IP协议是被广泛支持的以太网协议,在嵌入式系统中实现了TCP/IP协议,就可以方便地与计算机主机相连,将采集到的数据传输到主机进行保存和处理。
针对高速信号采集和处理系统,数据从采集-信号处理-网络传输,整个过程中一方面要保证信号处理的速度,即采集到的信号能够在限定的时间内得到处理,另一方面则要保证整条数据流通路不能有瓶颈。一般说来,网络接口由单独的芯片负责,才能保证其传输的实时性和高效率,而信号采集和处理则是另外的芯片负责。无论是AD与DSP之间还是DSP相互之间,都存在高速通信的问题。经过论证和实践,我们认为使用FIFO是很好的选择。
本文以TI(Texas Instruments)公司TMS320C6000系列芯片为基础,实现了一套高速信号处理—— 网络传输系统,如图1所示。高速A/D采集的数据通过FIFO(IDT72V273)传入TMS320C6713 DSP之中,该DSP芯片同步实时采集多路A/D数据并进行信号处理,由于传感器数目较多,我们采用了两片C6713同步处理的方式。两片C6713的处理结果通过各自后端的FIFO(IDT72V273)传入TMS320DM642 DSP。该DSP专用于数据的打包和网络发送。网络物理层由网络收发芯片LXT971ALC实现,最后数据通过网络进入计算机进行显示、保存和进一步处理。该系统实现了完整的传感器信号的高速信号处理、传输通路。技术上的难点除了信号处理算法之外,最主要的就是基于FIFO和网络的高速数据传输。本文根据在开发实践中积累的一些经验,对FIFO一网络数据传输的一些问题进行了探讨。
图1 信号处理-网络传输系统
1 硬件设计
在TI的C6000系列DSP中,C67x系列属于浮点DSP芯片,其中以C6713的运算能力最强,在300 MHz主频下,可达到2400 MIPs(百万指令每秒)和1800 Mfloot/s(百万浮点运算每秒)的运算速度,适合于大数据量和较复杂的浮点信号处理。而DM642作为定点DSP芯片,其主要优势不仅在于其速度快、性能好,还在于它自身携带了网络接口,硬件设计较为方便。
所谓FIFO,即“First In First Out”,是一种“先进先出”的存储器。FIFO存储器就像数据管道一样,数据从管道的一头流入、从另一头流出,先进入的数据先流出。以本文所采用的IDT72V273 FIFO芯片为例,其容量为16k×18或32k×9,主频达到133 MHz,仅6 ns读写周期,具有读指针和写指针,可以在FIFO出口读数据的同时在入口写入数据,能够满足实时系统的要求。本系统中在两处都用到了FIFO:A/D与C6713的数据接口及C6713和DM642的数据通道,FIFO基本接口如图2所示。
图2 FIFO 接口电路
DM642自身带网络控制器EMAC,省去了购买或开发网络子卡的麻烦,在硬件上只需连接一个网络收发芯片Intel LXT971ALC 即可,如图3所示。
图3 DM642网路接口电路
2 软件设计
软件开发在TI的集成开发环境CCS(Code Composer Studio)中进行,TI给C60000系列DSP提供了稳定高效的DSP/BIOS操作系统,为了方便网络开发,还提供了网络开发套件NDK(Network Developer's Kit)。所有的这些,保证了用户可以使用标准的C语言(程序中对速度要求较高的部分也可以用汇编语言)完成整个应用程序的开发,对硬件的操作只需调用相应API函数即可。
2.1 软件流程
无论是C6713还是DM642,都需要对FIFO进行操作。C6713需要读取FIFO传过来的A/D信号,进行处理后将结果写入后端的FIFO。而DM642则读取C6713发来的FIFO数据,进行网络打包发送。FIFO数据的读取部分,对于两者都是一样的,C6713给后端FIFO存数据,也只需对相应地址写入即可,所以C6713的程序,算法以外的部分跟DM642有相似之处,且相对简单。本文着重讨论DM642的程序流程。
DM642与C6713读取FIFO数据时,都是以EDMA的方式进行的。EDMA控制器可以独立于CPU工作,从而可方便地实现片内存储器、片内外设以及外部存储空间之间的数据转移。由外部中断自动触发EDMA传输,可以大大提高传输速率和CPU的工作效率。数据源源不断推入FIFO,FIFO数据存满则自动将满标志置位,再通过INT8触发DM642的自动EDMA数据传输,这样可以在不占用CPU资源的情况下将FIFO数据传人DM642的内存(或外存)中指定的位置。数据积累到一定程度后,通过SEM标志通知网络发送程序,将该数据取走并进行网络发送。这种数据传输方法经过试验是可行的。因此整个程序按照功能大体分为3部分:初始化程序对硬件中断和网络进行了初始化和设置;EDMA中断程序中通知网络发送程序,该数据已经准备好;在网络发送程序中对数据进行打包发送,图4是各个部分的流程图。
图4 网络程序流程图
需要说明的是,在我们的设计之中,两个C6713 DSP是在DM642的指令下同时工作的,数据的发送也同步进行操作。DM642前端的两片FIFO并联构成了64位的数据宽度,每次EDMA读取的是64位数据,读人数据后再进行拆分、提取和打包发送。
2.2 开发中的一些问题
C6000系列属于高端DSP芯片,开发起来有一定的难度。在开发过程中难免遇到很多的困难和问题,下面就其中一些问题及解决办法加以讨论。
2.2.1 程序初始化问题
C6000 DSP程序的开发最好在TI提供的例子程序基础上进行相应的修改,这样不仅方便快捷,也可以避免很多意想不到的问题。我们的DM642用户程序就以NDK的“client”例子为基础修改而得。其中程序的初始化主要在DM642的初始化程序dm642init.c中和主程序client.c的开头部分。在dm642init.c中,对缓存、网络物理地址等进行了初始化;而在client.c中,则是对中断、EDMA等进行初始化。
在dm642init.c中主要的初始化为以下几行语句:
CSL_init(); //初始化芯片函数库
CACHE_clean(CACHE_L2ALL,0,0);//清缓存
CACHE setL2Mode(CACHE_128KCACHE);//将L2缓存设为128K
CACHE_enableCaching(CACHE_EMIFA_CE00);//允许外存CEOO作为缓存
CACHE_enableCaching(CACHE_EMIFA_CE01);//允许外存CE01作为缓存
//Init the EVM
//EVMDM642_init();
//EVMDM642_LED_init();
L2缓存即为DM642的内部RAM,大小共256k,既可以设为缓存也可以设为内存。网络收发数据需要至少开辟64k的缓存,缓存越大性能越好。由于程序还要使用一部分内存,因此以设128k缓存为宜。
CACHE_enableCaching (CACHE_EMIFA_CE00)和CACHE_enableCaching(CACHE_EMIFA_CE01)的作用是开辟外存空间作为缓存,CE00对应外部RAM 的0x80000000~0x80FFFFFF空间,而CE01对应外部RAM 的0x81000000~0x81FFFFFF空间。在我们的开发板上的实践证明,这两个函数是必须的,如果不用,网络的性能要受到很大影响。实测数据如图5所示。
图5 CE00和CE01是否缓存对网络速度的影响
最后两个函数EVMDM642_LED_init()和EVMDM642_init()只适用于DM642EVM板,与板上的FPGA有关,而该FPGA的内部逻辑没有公开,所以在我们的开发板上这两个函数不能够正确运行。实践证明,在开发板上去掉这两个函数对程序性能影响不大。
在主程序client.c中,主要对中断、EDMA的通道等进行初始化。
EMIFA_config(&emifaCfg0); //设置EMW
IRQ_reset(IRQ_EVT_EDMAINT);//复位IRQ
IER=0x303; //设置中断寄存器
EDMA_config(hEdmaCha5,&edmaCfg0);//设置EDMA
IRQ_enable(IRQ_EVT_EDMAINT);//允许IRQ
HWI_enable(); //开硬件中断
EDMA_intEnable(2); //允许EDMA中断
EDMA_enableChannel(hEdmaCha5);//允许EDMA通道5
值得特别注意的是,DM642的网络发送之后,需要重新将缓存初始化,否则下一次接收时就会有个别数据出错。具体原因有待研究。即将以下语句写入到网络发送程序之后:
CACHE_clean(CACHE_L2ALL,0,0);
CACHE_setL2Mode(CACHE_128KCACHE);
CACHE_enableCaching(CACHE_EMIFA_CE00);
CACHE_enableCaching(CACHE_EMIFA_CE01);
2.2.2 硬件中断对网络程序的影响
以太网协议属于非实时网络协议,其内部实现机制也比较复杂。TI的NDK开发包中提供了符合berkeley socket标准的网络函数,如socket(),listen(),accept(),send(),recv()等等,但其内部源代码是不公开的。在实践中,我们遇到的一个较为突出的问题是,在数据量较大的情况下,FIFO的中断次数如果太频繁,会影响到DM642的网络发送。具体表现为程序运行并非十分平稳,中断较为频繁的时候,网络发送函数send()有时就会报错,返回(-1),导致该帧数据发送失败。
如果数据量较大且对数据信号处理实时性要求较高,那么该问题就会比较棘手,目前我们还未能够完全解决。但根据目前我们的需要,可以将网络发送的间隔时间延长。每次FIFO数据存满后,通过EDMA传输到外存中,但却不是每次存满都进行网络发送。而是将数据累积起来,多次的传输数据一起发送。这样的网络发送出错率会小得多。在软件编程上,也可以考虑双buffer甚至3个buffer的方式。一个buffer满后,进行发送,而此时的FIFO数据导入另外的buffer中,如此循环。另外软件上还需考虑容错机制,一次数据发送失败后,需要将该数据包重新发送,从而保证不丢失数据。事实上,以太网的速度是很快的,如图5所示,目前的DM642的网络接口我们实测的速度可以达到10-11 Mbyte/S(百兆网即100 Mbit/s,换算成字节大约11~12Mbyte/s)。需要指出的是,同样的数据流量条件下,大量的数据集合到一起一次发送,相比与分多次发送少量数据,要稳定得多。目前我们可以做到3 S发送一次,每次发送约5M 数据的较为稳定地程序运行,相信经过改进,还有较大的提高空间。
2.2.3 其它常见问题
参考文献[1]P44上提供了常见问题的列表,比如调用fdOpenSession()和fdCloseSession()的问题,PRD函数中设置100 ms周期的问题,内存溢出问题(设置“SO_LINGER”选项)等等,以及其他文献[5]上提到的“dispatcher选项”问题,上述问题笔者在实践中均遇到了,因此仔细阅读文献资料可以少走弯路。
3 结论
C6000系列DSP速度快,性能好,稳定性高,可以满足很多大规模信号处理系统的要求,但开发的难度也相对较大。我们完成的这一套信号处理-网络传输系统,FIFO和网络的数据传输是开发过程中遇到困难较多的一部分,其中一些问题仍需要深入探讨。目前,信号出口采用以太网,已经成为很多嵌入式系统的选择,形成一种趋势。随着网络技术和计算机集群技术的不断发展,从嵌入式网络接口输出的数据,可以通过网络接入到计算机集群中,进行更大规模的信号处理,这将是本文后续将要进行的工作。
参考文献:
[1] Texas Instruments TMS320C6000 TCP/IP Network Developer's Kit User's Guide.Texas Instruments,12-jun-2003.
[2] TMS320DM642 Video/Imaging Fixed-Point Digital Signal Processor Data Manual.Texas Instruments,August-2004.
[3] IDT 3.3 VOLT HIGH-DENSITY SUPERSYNC II NARROW BUS FIFO. IDT (Integrated Device Technology,Inc.Septemher-2003.
[4] Texas Instruments TMS320C6000 TCP/IP Network Developers Kit Programmers Reference Guide.Texas Instruments,12-Jun-2003.
[5] 李方慧等.TMS320C6000系列DSPs原理与应用(第二版) [M].电子工业出版社,2003