de1-soc培训教材记录

2023-05-16

第一章 准备

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

  1. 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.
  2. find_fast_cwd: WARNING: Couldn’t compute FAST_CWD pointer

解决方法

  1. 打开同路径下的ds-5_installer,在同路径下安装ds-5。注意ds-5在ECS 13.1环境下需要安装在同路径下,否则shell无法找到
  2. 出现这个错误是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设置
如图保存设置后,打开开发板电源,点击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盘传输

  1. 电脑中的文件拷贝到U盘中
  2. U盘插到DE1-soc的USB接口,1、2均可
  3. 输入命令mount –t vfat /dev/sda1 /mnt,将U盘挂载到开发板上
  4. 拷贝命令 cp /mnt/test.doc /home/root/test.doc将test.doc复制到root路径下

2. ftp传输

  1. 安装计算机文件传输工具filezillawinscp
  2. 开发板插入网线
  3. 检查linux中curl版本 curl –v/–version
  4. 写登陆网络的脚本
  5. 保存为connect.sh,然后chmod 777 conncect.sh。运行./connect.sh,连接校园网。
  6. 若./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所需文件

  1. 通过Quartus 中的设计工具Qsys选择设计所需的硬件模块,定义Soc FPGA系统的硬件架构。原本是需要同时设计好HPS和FPGA两个部分,但HPS部分原则上只要修改de1_soc_training\lab\HW中的DE1_Soc_GHRD项目即可。FPGA部分,如LED/Button PIO组件,可自己手动添加。
  2. generate生成Qsys系统。它生成了可以被Quartus编译的HDL文件。

2.2 Quartus生成FPGA所需的.soc文件,下载并测试。

  1. assignments-settings中增加soc_system.qip和soc_system_timing.sdc
  2. 修改ghrd_top.v中soc_system u0模块中led_pio_external_connection_export(LEDR)/button_pio_external_connection_export(KEY)
  3. analysis and synthesis
  4. 打开tools-tcl script,选择hps_sdram_p0_pin_assignments.tcl,然后run
    complication
  5. 下载.soc置de1-soc中
  6. 根据培训教材测试

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过程【软件实验中没有用到】

  1. 使用soc eds目录中的embedded command shell.bat启动bsp-editor
  2. 选择handoff\soc_system_hps_0文件夹中的配置,则系统在工程内产生software文件夹,并产生settings.bsp文件。
  3. 按下bsp-editor的generate按钮,生成preloader的原始文档以及makefile。文档存放位置为software\spl_bsp\generated文件夹下
  4. 然后使用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文件夹下.
  5. 最后将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 *~

编译运行步骤

  1. 使用embedded command shell.bat编译,在main.c和Makefile的路径下输入命令“make”,生成了my_first_hps文件
  2. 将my_first_hps通过网络/U盘放入DE1-SoC linux系统中
  3. 使用命令“chmod 777 my_first_hps”将my_first_hps改为可执行文件
  4. 输入命令“./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;      
    // 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 );
    }
    // initialize the pio controller
    // led: set the direction of the HPS GPIO1 bits attached to LEDs to output
    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 ) ) ) );      
        //usleep(1000*1000);        
        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 );
    }   
    // 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 );
}

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. 编译运行步骤

  1. 同软件实验一,使用embedded command shell.bat编译,在main.c和Makefile的路径下输入命令“make”,生成了hps_gpio文件
  2. 将hps_gpio通过网络/U盘放入DE1-SoC linux系统中
  3. 使用命令“chmod 777 hps_gpio”将hps_gpio改为可执行文件
  4. 输入命令“./ 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

  1. 与硬件实验的步骤相同,建Quartus工程,使用Qsys生成SOPC info file(.sopcinfo)文件,该文件存放在Quartus工程的目录下
  2. 在Quartus工程路径下编写文件generate_hps_qsys_header.sh。该脚本用来生成hps头文件hps0.h。
  3. 打开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;

    // 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 );
    }

    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;
    led_mask = 0x01;
    led_direction = 0; // 0: left to right direction
    while( loop_count < 60 ) {

        // control led,  add ~ because the led is low-active
        *(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 );
}

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 编译运行

  1. embedded command shell.bat生成文件my_first_hps-fpga,放入Linux中
  2. 编译Quartus工程,将.soc文件下载到DE1-soc中
  3. 可以观察到FPGA的10颗LED闪烁60次
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

