首页 > 技术 > 内容

基于ARM-Linux平台的FPGA程序加载模式浅析

时间:2025-12-02  作者:Diven  阅读:0

1、引言

在系统上电时,需要从外部载入所要运行的程序,此过程被称为程序加载。多数情况下,从外部专用的 读入程序。这种方式速度慢,而且只能加载固定的程序。显然,当系统需要容量大而且 FPGA要加载的程序可以根据需要有选择的加载时不能采用这种方法。本文实现了基于外部处理器的加载方法,速度快,而且可以根据设置给FPGA加载相应的程序。

对于 公司的 FPGA芯片,有五种加载方式:JTAG模式,串行从模式,串行主模式,并行从模式和并行主模式。JTAG模式常用于调试时,将主机好的程序加载到FPGA,优先级高于几种模式。加载模式取决于 FPGA上加载模式管脚(M0,M1,M2)的设置。

用外部处理器给 FPGA加载程序时,可以采用串行从模式、并行从模式,甚至于 JTAG模式。本文选择并行从模式,原因在于更高的配置速率。

2、 FPGA程序数据的产生

FGPA的程序加载即是要把好的程序文件按一定的时序写入FPGA。而 的开发环境可以根据用户的选择产生多种文件格式,以不同的后缀名区分。不同的文件格式包含了不同的信息,有不同的用途。

本文选择了.bin格式的文件。此文件是只包含有程序数据的二进制文件。产生此文件,要在bitgen 参数里增加-g :yes 选项。

需要说明的是,通常的微处理器 D0位是最低有效位,而 的 FPGA在接收程序数据时,D0位是最高有效位。在按字节读取.bin格式的文件之后,需要有一个转换的过程。如从文件读到一个字节,0x7D,即二进制的 0111 1101,需转换为:1011 1110。

加载过程开始时,就要从.bin文件序按字节读出数据,然后在 CCLK的上升沿写入 FPGA。在.bin文件中的数据都被写入 FPGA后,CCLK需要多出四个时钟周期,以使得 FPGA完成启动过程。

3、硬件设计

在FPGA上,与配置有关的管脚分为两类:专用管脚,包括_B,HSWAP_EN,TDI, TMS,,TCK,TDO,CCLK,DONE,和M0-M2。还有一类是可复用管脚,这类管脚在配置阶段作为配置管脚,配置结束后可以配置为通用普通的IO管脚,也可以继续作为配置管脚。在并行从模式下,涉及到的配置管脚和功能如下:

CS_B:片选信号,低有效; RDWR_B:写信号,低有效; BUSY:FPGA忙指示,高有效,一般只有在并行加载时钟速率大于50M时才有可能用到;D0-D7:数据线; _B:芯片被复位后,此管脚为输出信号,输出低电平指示FPGA正在自行复位内部

寄存器。复位结束后,此管脚浮空,处于输入状态。因此需要上拉电阻,指示复位结束。内部寄存器复位结束后,此管脚若被拉低,则会推迟FPGA的程序加载过程。在程序加载过程中,此管脚又变回输入状态,对外输出低电平指示加载的程序数据存在CRC校验错误。

_B:异步复位信号,下降沿有效,此信号为低电平时复位FPGA,复位后,FPGA芯片处于内部寄存器自行复位过程,_B被FPGA芯片拉低,此过程结束后,FPGA不再驱动_B管脚,INIT_B管脚处于浮空状态,此时,INIT_B有上拉电阻时,INIT_B呈现高电平,依次可以指示FPGA的内部寄存器自行复位结束。程序加载状态。

DONE:加载成功指示。 CCLK:程序加载时,数据在此信号的上升沿被写入FPGA。在本设计中,ARM芯片采用的是 SUMSUN公司的,与 FPGA配置管脚相连的是此芯片的通用 IO管脚 D组。硬件连接如图[1]所示。在 ARM的程序中,ARM管脚在程序加载的各阶段的输入输出设置如下:设置 GPD[10](与 FPGA的 INIT_B相连)、GPD[11](与 FPGA的 BUSY相连)为输入管脚,以监视 FPGA内部寄存器自行复位结束和忙闲状态。设置GPD[12](与 FPGA的 _B相连)为输出状态,并使其输出低脉冲,使 FPGA复位。然后依次设置 GPD[8](与 FPGA的 CS_B相连)、GPD[9](与 FPGA的 RDWR_B相连)、GPD[14] (与 FPGA的 CCLK相连)为输出管脚,并使其输出低电平,使 FPGA处于被选可接受数据状态;接着设置D[0..7]为输出状态。

至此,ARM中的程序开始轮询GPD[10]的状态,检测到此信号为高时,有两种选择,其一是因为需要而推迟 FPGA的程序加载,可以通过设置 GPD[10]为输出,并使其输出为低电平直至程序加载开始。其二是开始给 FPGA加载程序,FPGA在 CCLK的上升沿接收数据,在给 FPGA加载程序的过程中,程序需要监视GPD[10]管脚的状态,一旦为低,FPGA指示程序数据加载 CRC校验出错。此时需要复位FPGA,重新加载。

4、嵌入式 的驱动实现

本文以模块形式实现了运行于上的驱动程序,源文件如下(有关寄存器

的设置参考的数据手册,以下源代码未包含头文件):

#define GPIO_va_ 0x0F6000000

//基于S3C2410 上的Linux内核IO控制寄存器首地址映射后的虚拟地址

#define ARM_GPDCON PIO_va_+0x30);

#define ARM_GPDUP PIO_va_+0x38);

#define ARM__wr(addr,) *(volatile unsigned int*)(addr)=)

//定义输出

#define FPGA_CS 8

#define FPGA_RW 9

