您好,  [请登录] [QQ登录]  [支付宝登录[免费注册]

商品分类

分享到: 百度搜藏 搜狐微博 新浪微博 腾讯微博 QQ收藏 人人网 Facebook Twitter

XScale PXA270在Linux下的FPGA配置驱动

发布日期:2011-04-17


   择要:
以ACEX1K50为例,先容FPGA在Intel XScale PXA270微处理惩罚器体系上的应用。通过内存映射机制实现ACEX1K50在Linux下的配置驱动;通过用户应用步伐实现对ACEX1K50配置的操纵,为FPGA嵌入式范畴的应用提供一种要领。

   关键词:XScale PXA270 FPGA Linux 驱动

小序

  Intel公司推出的XScale采取ARM V5TE布局,是Strong ARM的升级换代产品。XScale PXA270处理惩罚器最高主频可达624 MHz,参加了Wireless MMX、Intel SpeedStep等新技能,以其高性能、低功耗、多成果等特点在信息家电、产业控制等范畴得到了遍及的应用。在嵌入式控制中,“微处理惩罚器+FPGA”是一种常用的办理方案。FPGA(现场可编程门阵列)有编程方便、集成度高、速率快等特点,电子计划职员可以通过硬件编程的要领来实现FPGA芯片种种成果的开辟。在我们的一个数控平台的研究项目中,采取XScale PXA270作为主CPU,并对其举行FPGA扩展,使其具有插补、电机驱动、信号处理惩罚、I/O口扩展的成果。Linux以其内核简练、高效,源代码开放且免费等上风,在嵌入式范畴得到了遍及的应用。下面以Intel XScale PXA270上的Altera FLEX/ACEX的应用为例,细致先容LinuxFPGA配置驱动的实现。

1 Altera FLEX/ACEX芯片布局

  Altera FLEX/ACEX芯片是基于查找表LUT(LookUpTable)原理而实现的。LUT本质上便是一个RAM。如今FPGA中多利用4输入的LUT,以是每个LUT可以当作一个有4位地点线的16×1的RAM。当用户通过原理图或HDL语言形貌一个逻辑电路以后,FPGA开辟软件会主动谋略逻辑电路的全部大概的结果,并把结果事先写入RAM。如许,每输入一个信号举行逻辑运算就便是输入一个地点举行查表,找出地点映射的内容,然后输出即可。由于LUT重要得当SRAM工艺生产,以是如今大部分FPGA都是基于SRAM工艺的,而SRAM工艺的芯片在失电后信息就会丢失,肯定要外加1片专用配置芯片(本实行电路利用Altera EPC2LC20)。在上电时,由这个专用配置芯片把数据加载到FPGA中,然后FPGA即可正常事变。由于配置时间很短,因此不会影响体系正常事变。在利用ACEX1K50之前,应对其举行计划编程,实现相应寄存器及I/O口的成果。有关FPGA的细致内容请参阅相干数据。

2 Intel XScale PXA270处理惩罚器的体系存储器接口

  PXA270处理惩罚器的可编程静态存储体系布局如图1所示。


图1PXA270静态存储体系布局

  在体系上, ACEX1K50位于nCS<2>上,物理地点0x8000000~0x8001000共4K的静态地点空间。图2表现了Intel XScale PXA270与ACEX1K50的硬件连接干系。


图 2Intel XScale PXA270与ACEX1K50的硬件连接

3 Linux下ACEX1K50配置驱动的实现

3.1 Linux下配置驱动基源头根本理

  配置驱动步伐是应用步伐与硬件之间的一此中间软件层,配置驱动步伐为应用步伐屏蔽了硬件的细节。如许在应用步伐看来,硬件配置只是一个配置文件,应用步伐可以像操纵平凡文件一样对硬件配置举行操纵。配置驱动步伐是内核的一部分,它重要实现的成果有:对配置举行初始化和开释;把数据从内核发送到硬件和从硬件读取数据;读取应用步伐发送给配置文件的数据,回送应用步伐恳求的数据以及检测和处理惩罚配置出现的错误。

  Linux将配置分为最根本的两大类:一类是字符配置;另一类是块配置。字符配置和块配置的重要区别在于是否利用了缓冲技能。字符配置以单个字节为单位举行次序读/写操纵,通常不利用缓冲技能;块配置为了进步服从,利用一块体系内存作为读/写操纵的缓冲区,由于涉及缓冲区办理、调理和同步等题目,实现起来比字符配置巨大得多。

  Linux通过配置文件体系对配置举行办理,种种配置都以文件的情势存放在/dev目次下,称为“配置文件”。应用步伐可以像平凡文件一样打开、封闭和读/写这些配置文件。为了办理这些配置,体系为配置编了号,每个配置号又分为主配置号和次配置号。主配置号用来区分差别种类的配置,而次配置号用来区分同一范例的多个配置。Linux为全部的配置文件都提供了同一的操纵函数接口,要领是利用数据布局struct file_operations。这个数据布局中包括很多操纵函数的指针,如open()、close()、read()和write()等,但由于外设的种类较多,操纵方法各不雷同。struct file_operations布局体中的成员为一系列的接口函数,如用于读/写的read/write函数和用于控制的ioctl等。打开一个文件便是调用这个文件file_operations中的open操纵。差别范例的文件(如平凡的磁盘数据文件)有差别的file_operations成员函数,接口函数完成磁盘数据块读/写操纵;而对付种种配置文件,则终极调用各自驱动步伐中的I/O函数举行详细配置的操纵。如许,应用步伐底子不必思量操纵的是配置还是平凡文件,可同等当作文件处理惩罚,具有非常清楚、同一的I/O接口,以是file_operations是文件层次的I/O接口。

3.2 ACEX1K50在Linux下配置驱动的实现

  在驱动步伐中利用内存映射可以提提供用户步伐直接访问配置内存的本领。利用内存映射的长处是处理惩罚大文件时速率明显快于标准文件I/O,无论读/写,都少了一次用户空间与内核空间之间的复制。在用户空间对ACEX1K50 FPGA配置的访问是通过内存映射来实现的。

  ACEX1K50可以看作是硬件连接在PXA270微处理惩罚器的nCS<2>上的一段物理地点来寻址。由于有假造内存办理单位,以是要是在Linux下,必须先把物理地点映射到假造地点空间,然后才华对该段地点举行读/写。

  在内核驱动步伐的初始化阶段,通过ioremap()将ACEX1K50的这段物理地点映射到内核假造空间;在驱动步伐的mmap体系调用中,利用remap_page_range()将该块ROM映射到用户假造空间。如许内核空间和用户空间都能访问ACEX1K50的这段被映射后的假造地点。

  由于ACEX1K50位于nCS<2>上,参照PXA270静态存储体系布局映射表,其物理肇始地点为0x08000000。别的,其配置名称及主次配置号定义如下:

  #define FPGA_PHY_START0x08000000
      // nCS<2>: PAX270平台
  #define FPGA_PHY_SIZESZ_4K
      // nCS<2>: Slot FPGA物理基大小为4K
  #define DEVICE_NAME"PXA270 FPGA"
  #define FPGARAW_MINOR 1
  #define FPGA_Devfs_path"fpga/0"
  static int fpgaMajor = 0;

  此中FPGA主配置号定义为零,使得操纵体系可以随机为该配置分派主配置号。

  ioremap()的作用是把一个物理内存地点点映射为一个内核指针,被映射数据的长度由size参数设置。该函数的实质是把一块物理地区二次映射到一个可以从驱动步伐里访问的假造地点上去。以下是该函数的定义:

  void *ioremap(unsigned long phys_addr, unsigned long size);

  配置驱动通过fpga_init()函数初始化FPGA配置,终极通过init_module(fpga_init)在内核启动时初始化FPGA配置。

  fpga_init()函数的流程如图3所示。


图 3fpga_init()流程

  ioremap()调用的语句如下:
pxa270_fpga_base= (unsigned long) ioremap(FPGA_PHY_START, SZ_4K);

  可以通过ioremap()调用的返回值pxa270_fpga_base来果断FPGA物理地点到内核假造空间是否映射告成。

  if(!pxa270_fpga_base) {
  printk("ioremap pxa270 fpga failed\n");
  return -EINVAL;
}

  向配置文件体系刊出FPGA配置通过调用cleanup_module()函数来实现。其代码如下:

  void __exit fpga_exit(void) {
    #ifdef CONFIG_DEVFS_FS
    devfs_remove(FPGA_Devfs_path);
    #endif
    unregister_chrdev(fpgaMajor, DEVICE_NAME);
  }
  cleanup_module (fpga_exit);

  在向内核配置文件体系注册该FPGA驱动后,还须实现配置驱动的file_operations布局。ACEX1K50的配置驱动定义了如下file_operations成员函数:

  static struct file_operations pxa270_fops = {
  owner:THIS_MODULE,
  open:fpga_open,
  mmap:fpga_mmap,
  ioctl:fpga_ioctl,
  release:fpga_release,
  };

  此中fpga_open和fpga_release体系调用的成果只大略地实现了FPGA配置利用计数器的递增与递减,fpga_ioctl体系调用也只是大略的打印一条没有ioctl控制的信息提示。这里不再阐发实现的详细代码。下面详细阐发fpga_mmap的实现进程:

  static int fpga_mmap(struct file *filp, struct vm_area_struct *vma) {
  unsigned long off = vma->vm_pgoff << PAGE_SHIFT;
  unsigned long physical = FPGA_PHY_START + off;
  unsigned long vsize = vma->vm_end - vma->vm_start;
  unsigned long psize = FPGA_PHY_SIZE- off;
    if (vsize > psize)
      return -EINVAL; //spans too high
    vma->vm_flags |= VM_IO|VM_RESERVED;
    vma->vm_page_prot=pgprot_noncached(vma->vm_page_prot);
    remap_page_range(vma, vma->vm_start, physical, vsize, vma->vm_page_prot);
    return 0;
  }

  fpga_mmap(struct file *filp, struct vm_area_struct *vma)体系调用容许直接将FPGA配置内存线性地映射到用户进程的地点空间中。fpga_mmap体系调用是通过调用remap_page_range()函数来实现一段线性物理地点的映射,调用remap_page_range()函数必要填写vm_area_struct布局的几个关键字段。

  int remap_page_range(struct vm_area_struct *vma, unsigned long from, unsigned long to, unsigned long size, pgprot_t prot)函数每个参数的意义阐明如下:

  vm_area_struct *//假造内存地区(VMA)指针
  unsigned long from//必要映射的用户假造地点的肇始位置
  unsigned long to//假造地点所映射到的物理地点
  unsigned long size//被重映射地区的大小,以字节为单位

4 ACEX1K50配置驱动在用户步伐中的利用

  当配置驱动实现后,就可以在用户空间利用该配置了。在用户空间重要是通过调用mmap()函数来实现对FPGA配置的访问。以下是用户空间应用步伐的一个示例:

  ……………………………………………………………………
  fd = open("/dev/fpga/0",O_RDWR);//打开配置文件
  if(fd < 0){
    printf("####fpgadevice open fail####\n");
    return (-1);//果断打开配置文件是否告成
    }
  iobase = (unsigned char *)mmap(0, 4096,PROT_READ | PROT_WRITE, MAP_SHARED,fd,0);//颠末地点映射后,可对FPGA的寄存器举行一系列操纵
  ……………………………………………………………………
  close(fd);//封闭配置文件

结语

  本文通过先容ACEX1K50在Linux操纵体系下配置驱动的实现进程,为FPGA嵌入式范畴的应用提供了一种要领。在实际应用中,通过用户步伐可以或许很好地实现对FPGA硬件编程后的种种成果的控制。

参考文献

[1] Alessandro Rubini, Jonathan Corbet. Linux配置驱动步伐.魏永明,等译.第2版.北京:中国电力出版社,2004.
[2] Intel Company. Intel PXA270 Processor Family Developers Manual. 200410.
[3] 倪继利. Linux内核阐发及编程.北京:电子产业出版社,2005.
[4] 林容益. CPU/SOC及外围电路应用计划——基于FPGA/CPLD. 北京:北京航空航天大学出版社,2004.