de1-soc培训教材记录 的相关文章

  • 无人机、无人车仿真器AirSim中激光雷达Lidar设置

    1 在车辆或无人机中激活激光雷达 默认情况下 xff0c 激光雷达是不开启的 xff0c 如果需要开启激光雷达 xff0c 则需要在settings jason文件中进行激活 xff0c settings jason 文件位于 Docume
  • 软件项目产品化之路

    软件项目产品化之路 2 产品化之路 2 1 困惑 软件项目产品化是大量软件企业 xff0c 特别是应用型软件研发企业所必须面临的问题 不论是小型的软件公司和中大型的软件企业 xff0c 在面对软件项目和软件产品 xff0c 都有诸多困惑 到
  • 软件产品化的一些见解

    软件产品化的定义 软件产品化 即客户无需为软件添加或调整代码和语句即能完成软件的安装配置 应用初始化 系统管理 用户使用的全过程 并且软件至少能满足80 以上的用户某一组应用需求 软件产品化只是完成了产品的生产环节 后面的产品销售 市场推广
  • 程序员与工匠精神

    前几天和一个朋友聊天时说 xff1a 我有强迫症 xff0c 每次看到不符合自己审美的代码时 xff0c 总想重构一下 朋友的观点与大多数人相仿 xff0c 程序只要满足要求 xff0c 运行正确就可以 在现实的工作中一样 xff0c 每当
  • linux 进程线程思维导图

  • 修改结构体中成员的值

    include lt iostream gt using namespace std struct student char name 10 float grade 更改student数据的grade成员 xff0c 参数形式为引用 voi
  • C++中冒号的用法

    1 冒号 xff08 xff09 用法 xff08 1 xff09 表示机构内位域的定义 xff08 即该变量占几个bit空间 xff09 typedef struct XXX unsigned char a 4 unsigned char
  • C/C++预处理指令

    本文主要记录了C C 43 43 预处理指令 xff0c 常见的预处理指令如下 xff1a 空指令 xff0c 无任何效果 include包含一个源代码文件 define定义宏 undef取消已定义的宏 if如果给定条件为真 xff0c 则
  • STM32F1常用外设介绍(超详细35000字介绍)

    STM32学习笔记 GPIO配置步骤 步骤 xff1a 第一步 xff0c 使用RCC开启GPIO的时钟 第二步 xff0c 使用GPIO Init 函数初始化GPIO 第三步 xff0c 使用输出或者输入的函数控制GPIO口 常用的RCC
  • MFC拷贝文件及进度条显示

    参考 xff1a 封装CopyFileEx函数 xff0c 实现文件复制中的暂停 xff0c 控速 xff0c 获取进度 http blog csdn net career2011 article details 6844513 实例讲解C
  • 什么是寄存器?(STM32)

    什么是寄存器 xff1f 我们现在在开发STM32时 xff0c 已经很少用到寄存器编程 xff0c 更多的使用ST公司所提供的标准库和最新的HAL库进行编程实现 xff0c 但是不管是标准库还是HAL库都是在原来的寄存器层面上进行了封装
  • 计算机网络——物理层(一)

    物理层 xff08 部分 xff09 机械特性 xff1a 指明接口所用接线器的形状和尺寸 引脚数目和排列 固定和锁定装置等 电气特性 xff1a 指明在接口电缆的各条线上出现的电压的范围 功能特性 xff1a 指明某条线上出现的某一电平的
  • 洛谷P5717-三角形分类

    洛谷P5717 三角形分类 题目 这道题更像是初中题 xff0c 但是怎么能完整的按照题目的意思来解决呢 xff0c 说实话这个题卡了我有一会儿 xff0c 要做一次性做出这个题 xff0c 我觉得需要搞清楚if if 和if else i
  • 洛谷P1424-小鱼的航程(改进版)

    洛谷P1424 小鱼的航程 xff08 改进版 xff09 这个题我第一次做的时候 xff0c 有两个没过 xff0c 后来检查的时候发现原来是没有考虑开始的时间是不是周六周日 xff0c 如果是周六要在原来的天数上 2 xff0c 如果是
  • freertos-简介(一)

    FreeRTOS 裸机 不带任何操作系统 只能先打完游戏回复信息 实时性差 xff0c 程序轮流执行delay空等待 xff0c CPU不执行其他代码结构臃肿 xff0c 实现功能都在while循环 RTOS 实时操作系统 会执行打游戏一个
  • PCB设计过程中AD使用流程详解(超详细)

    PCB设计过程中AD使用流程详解 xff08 超详细 xff09 1 设计前期部分 规则设定 xff1a Preference system file type关联文件 xff08 所有关联 xff09 PCB editor General
  • python面向对象编程

    符合python风格的对象 先来看一个向量类的例子 span class token keyword class span span class token class name Vector2d span span class token
  • DIY 一个树莓派无人机

    学习目标 xff1a DIY 一个树莓派无人机 这篇文章来源于DevicePlus com英语网站的翻译稿 提示 xff1a 这里可以添加学习目标 学习内容 xff1a 提示 xff1a 这里可以添加要学的内容 今天 xff0c 我们将利用
  • Linux开源杀毒软件CLamAV介绍

    Linux开源杀毒软件CLamAV介绍 很多用户可能不知道在Linux上会有计算机病毒 xff0c 虽然Linux上的病毒不像在Windows上那么常见 xff0c 但实际上 xff0c 很多重要系统均采用Linux系统作为服务器的操作系统
  • vrpn_cient_ros发送频率无法调整提供解决思路

    最近写了节点来订阅ros client ros 但是发现在launch文件修改update frequency不起作用 xff0c 然而我又需要通过串口给下位机发送数据 xff0c 频率一快 xff0c 串口直接堵死了 怎么调都freque

随机推荐