#define FPGA_PROG 12

#define FPGA_CCLK 14

//定义操作

#define ARM_GPDDAT (*(volatile u32 *)(GPIO_va_base+0x34))

#define set_register_bit(x) ARM_GPDDAT=(1《《x)|ARM_GPDDAT

#define _register_bit(x) ARM_GPDDAT=(~(1《《x))&ARM_GPDDAT

//定义输入

#define FPGA_INIT ((ARM_GPDDAT》》10)&1)

#define FPGA_BUSY ((ARM_GPDDAT》》11)&1)

#define FPGA_DONE ((ARM_GPDDAT》》13)&1)

#define FPGA 211

//定义主设备号,和mknod /dev/ c 211 0匹配

typedef __t;

statIC __t fpga_s[257];

buf[1000000];

int fpga_(struct inode *, struct file *);

ssize_t fpga_write(struct file *, *,size_t ,loff_t *);

int fpga_(struct inode*, struct file *);

//初始化ARM的D组通用IO管脚

void _fpga(void){

ARM__wr(GPIO_va_base+0x30,0x55555555);

//FPGA_BUSY FPGA_DONE FPGA_INIT be set input

ARM__wr(GPIO_va_base+0x34,0xFFFF);

ARM_port_wr(GPIO_va_base+0x30,0x51055555);

ARM_port_wr(GPIO_va_base+0x38,0);// put up

set_register_bit(FPGA_CCLK);//set GCLK

}

statIC struct file_operations fpga_ctl_fops= {

: fpga_,

write: fpga_write,

: fpga_,};

int _(void) {

printk(“,word,Now preparing FPGA.。。.。。\n”);

printk(“register FPGA.。。.。。\n”);

register_chrdev(FPGA, “fpga”, &fpga_ctl_fops);

printk(“Done!\n”);

printk(“,word,success!\n”);

0;

}

int fpga_open(struct inode *inode, struct file *filp){

int minor;

minor = MINOR(inode-》i_rdev);

_fpga();

fpga_[minor]++;

printk(“FPGA is ready.\n”);

0;

}

ssize_t fpga_write(struct file *, char *buffer,size_t count,loff_t

*ppos){

int i;

if(__(buf,buffer,count)){

printk(“error \n”);

-EFAULT;

}

printk(“%d s have been received!\n”,count);

printk(“The is:%d\n”,count);

for(i=0;i《count;i++){

ARM_GPDDAT=(ARM_GPDDAT&0x3F00)|buf[i];

set_register_bit(FPGA_CCLK);

}

printk(“data write finished\n”);

for(i=0;i《4;i++){

set_register_bit(FPGA_CCLK);

_register_bit(FPGA_CCLK);

}

return count;

}

int fpga_release(struct inode *inode, struct file *filp){

int minor;

minor = MINOR(inode-》i_rdev);

if (fpga_[minor])

fpga_[minor]--;

printk(“Goodbye cruel world\n”);

return 0;

}

void cleanup_(void){

printk(“Goodbye cruel world\n”);

}

5、结束语

本文的创新点:基于ARM-Linux平台,实现了FPGA的程序加载模式,加载速度快,灵活高效。

猜您喜欢


贴片电阻功率表是一款专门用于测量贴片电阻功率的精密仪器。它能够快速、准确地测量各种尺寸和阻值的贴片电阻的实际功率,帮助工程师和技术人员评估电路性能、优化设计,并...
2025-04-14 15:02:25
关于继电保护系统的简单介绍。首先简单了解一下继电保护系统构成。继电保护的根本任务是检测并发现故障,然后通过断路器切除故障设备。因此,一个完整的继电保护系统至少应...
2023-08-16 14:18:00
四端子电阻凭借其高精度和稳定性,成为不可少的元器件。作为知名品牌,TA-I(大毅)四端子电阻凭借优良的品质和多样的型号,深受工程师和技术人员的青睐。本文将全面介...
2014-04-30 14:24:10
现代电子设备中,贴片电阻是重要的元件。小型化、便于自动化生产而被应用于各种电子产品中。了解不同型号的贴片电阻及其对照关系,对于工程师和设计师来说非常重要。本文将...
2025-04-19 00:30:39
视觉传感是人类感知外界、认知世界的主要途径,研究表明人类获取的外界信息大约有80%来自于视觉。作为感知外界信息的“电子眼球”,视觉传感器是消费电子、机器视觉、安...
2023-11-27 09:50:00
测速电机是很常见的一种工业机械设备,它可以通过转速来检测机器设备的工作状态。这类电机具备简单、精确、可靠等优点,广泛用于各个行业领域。RADIO ENERGIE...
2023-09-15 11:39:00
电流检测电阻作为关键元件在电路中是重要配件。禾伸堂(HEC)作为知名的电子元器件制造商,其电流检测电阻凭借很好的性能和可靠的品质,赢得了的市场认可。本文将深入探...
2022-11-25 19:27:21
Kyocera(京瓷)作为知名的品牌,其分流器电阻因高精度和高可靠性广受欢迎。分流器电阻在电路中起到测量电流和保护电路的重要作用,而选择合适的品牌和类型对于电子...
2015-06-30 21:37:16
随着电子设备和工业自动化的发展,大功率绕线电阻器作为关键的电子元件,需求量不断攀升。对于采购商而言,选择专业的大功率绕线电阻器厂家批发,不仅能保证产品质量,还能...
2025-11-04 04:00:35
XLR(卡侬)连接器因其优良的性能和可靠性,应用于多个领域。在音频领域,XLR连接器常用于专业音响设备,如麦克风、混音台和音频处理器,确保高质量的音频传输和降低...
2018-12-28 00:00:00