基于Linux的ARM与FPGA数据通信设计与实现
2015-12-02
(杭州电子科技大学通信工程学院,浙江 杭州310018)
0 引 言
以应用为中心的嵌入式系统的构建,需要在相应的微处理器及硬件设备上完成,硬件设备之间的数据通信在系统中也十分必要。高级精简指令集处理器(Advanced RISC Machines,ARM)是一款高性能、低功耗的嵌入式处理器,ARM9系列在无线设备、数字多媒体设备、通信和信息系统等控制领域中仍是主流的ARM 处理器[1]。现场可编程门阵列(Field-Programmable Gate Array,FPGA)可以快速测试实现用硬件描述语言完成的电路设计,是现代IC 设计验证技术的主流。在数据处理方面,FPGA 采用并行多通道方式,并且运行速度快,从而实现高速数据处理。由于FPGA 没有指令系统,它的控制能力较弱,因此结合ARM的控制功能和FPGA的数据处理功能进行综合设计已成为一种开发趋势。目前,ARM+FPGA的开发方案已被越来越多的运用到实际项目中,但在ARM 上开发的裸机程序可移植性差,也不便于后续应用程序的开发。为了改进不足,本文借助嵌入式Linux 操作系统,通过系统上的设备驱动程序开发,简化了接口数据通信的实现方式。嵌入式Linux是将Linux 内核进行裁剪修改后移植到微处理器运行的一种操作系统,具有实时、开源、网络支持等特性[2]。结合Linux系统,能让ARM 更好的控制设备和资源,并使在ARM 上开发应用程序变得简单。本文设计的接口,包括通用输入输出端口(General Purpose Input Output,GPIO),它提供了ARM 对FPGA的控制功能,并且采用并行总线接口,弥补了串行传输速率低的缺陷。
1 ARM与FPGA 硬件接口设计
1.1 硬件平台简介
在本设计方案中,ARM平台选用飞凌嵌入式公司生产的FL2440 开发板,采用核心板+底板的结构。核心板上包括ARM 微控制器、64 MB的SDRAM 内存、256 MB的NAND Flash以及4 MB的NOR Flash。其中,微控制器是三星公司生产的ARM9 处理器S3C2440A,具有高性能、低价格、低功耗等特点,并带有全性能的MMU(内存管理单元),使其支持Linux 等嵌入式操作系统[3]。开发板上已成功移植Linux系统,并能通过串口在PC 端用超级终端实现控制。
FPGA 选用ALTERA 公司的Cyclone Ⅲ系列EP3C16Q240C8N 芯片。该系列EP3C16 芯片具有15 408个LE(Logic Element,逻辑单元),0.5 Mbits 存储空间,56个乘法器,4个锁相环,20个全局时钟,以及346个可供用户使用的I/O 引脚。它是一款典型的低成本FPGA,并将低功耗、高性能结合在一起,具有灵活的解决方案,便于使用者做出快速复杂的设计。其广泛应用于视频图像处理、无线通信等领域。
1.2 通信接口设计
ARM 核心板与底板相连的接口中,包括了地址总线、数据总线、SPI、IIC、通用IO 口,以及复位、电源引脚等。这里选取DATA0 DATA15 总共16位数据总线作为与FPGA 进行并行数据传输的接口,另外包括读使能(R_EN)、写使能(W_EN)、片选(NGCS5)3 路控制信号,数据总线直接与ARM 芯片相连。相比于SPI、IIC 等串行总线接口,采用并行总线方式可以实现大数据量的高速传输[4]。
针对具体的通信方案,往往需要ARM 对总线上所传输数据的含义进行解释。在本设计中为了实现ARM 对FPGA的控制及指示数据含义,选取4 路GPIO 口作为控制命令信号,总共可以配置16种状态。具体为开发板上的GPF0、GPG1、GPF2、GPF1 等4 路IO。
ARM与FPGA 通信接口的所有连线如图1所示。
图1 ARM与FPGA连接口
ARM 上运行了Linux系统,因此需要设计接口驱动,并编写用于具体通信测试的应用程序。由于和ARM 不在同一个时钟域中,FPGA 端则通过异步FIFO 实现对总线上数据的读写缓存,从而准确传输数据。
2 Linux 嵌入式系统驱动设计
由于嵌入式Linux的可裁剪特性,通过各类接口连接到系统的外部设备可以自由的加载(insmod)和卸载(rmmod)[5],在系统中则通过相应的驱动来支持该设备。设备驱动程序是一个中间软件层,位于实际硬件和用户应用程序之间,它为应用程序设计屏蔽了硬件的实现细节。对于Linux 来说,任何硬件设备都以文件形式存在,因此通过驱动程序中的系统函数调用,应用程序可以对设备进行打开、关闭、控制、读写等操作,方式就和操作普通文件一样。
Linux系统将设备分为字符设备、网络设备和块设备3种基本类型[5],每一类都有对应的设备驱动程序。FPGA 通常属于字符设备[6],它可以按字节来读写的,本文设计的接口驱动程序主要包括加载及卸载设备驱动、实现设备操作两大模块。
2.1 设备的加载及卸载
为了使设备驱动程序能被应用程序访问,首先要将编译好的驱动模块完整的加载到内核当中。加载模块时运行如下的初始化函数[5]:
初始化代码依次完成申请、映射I/O 内存资源,初始化GPIO 寄存器,动态分配设备号,初始化设备文件结构,注册字符设备,创建设备节点等工作。由于要对具体的硬件进行读写操作,因此需要将FPGA的I/O 内存资源进行映射,以便在驱动程序中通过虚地址来访问FPGA的物理地址,这里用到系统调用函数ioremap()来映射内存,代码如下:
初始化GPIO 寄存器即将对应的4 路IO 口配置成输出模式,以实现ARM 对FPGA的控制。动态分配设备号使用系统函数alloc_chrdev_region(),然后调用cdev_init(),cdev_add()完成设备初始化及注册,最后调用device_create()自动创建设备节点。
同样,卸载模块时运行模块清除函数[5],代码如下:
清除代码依次完成与初始化相对应的工作,即注销设备、释放设备号、取消内存映射,分别调用函数cdev_del(),unregister_chrdev_region(),iounmap()实现。
2.2 设备操作的实现
所有的设备操作都定义在一个file_operations 结构体中,它是由一系列函数指针组成的集合,其中定义的打开、关闭、控制、读写等操作,均能在设备上进行。驱动中的函数与结构成员一一对应,对设备的特定操作均由这些函数分别实现。
如下定义了本文设计的设备文件操作接口,包括了对设备的基本操作:
其中,fpga_open、fpga_release 分别执行FPGA 设备的打开和关闭,s3c2440_ioctl 发送4 路IO 口控制命令,fpga_read、fpga_write 分别完成数据总线上16位并行数据的读写操作。
2.2.1 GPIO控制驱动
ARM 通过4 路GPIO 口对FPGA 进行控制操作,对应文件操作接口中的s3c2440_ioctl,使用设备驱动程序设计中的ioctl 方法实现,它是用于设备控制的公共接口。
首先定义命令,具体包括命令的类别(幻数)、序号、信号传递方向等,代码如下:
然后实现s3c2440_ioctl 函数,其主体部分代码如下所示,利用switch-case 语句可以根据不同命令配置出IO 口的高低电平,FPGA 根据IO 口上的电平然后执行相应的复位、读写数据操作,这样即实现了ARM 向FPGA 发送控制信号。
2.2.2 数据总线驱动
数据总线主要实现16位并行数据的读和写功能,对应设备文件操作接口中的fpga_read、fpga_write。读和写功能完成类似的工作,从设备读取数据到用户空间,将数据从用户空间写到设备上,因此它们的函数也极为相似。
上述函数的4个参数中,fp是设备文件指针,buf是数据缓存,size是传输的数据量,ppos是文件当前访问位置。由于buf是用户空间的数据指针,不能被内核驱动代码直接引用,同样的,设备文件也不能直接与buf 进行数据传递。因此,这里使用内核提供的I/O 内存访问函数,用于读写前面映射好的FPGA 内存空间,其函数原型为:
通过一次调用ioread16()或iowrite16(),可以将设备中的一个16位数据传递给用户空间的buf,或将buf中的一个16位数据写到设备上。
3 ARM与FPGA 通信方案测试
为了验证ARM 对FPGA控制的有效性以及并行数据传输的准确性,设计如下的通信测试方案。ARM 向FPGA 先后发送两个32位的数据,经过FPGA 对这两个数进行异或运算处理后,再由ARM 读取运算结果,具体流程如图2所示。
图2 通信测试流程
按照测试方案流程,在Linux 中编写应用程序,交叉编译后烧写到开发板上运行[2]。利用FPGA 开发软件Quartus II中的Signal tap 工具,可以抓取程序运行时各引脚上的时序状态,从而验证数据以及整个测试流程的正确性。
测试运行结果如图3所示。图3中,图3(a)、图3(b)是ARM 写数据到FPGA的时序,图3(c)是ARM 从FPGA 读数据的时序,由图3可见,data=0x5AA5B9F9,与理论计算值data1 ⊕data2 也相符。
图3 通信测试运行结果
4 结束语
通过嵌入式Linux 下的驱动开发,本文设计的ARM与FPGA 之间的通信接口,可以准确实现ARM对FPGA的控制以及并行数据的传输。在Linux系统中,底层硬件的实现由驱动程序完成,并且有相应的编程接口提供给应用程序,这样使顶层开发工作变得简便。在涉及ARM+FPGA 共同开发的领域中,本文提出的该种具体的通信接口设计方案,具有一定参考价值。
[1]杜春雷.ARM 体系结构与编程[M].北京:清华大学出版社,2003:1-11.
[2]韦东山.嵌入式Linux 应用开发完全手册[M].北京:人民邮电出版社,2008:2-9.
[3]飞凌嵌入式技术有限公司.FL2440 使用手册V4[EB/OL].[2009-08-22].http://www.114w.com/p-230375-1.html.
[4]李寿强.基于FPGA的ARM 并行总线研究与仿真[J].电子测试,2013,4(8):22-23.
[5]魏永明,耿岳,钟书毅.Linux 设备驱动程序[M].北京:中国电力出版社,2009:137-144.
[6]蒋贵全,张辉,王国锋.基于Linux的FPGA数据通信接口驱动设计与实现[J].计算机应用,2009,29(9):2520-2522.