第一章 准备
1.1 安装软件
《Altera De1-SoC培训教材》中的环境
- quartus 13.1
- embedded command shell 13.1
- 我所用的linux是de1soc_lxde_1604
1.1.1下载链接 **
[1] 培训教材.https://pan.baidu.com/s/1uFRa-5kuf9m_q_UyVIRS4A
[2] Quartus下载. https://www.altera.com.cn/downloads/download-center.html
[3] DE1-SoC Board资源.https://www.terasic.com.tw/cgi-bin/page/archive.pl?Language=Taiwan&CategoryNo=173&No=869&PartNo=4
[4] Quartus 13.1 crack. https://pan.baidu.com/s/1xKbBXYKyD2_76tdNFyC9Sg
1.1.2 Embedded command shell出现问题
打开”~\altera\13.1\embedded”路径下的Embedded_Command_Shell.bat文件,出现两个warning
- WARNING: DS-5 install not detected in /cygdrive/d/altera/13.1/embedded/ds-5. SoC EDS may not function correctly without an embedded DS-5 install.
- find_fast_cwd: WARNING: Couldn’t compute FAST_CWD pointer
解决方法
- 打开同路径下的ds-5_installer,在同路径下安装ds-5。注意ds-5在ECS 13.1环境下需要安装在同路径下,否则shell无法找到
- 出现这个错误是embedded中的host_tools中cygwin版本过低,为1.7,应下载高版本如2.0。
1.2 驱动安装
开发板接通电源后,有两根线可以用来de1-soc与计算机连接
- USB-Blaster II。用于配置FPGA与HPS Debug。在quartus安装目录~\altera\13.1\quartus\drivers\usb-blaster-ii\路径下寻找驱动
- UART-to-USB。用于计算机与HPS通信。在《培训教材实验包》的tool\drivers\USB2UART_driver中寻找驱动
1.3 在DE1-SOC上运行Linux
1.3.1 电脑串口设置
使用串口终端工具putty与DE1-SOC连接。
如图保存设置后,打开开发板电源,点击putty中的open。注意串口不一定是COM3,要使用设备管理器查看
1.3.2 制作microSD card Image
使用tool工具包中Win32DiskImager将linux镜像刻录到microSD卡(4G以上)上
1.3.3 运行Linux
将刻录了Linux的SD卡插入开发板上microSD card的插槽上,打开开发板电源。
打开putty,load de1-soc_usb,点击open。
若putty没有反应,按下enter键,若开发板启动正常,应出现用户名输入。用户名为root,密码在下载的Linux镜像文件夹中找,是readme.txt。
1.3.4 计算机与开发板上linux进行数据传输
1. U盘传输
- 电脑中的文件拷贝到U盘中
- U盘插到DE1-soc的USB接口,1、2均可
- 输入命令mount –t vfat /dev/sda1 /mnt,将U盘挂载到开发板上
- 拷贝命令 cp /mnt/test.doc /home/root/test.doc将test.doc复制到root路径下
2. ftp传输
- 安装计算机文件传输工具filezilla或winscp
- 开发板插入网线
- 检查linux中curl版本 curl –v/–version
- 写登陆网络的脚本
- 保存为connect.sh,然后chmod 777 conncect.sh。运行./connect.sh,连接校园网。
- 若./connect.sh | iconv –f gbk –t utf-8出现”连接成功”字样,说明连接成功。
注意,如果是使用校园网登陆,不能固定ip。
网络登陆脚本connect.sh
#!/bin/bash
USERID=20**********
PASSWORD=20**********
echo login
curl ‘https://connect.cuc.edu.cn/action.jsp’ –data “act=1&userid=$USERID&passwd=$PASSWORD”
注意
使用SSH安全登录开发板,用到了SSH密匙。 putty和filezilla均通过密匙登录开发板。
之后filezilla可以传输文件了。
第二章 de1-soc硬件实验
2.1 Qsys生成HPS及FPGA所需文件
- 通过Quartus 中的设计工具Qsys选择设计所需的硬件模块,定义Soc FPGA系统的硬件架构。原本是需要同时设计好HPS和FPGA两个部分,但HPS部分原则上只要修改de1_soc_training\lab\HW中的DE1_Soc_GHRD项目即可。FPGA部分,如LED/Button PIO组件,可自己手动添加。
- generate生成Qsys系统。它生成了可以被Quartus编译的HDL文件。
2.2 Quartus生成FPGA所需的.soc文件,下载并测试。
- assignments-settings中增加soc_system.qip和soc_system_timing.sdc
- 修改ghrd_top.v中soc_system u0模块中led_pio_external_connection_export(LEDR)/button_pio_external_connection_export(KEY)
- analysis and synthesis
- 打开tools-tcl script,选择hps_sdram_p0_pin_assignments.tcl,然后run
complication - 下载.soc置de1-soc中
- 根据培训教材测试
2.3 Qsys生成的供SoC系统开发的文件
- SOPC info file(.sopcinfo):文档用于生成Device Tree
- Handoff Folder:里面有关于产生preloader相关配置文件【暂时用不到】
- System View Descr(.svd):用户DS-5 debug功能【暂时用不到】
解释
- Device Tree:Device Tree由一系列被命名的结点(node)和属性(property)组成,而结点本身可包含子结点。所谓属性,其实就是成对出现的name和value。https://blog.csdn.net/21cnbao/article/details/8457546
- preload:将目标文件加入RAM中,系统启动更快
- DS-5:调试用,基本用不到
2.3.1 生成preloader image file过程【软件实验中没有用到】
- 使用soc eds目录中的embedded command shell.bat启动bsp-editor
- 选择handoff\soc_system_hps_0文件夹中的配置,则系统在工程内产生software文件夹,并产生settings.bsp文件。
- 按下bsp-editor的generate按钮,生成preloader的原始文档以及makefile。文档存放位置为software\spl_bsp\generated文件夹下
- 然后使用embedded command shell.bat进入software\spl_bsp文件夹,make生成u-boot-spl和u-boot-spl.bin两个文件,前者是可执行文件preloader elf file,后者是二进制文件preloader binary file,两个文件在DE1_SoC_GHRD\software\spl_bsp\uboot-socfpga\spl文件夹下.
- 最后将u-boot-spl.bin复制到software\spl_bsp文件夹下,shell到该路径,输入指令mkpimage –o preloader_with_header.img u-boot-spl.bin生成preloader_with_header.img文件。
2.3.1 生成Device Tree
在软件实验三种用到了SOPC info file(.sopcinfo)
第三章 软件实验一
目标:在DE1-SoC上输出“Hello World\n”
文件:
main.c
#include <stdio.h>
int main(int argc, char **argv)
{
printf("hello world\n");
return 0;
}
Makefile
TARGET = my_first_hps
CROSS_COMPILE = arm-linux-gnueabihf-
CFLAGS = -g -Wall -I $(SOCEDS_DEST_ROOT)/ip/altera/hps/altera_hps/hwlib/include
LDFLAGS = -g -Wall
CC = $(CROSS_COMPILE)gcc
ARCH = arm
build: $(TARGET)
$(TARGET): main.o
$(CC) $(LDFLAGS) $^ -o $@
%.o : %.c
$(CC) $(CFLAGS) -c $< -o $@
.PHONY: clean
clean:
rm -f $(TARGET) *.a *.o *~
编译运行步骤:
- 使用embedded command shell.bat编译,在main.c和Makefile的路径下输入命令“make”,生成了my_first_hps文件
- 将my_first_hps通过网络/U盘放入DE1-SoC linux系统中
- 使用命令“chmod 777 my_first_hps”将my_first_hps改为可执行文件
- 输入命令“./my_first_hps”,可看到putty屏幕输出“hello world”
第四章 软件实验二
本实验与实验一相同,只用到DE1-SoC的HPS部分。只需在embedded command shell.bat中使用两个文件*.c和Makefile生成可执行文件,将文件传输到linux系统中并改成可执行文件,即可运行。
4.1. 目标
控制HPS的LED和KEY。运行可执行文件后,HPS的LED会先闪烁两次。之后按下HPS的KEY,LED亮起,否则熄灭。
4.2. 原理
通过linux内核memory-mapped device访问GPIO控制器。
4.3. 软件API
可以通过如下软件 API 访问 GPIO 控制器的寄存器
* open: 打开内存映射设备驱动
* mmap: 映射物理地址到用户空间
* alt_read_word: 从指定寄存器读取一个值
* alt_write_word: 写入一个值到指定寄存器
* munmap:清除内存映射
* close:关闭设备驱动
通过一些宏访问寄存器
* alt_setbits_word:设定制定寄存器的指定位为1
* alt_clrbits_word:设定制定寄存器的指定位为0
4.4. 关键命令
配置LED引脚为输出引脚
alt_setbits_word( (virtual_base + ( ( uint32_t )( ALT_GPIO1_SWPORTA_DDR_ADDR ) & ( uint32_t)( HW_REGS_MASK ) ) ), USER_IO_DIR );
点亮LED
alt_setbits_word( (virtual_base + ( ( uint32_t )( ALT_GPIO1_SWPORTA_DR_ADDR ) & ( uint32_t)( HW_REGS_MASK ) ) ), BIT_LED );
读取KEY值
alt_read_word( ( virtual_base + ( ( uint32_t )( ALT_GPIO1_EXT_PORTA_ADDR ) & ( uint_t )( HW_REGS_MASK ) ) ) );
4.5. 代码
main.c
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include "hwlib.h"
#include "socal/socal.h"
#include "socal/hps.h"
#include "socal/alt_gpio.h"
#define HW_REGS_BASE ( ALT_STM_OFST )
#define HW_REGS_SPAN ( 0x04000000 )
#define HW_REGS_MASK ( HW_REGS_SPAN - 1 )
#define USER_IO_DIR (0x01000000)
#define BIT_LED (0x01000000)
#define BUTTON_MASK (0x02000000)
int main(int argc, char **argv) {
void *virtual_base;
int fd;
uint32_t scan_input;
int i;
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 );
}
alt_setbits_word( ( virtual_base + ( ( uint32_t )( ALT_GPIO1_SWPORTA_DDR_ADDR ) & ( uint32_t )( HW_REGS_MASK ) ) ), USER_IO_DIR );
printf("led test\r\n");
printf("the led flash 2 times\r\n");
for(i=0;i<2;i++)
{
alt_setbits_word( ( virtual_base + ( ( uint32_t )( ALT_GPIO1_SWPORTA_DR_ADDR ) & ( uint32_t )( HW_REGS_MASK ) ) ), BIT_LED );
usleep(500*1000);
alt_clrbits_word( ( virtual_base + ( ( uint32_t )( ALT_GPIO1_SWPORTA_DR_ADDR ) & ( uint32_t )( HW_REGS_MASK ) ) ), BIT_LED );
usleep(500*1000);
}
printf("user key test \r\n");
printf("press key to control led\r\n");
while(1){
scan_input = alt_read_word( ( virtual_base + ( ( uint32_t )( ALT_GPIO1_EXT_PORTA_ADDR ) & ( uint32_t )( HW_REGS_MASK ) ) ) );
if(~scan_input&BUTTON_MASK)
alt_setbits_word( ( virtual_base + ( ( uint32_t )( ALT_GPIO1_SWPORTA_DR_ADDR ) & ( uint32_t )( HW_REGS_MASK ) ) ), BIT_LED );
else alt_clrbits_word( ( virtual_base + ( ( uint32_t )( ALT_GPIO1_SWPORTA_DR_ADDR ) & ( uint32_t )( HW_REGS_MASK ) ) ), BIT_LED );
}
if( munmap( virtual_base, HW_REGS_SPAN ) != 0 ) {
printf( "ERROR: munmap() failed...\n" );
close( fd );
return( 1 );
}
close( fd );
return( 0 );
}
Makefile
TARGET = hps_gpio
CROSS_COMPILE = arm-linux-gnueabihf-
CFLAGS = -g -Wall -I ${SOCEDS_DEST_ROOT}/ip/altera/hps/altera_hps/hwlib/include
LDFLAGS = -g -Wall
CC = $(CROSS_COMPILE)gcc
ARCH= arm
build: $(TARGET)
$(TARGET): main.o
$(CC) $(LDFLAGS) $^ -o $@
%.o : %.c
$(CC) $(CFLAGS) -c $< -o $@
.PHONY: clean
clean:
rm -f $(TARGET) *.a *.o *~
4.6. 编译运行步骤
- 同软件实验一,使用embedded command shell.bat编译,在main.c和Makefile的路径下输入命令“make”,生成了hps_gpio文件
- 将hps_gpio通过网络/U盘放入DE1-SoC linux系统中
- 使用命令“chmod 777 hps_gpio”将hps_gpio改为可执行文件
- 输入命令“./ hps_gpio”,可看到开发板上属于HPS的LED灯先闪烁两次,然后按下HPS的按钮可以控制LED亮灭
第五章 软件实验三
本章实现HPS与FPGA交互。
5.1 目标
使用HPS控制FPGA的10颗LED灯闪烁60次
5.2 原理
FPGA端的PIO控制器pio_led连接到HPS/ARM lightweight axi bridge,获得在HPS/ARM总线上的物理地址空间。linux通过内核memory-mapped device驱动访问PIO控制器pio_led的寄存器物理地址,从而控制pio_led【同软件实验二】
5.3 过程
5.3.1 生成HPS头文件hps0.h
- 与硬件实验的步骤相同,建Quartus工程,使用Qsys生成SOPC info file(.sopcinfo)文件,该文件存放在Quartus工程的目录下
- 在Quartus工程路径下编写文件generate_hps_qsys_header.sh。该脚本用来生成hps头文件hps0.h。
- 打开embedded command shell,到Quatus工程路径下,输入命令”./generate_hps_qsys_header.sh”,生成hps头文件
generate_hps_qsys_header.sh
#!/bin/sh
export PATH=$PATH:/cygdrive/d/altera/quartus13.1/quartus/sopc_builder/bin
sopc-create-header-files "./soc_system.sopcinfo" --single hps_0.h --module hps_0
5.3.2 生成HPS可执行文件
注意hps0.h和main.c及Makefile在一个文件夹中
main.c
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#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;
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 );
}
h2p_lw_led_addr=virtual_base + ( ( unsigned long )( ALT_LWFPGASLVS_OFST + PIO_LED_BASE ) & ( unsigned long)( HW_REGS_MASK ) );
loop_count = 0;
led_mask = 0x01;
led_direction = 0;
while( loop_count < 60 ) {
*(uint32_t *)h2p_lw_led_addr = ~led_mask;
usleep( 100*1000 );
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++;
}
}
}
if( munmap( virtual_base, HW_REGS_SPAN ) != 0 ) {
printf( "ERROR: munmap() failed...\n" );
close( fd );
return( 1 );
}
close( fd );
return( 0 );
}
Makefile
TARGET = my_first_hps-fpga
CROSS_COMPILE = arm-linux-gnueabihf-
CFLAGS = -static -g -Wall -I${SOCEDS_DEST_ROOT}/ip/altera/hps/altera_hps/hwlib/include
LDFLAGS = -g -Wall
CC = $(CROSS_COMPILE)gcc
ARCH= arm
build: $(TARGET)
$(TARGET): main.o
$(CC) $(LDFLAGS) $^ -o $@
%.o : %.c
$(CC) $(CFLAGS) -c $< -o $@
.PHONY: clean
clean:
rm -f $(TARGET) *.a *.o *~
5.3.3 编译运行
- embedded command shell.bat生成文件my_first_hps-fpga,放入Linux中
- 编译Quartus工程,将.soc文件下载到DE1-soc中
- 可以观察到FPGA的10颗LED闪烁60次
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)