资讯详情

DE1-SoC软件实验(三)—— HPS控制FPGA端的LED,实现流水灯的效果

文章目录

  • 实验目的
  • 实验内容
  • 知识需求
  • 实现的原理
  • hps_0.h理解头文件
  • C程序编写
  • 下载sof文件到开发板
  • 启动DE1-SoC中的Linux系统执行例程

实验目的

这个实验是为了学习HPS(ARM)如何和FPGA进行交互。

实验内容

演示 HPS(ARM)如何控制FPGA端的LED。(FPGA端的LED作为外设,从而实现HPS控制外设)

知识需求

本实验主要分为硬件设计和软件设计两部分。Quartus硬件设计和C程序设计)

HPS和FPGA协议通信主要通过AXI包括高速总线 HPS-to-FPGA AXI、FPGA-to-HPS AXI以及Light-weight HPS-to-FPGA AXI。

当HPS作为主端(master)它可以访问FPGA端Avalon MM slave接口的所有组件,HPS作为主端AXI-Bridge包括:

  • HPS-to-FPGA AXI
  • Light-weight HPS-to-FPGA AXI

FPGA作为主端AXI-Bridge包括:

  • FPGA-to-HPS AXI 本实验采用 HPS-to-FPGA AXI 来实现HPS控制FPGA端的LED

实现的原理

下面描述一下如何基于下面的内容ARM(HPS)的Linux应用程序 来控制FPGA端的PIO另外,控制器是连接的HPS lw h2f 因此,它可以在总线上获得HPS物理地址空间在总线。基于这个物理地址空间,我们可以使用它Linux内核内存映射设备(memory-mapped device)驱动访问PIO控制器寄存器可以控制LED的行为。采用应用程序DS-5编写编译。

hps_0.h理解头文件

在软件实验二中,已经解释了如何生成hps_0.h头文件。头文件有什么用?

该文件包含在该文件中 qsys配置一些信息。 例如: 包含了PIO控制器在Qsys相对于中分配lwh2fAXI的基地址 它表现为宏定义PIO_LED_BASE PIO控制器位宽信息表示宏定义PIO_LED_DATA_WIDTH 驱动访问寄存器时使用这两个参数

#define PIO_LED_BASE 0x0 #define PIO_LED_DATA_WIDTH 10 

C程序编写

打开SOCEDS,输入elcipse&,跳转打开DS-5软件,软件中新建C项目并在项目中建立source文件。

编写如下C程序,并进行全编译,未出现错误,即可得到可执行文件。

具体步骤与实验相同。

#include <stdio.h> #include <unistd.h> #include <fcntl.h> #include <sys/mman.h> #define soc_cv_av #include "hwlib.h" #include "socal/socal.h" #include "socal/hps.h" #include "socal/alt_gpio.h" #include "hps_0.h"  #define HW_REGS_BASE ( ALT_STM_OFST ) #define HW_REGS_SPAN ( 0x04000000 ) #define HW_REGS_MASK ( HW_REGS_SPAN - 1 )

int main() { 
        

	void *virtual_base;
	int fd;
	int loop_count;
	int led_direction;
	int led_mask;
	void *h2p_lw_led_addr;

	// map the address space for the LED registers into user space so we can interact with them.
	// we'll actually map in the entire CSR span of the HPS since we want to access various registers within that span
	//打开内存映射设备
	if( ( fd = open( "/dev/mem", ( O_RDWR | O_SYNC ) ) ) == -1 ) { 
        
		printf( "ERROR: could not open \"/dev/mem\"...\n" );
		return( 1 );
	}
	//将寄存器物理地址空间映射到用户空间
	virtual_base = mmap( NULL, HW_REGS_SPAN, ( PROT_READ | PROT_WRITE ), MAP_SHARED, fd, HW_REGS_BASE );

	if( virtual_base == MAP_FAILED ) { 
        
		printf( "ERROR: mmap() failed...\n" );
		close( fd );
		return( 1 );
	}
	//PIO的虚拟地址被定义为空指针h2p_lw_led_addr,后可用该指针变量访问PIO控制器的寄存器
	h2p_lw_led_addr=virtual_base + ( ( unsigned long  )( ALT_LWFPGASLVS_OFST + PIO_LED_BASE ) & ( unsigned long)( HW_REGS_MASK ) );
	

	// toggle the LEDs a bit
	//流水灯的切换
	loop_count = 0; //初始化,并循环60次
	led_mask = 0x01;
	led_direction = 0; // 0: left to right direction 
	while( loop_count < 60 ) { 
        
		// control led, add ~ because the led is low-active
		//led灯低电平有效,因此加~
		*(uint32_t *)h2p_lw_led_addr = ~led_mask; 

		// 把进程挂起一段时间 wait 100ms
		usleep( 100*1000 );
		
		// update led mask
		if (led_direction == 0){ 
        
			led_mask <<= 1;  
			if (led_mask == (0x01 << (PIO_LED_DATA_WIDTH-1)))
				 led_direction = 1; //从右到左
		}else{ 
        
			led_mask >>= 1; 
			if (led_mask == 0x01){ 
         
				led_direction = 0; //从左到右
				loop_count++;
			}
		}
		
	} // while

	// clean up our memory mapping and exit
	
	if (munmap(virtual_base, HW_REGS_SPAN) != 0) { 
        
		printf("ERROR: munmap() failed...\n");
		close(fd);
		return(1);
	}
	close( fd );
	return( 0 );
}

在这里插入图片描述 my_hps_led为生成的可执行文件,将其右键复制到SD卡中即可。

下载sof文件到开发板

由于此LED灯采用的是开发板FPGA部分的LED灯,因此我们需要将硬件设计的工程全编译,得到sof文件,将sof文件下载到开发板中。

启动DE1-SoC中的Linux系统执行例程

打开putty以root用户登录终端 找到我们复制到SD卡中的文件,my_hps_led,并将该可执行程序复制到根目录 采用命令修改可执行文件的权限

chmod 777 my_hps_led

采用命令运行 可执行文件

./my_hps_led

此时即可看到开发板上的LED灯做60次的流水灯操作。

总结: 本实验分为两个大的部分,硬件设计和软件设计。

  • 硬件设计:采用quartus中的qsys来搭建硬件系统,将我们所需要的led组件配置进来,并将其例化到顶层中,全编译即可生成sof文件,以及sopcinfo文件。 sof文件需要将其下载到开发板 sopcinfo文件用来根据sh文件生成hps_0.h头文件
  • 软件设计:采用DS-5软件来编写C程序,重点包括了LED的控制方式,以及通过硬件文件生成的hps_0.h头文件,全编译生成可执行文件,并将其放到SD卡。

最终我们将quartus生成的sof文件下载到开发板,采用串口终端调试软件putty 以实现在开发板上运行Linux系统,并通过命令找到我们所需要的可执行文件,修改权限并执行,至此,即可在开发板上看到实验效果。

标签: hps拉绳位稳传感器

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台