基于SOPC技术的嵌入式Linux数据采集系统设计
2014-03-23赵建军刘石山
岳 奇, 赵建军, 刘石山
(昆明理工大学 理学院, 云南 昆明 650500)
0 引 言
SOPC(System On a Programmable Chip,可编程片上系统)技术是一种全新的综合性的电子设计技术,结合了SOC(System On Chip,片上系统)、PLD(Programmable Logic Device,可编程逻辑器件)和FPGA(Field Programmable Gate Array,现场可编程门阵列)各自的优点,具有灵活的设计方式,可裁剪,可扩充,并具备软硬件在系统可编程的功能,已逐渐成为一个新兴的技术方向。在FPGA中嵌入PowerPC处理器,可以充分利用FPGA具有可重配置、巨大的I/O带宽和高速并行处理能力,在数据采集和智能控制领域具有重要的应用价值;另一方面通过将Linux系统在PowerPC 405处理器中移植,可以充分利用Linux在数据处理、任务管理、界面控制和文件操作等方面的优点,大大提升了系统的整体性能,缩短了系统设计的周期。因此,将Linux系统嵌入到PowerPC 405硬核中,是一种低成本、高性能的嵌入式系统开发方案。
PowerPC处理器在通信领域和工业控制领域有着广泛的应用,本文采用Xilinx公司SOPC技术的PowerPC硬核处理器,在Xilinx公司的XUP Virtex-II Pro平台上研究并实现了以PowerPC 405处理器为核心的硬核处理器硬件平台的搭建;采用Linux 2.6.28内核在Linux系统平台上通过内存映射机制实现了GPIO(General Purpose Input Output,通用输入/输出口)控制器的驱动程序和应用软件的开发,实现了对GPIO设备控制和数据的读写。
1 可编程SOPC和Virtex-II Pro
Virtex-II Pro系列是Xilinx公司推出的一种较为完善的SOPC解决方案。随着嵌入式技术的发展和应用,Xilinx公司结合其高端芯片推出基于FPGA的两种32位的嵌入式处理器内核。一种是采用先进的IP植入技术在Virtex-II Pro中嵌入IBM PowerPC 405硬核处理器;另一种采用MicroBlaze 32位嵌入式处理器软核。PowerPC 405是32位体系结构的嵌入式处理器,采用精简指令集框架的CPU,运行的最高频率可达到400 MHz,能够实现更快的数据处理能力,而MicroBlaze软核处理器,运行频率最高为150 MHz,具有更好的灵活性。由于PowerPC 405硬核处理的速度和资源优势,在项目设计中我们采用了PowerPC 405硬核处理器为核心的SOPC系统。
2 PowerPC 405硬件平台的搭建
嵌入式系统的开发环境包含了硬件环境和软件环境两个方面,Xilinx公司的EDK(Embedded Development Kit,嵌入式开发套件)为嵌入式PowerPC 405硬核处理器和MicroBlaze软核处理器提供进行Xilinx平台FPGA设计所需的IP核,利用EDK可以快速生成以PowerPC 405为处理器的基本片上系统的硬件和软件结构,硬件平台的核心是Virtex-II Pro芯片XC2VP30,内嵌了两个PowerPC 405硬核处理器。设定处理器时钟为200 MHz;RS232_Uart_1的波特率为115 200 bit/s;支持SysACE_CompactFlash用于CF卡引导系统的启动和文件系统的操作;DDR_SDRAM 256M作为系统内存;16 KB RAM的支持;用户自定义IP核用于对数据的采集。完成系统配置后,运行XPS就可以生成与硬件平台相关的download.bit,用于完成片上系统硬件的初始化工作,硬件平台组成如图1所示。硬件比特流文件生成以后,需要配置相应的软件板级的支持包,用于配置系统硬件以完成硬件之间的数据交互。在EDK软件平台设置中,在操作系统选项中选择device_tree,在OS and Libraries选项中选择RS232_Uart_1为串口通信。相应参数设置完成后就可以生成xilinx.dts文件,它记录了系统的硬件信息,包括各个硬件分配的地址大小、基地址及IP核的版本号。
图1 硬件平台组成框图
由于FPGA和Linux系统处于两个不同的时钟域中,实现对FPGA采集的数据准确地传送成为系统设计的关键问题。文章采用调用Xilinx IP core生成的异步FIFO作为数据的缓冲,异步FIFO的数据宽度为40 bit,用于FPGA和Linux系统进行数据通信。TDC(Time-to-Digital Converter,时间数字转换器)是一个高精度的计时器,利用FPGA进位链延时将单光子到达时间转换为数字信号,实现光子到达时间的测量,经过特殊的格式化后将光子到达时间数据的测量结果输出到异步FIFO中。IPIF(IP Interface)是总线和用户逻辑之间的可快速实现和可配置的接口。FPGA内部结构如图2所示。
图2 系统硬件原理图
GPIO把FIFO中的两个控制信号与PLB总线连接起来,通过这两个控制信号判断FIFO是否为空的信号empty和读取数据有效信号valid,用于对FIFO中数据的读取控制。由于异步FIFO的读时钟(rd_clk)和写时钟(wr_clk)工作于两个不同的时钟域中,需要DCM(Digital Clock Manager,数字时钟管理单元)对异步FIFO时钟进行控制,用来产生系统所需的时钟信号。CPU通过读取GPIO中的控制信号判断是否可以读取FIFO中的数据,当FIFO中的控制信号为HF半满且RD_EN有效时触发中断,从而使Linux系统读取FIFO中的数据。
3 FPGA控制器的驱动程序编写
设备驱动程序是应用程序与硬件之间的一个中间软件层,设备驱动程序为应用程序屏蔽了硬件的细节。应用程序可以像操作普通文件一样利用open( )、close( )、read( )、write( )等文件处理函数,实现对硬件设备的操作。本文采用Linux 2.6.28的内核在Linux平台下编写用于读取和控制FPGA字符的设备驱动程序,包含以下模块:设备初始化和卸载模块、设备打开和关闭模块、中断处理模块、读模块、写模块、I/O控制模块。设备驱动程序是内核的一部分,它实现的主要功能有:实现设备的初始化和卸载;把内核态的数据传送到硬件,把底层硬件的数据读取到内核态;实现应用程序和设备文件的数据交互;硬件检测处理及错误处理。
3.1 设备初始化和卸载模块
图3 初始化工作流程图
Linux在系统上电启动或动态加载驱动程序时要调用内核的初始化函数,初始化模块在内核启动时负责FPGA设备的初始化。利用module_init( )和module_exit( )宏实现驱动程序的初始化和注销。设备初始化由module_init( )函数来完成,包括检测硬件、注册设备驱动程序、向内核注册主次设备号、申请I/O内存、物理地址到虚拟地址映射等操作。注销加载到内核上的设备驱动程序模块时,通过调用module_exit( )函数来完成,特别地,要释放在初始化时分配的内存、注销设备驱动程序等操作。初始化工作流程如图3所示。
由于PowerPC体系结构没有专门用于设备I/O的指令,而采用把寄存器看作内存的一部分,它与设备通讯的主要机制是通过内存映射方式对寄存器进行操作。在Linux设备驱动程序开发过程中,由于驱动程序操作的是设备的虚拟地址,通过MMU(Memory Management Unit,内存管理单元)将设备的虚拟地址映射到正确的物理地址上去。在初始化调用module_init( )时,首先利用request_mem_region(phys_addr,size)函数检测I/O内存区是否可用,phys_addr为FPGA的基地址,size为注册的输入输出空间的大小,利用返回值来判断是否有可用的虚拟内存空间。然后利用ioremap_nocache( )函数进行地址映射,调用该函数直接将FPGA设备寄存器的线性地址映射到内存空间中,返回值为内存映射后的虚拟内存地址,用户通过对返回的虚拟内存的地址的读写实现对FPGA硬件的控制和操作。
3.2 file_operation结构
Linux通过设备文件系统对设备进行管理,各种设备都以文件的形式存放在/dev目录下,Linux使用struct file_operating为所有的设备文件提供了统一的操作函数接口。file_operation结构体在头文件Linux/fs.h中定义,它是系统调用和驱动程序关联起来的关键数据结构,用来存储驱动内核模块提供的对设备进行各种操作函数的指针。它为应用程序提供了统一的系统调用接口。
具体声明如下:
static const struct file_operations xgpio_fops=
{
owner=THIS_MODULE,
ioctl=xgpio_ioctl,
read=xgpio_read,
open=xgpio_open,
release=xgpio_release,
};
应用程序打开设备时通过调用file_operation结构体中的xgpio_open( )函数,实现对设备的打开。注册中断服务采用request_irq( )函数,完成中断的申请。在设备打开后,返回一个文件指针,可以利用文件指针对设备进行一系列操作。关闭设备时使用xgpio_release( )释放进程分配的内存空间。
3.3 FPGA硬件设备的数据读取和控制
利用readl(address)和writel(value,address)函数可以实现对FPGA物理地址的寄存器32位数据的读写。由于Linux是保护模式的操作系统,内核和应用程序分别运行在完全分离的虚拟地址空间,用户空间的进程一般不能直接访问硬件。因此需要用到copy_to_user( )和copy_from_user( )实现驱动程序所在的内核空间与应用程序所在的用户空间的数据交互。下面是实现内核与FPGA的数据读写的部分代码:
static ssize_t xgpio_read(struct file *filp,char *buffer,size_t count,loff_t *ppos)
{
for(i=0;i drv_buf[i]=readl(remapped_addr+i); //读取FPGA寄存器count个数据到内核空间 rmb(); //等待读缓冲完毕 copy_to_user(buffer,drv_buf,count); //count个内核空间的数据复制到用户空间 } static ssize_t xgpio_write(struct file *filp,const char *buffer,size_t count,loff_t *ppos) { copy_from_user(drv_buf,buffer,count); //复制count个用户空间的数据到内核空间 for(j=0;j wmb(); //等待写缓冲完毕 } 在Linux平台上的设备驱动程序编写完成后,需要将驱动程序添加到内核空间,Linux驱动程序的加载分为动态方式和静态方式。当利用动态加载的方式并调试无误后,就可以采用静态加载的方式直接将驱动程序编译进Linux内核,实现系统上电自动调用,步骤如下: (1)在EDK硬件平台搭建完成后,将EDK工程目录下device_tree生成的xilinx.dts拷贝到Linux-2.6-xlnx/arch/powerpc/boot/dts目录下; (2)将编写的读写GPIO的驱动程序拷贝到Linux-2.6-xlnx/driver/char目录下; (3)修改Linux-2.6-xlnx/driver/char的Makefile文件,在Makefile文件中添加: obj-$(CONFIG_DRIVER_GPIO)+=xgpio.o (4)修改Linux-2.6-xlnx/driver/char的Kconfig文件,并添加: #Character device configuration menu “Character devices” config DRIVER_GPIO tristate “DRIVER_GPIO” help Enable Xilinx Virtex-II Pro GPIO (5)返回到Linux-2.6-xlnx目录下,利用make menuconfig可视化Linux内核配置界面,在Character devices中选择DRIVER_GPIO<*>,利用# nice make-j 4 simpleImage.virtex405-linux命令将驱动程序编译进内核,最终生成可以在PowerPC 405处理器上运行和进行FPGA数据采集的simpleImage.virtex405-linux.elf内核文件。 文章针对基于SOPC技术的嵌入式Linux数据采集系统的研究与设计,介绍了基于PowerPC架构的嵌入式Linux平台设备驱动程序的设计方法。系统以PowerPC 405处理器为核心,定制了基于PowerPC 405处理器的Linux系统,实现应用程序与FPGA中自定义IP核的控制和单光子到达时间的数据读取,完成了对光子到达时间的数据采集。验证了Linux操作系统运行在PowerPC硬核处理器的可行性,同时验证了SOPC技术、操作系统与FPGA的结合进行数据处理的可行性。充分发挥了Linux操作系统可移植性和扩展性强以及FPGA的数据处理速度快的特点,实现了Linux操作系统与FPGA的融合和信号的处理,对于通信、消费类产品等多方面有着广泛的应用前景。 [参考文献] [1] 张春生,常青,肖山竹.基于PowerPC 405的SOPC简单应用[J].微处理机,2007(6):117-120. [2] 陈鑫旺,姜秀杰.基于嵌入式Linux和FPGA的数据通信系统设计[J].微计算机信息,2012,28(6):76-78. [3] 买培培,邵东晖,苏涛.Linux在Xilinx FPGA上的移植[J].火控雷达技术,2009,38(4):72-76. [4] 田耘,徐文波.Xilinx FPGA开发实用教程[M].北京:清华大学出版社,2008:469-521. [5] LING Hsiang,LIN Jamie.Evaluating hardware/software partitioning and an embedded Linux Port of the Virtex-II Pro development system[D].Washington:Washington State University,2006:42-46. [6] 吴彦宏,陈相宁.S3C2410在Linux下的FPGA驱动[J].科学技术与工程,2008,8(17):5034-5038. [7] 刘振彪,肖国强,武兵.基于PowerPC的嵌入式MPEG4视频解码器的设计与实现[J].计算机工程与设计,2008,29(6):1384-1386.3.4 添加驱动程序到内核空间
4 结 语