一、SoC 外设简介
fpga与hps交互
axi与avalon总线
Avalon总线接口
- 流接口
- mm接口
- slave从接口
一般SoC使用的是mm slave接口
avalon-mm系统
ip外设
外设访问流程
1、获取总线虚拟地址
2、计算外设地址
3、映射外设接口
4、操作
5、关闭虚拟地址
二、SoC led原理图
三、工程代码
1.hps_0.h
#ifndef _ALTERA_HPS_0_H_
#define _ALTERA_HPS_0_H_
/*
* This file was automatically generated by the swinfo2header utility.
*
* Created from SOPC Builder system 'soc_system' in
* file './soc_system.sopcinfo'.
*/
/*
* This file contains macros for module 'hps_0' and devices
* connected to the following masters:
* h2f_axi_master
* h2f_lw_axi_master
*
* Do not include this header file and another header file created for a
* different module or master group at the same time.
* Doing so may result in duplicate macro names.
* Instead, use the system header file which has macros with unique names.
*/
/*
* Macros for device 'led_pio', class 'altera_avalon_pio'
* The macros are prefixed with 'LED_PIO_'.
* The prefix is the slave descriptor.
*/
#define LED_PIO_COMPONENT_TYPE altera_avalon_pio
#define LED_PIO_COMPONENT_NAME led_pio
#define LED_PIO_BASE 0x0
#define LED_PIO_SPAN 16
#define LED_PIO_END 0xf
#define LED_PIO_BIT_CLEARING_EDGE_REGISTER 0
#define LED_PIO_BIT_MODIFYING_OUTPUT_REGISTER 0
#define LED_PIO_CAPTURE 0
#define LED_PIO_DATA_WIDTH 4
#define LED_PIO_DO_TEST_BENCH_WIRING 0
#define LED_PIO_DRIVEN_SIM_VALUE 0
#define LED_PIO_EDGE_TYPE NONE
#define LED_PIO_FREQ 50000000
#define LED_PIO_HAS_IN 0
#define LED_PIO_HAS_OUT 1
#define LED_PIO_HAS_TRI 0
#define LED_PIO_IRQ_TYPE NONE
#define LED_PIO_RESET_VALUE 0
/*
* Macros for device 'sysid_qsys', class 'altera_avalon_sysid_qsys'
* The macros are prefixed with 'SYSID_QSYS_'.
* The prefix is the slave descriptor.
*/
#define SYSID_QSYS_COMPONENT_TYPE altera_avalon_sysid_qsys
#define SYSID_QSYS_COMPONENT_NAME sysid_qsys
#define SYSID_QSYS_BASE 0x10
#define SYSID_QSYS_SPAN 8
#define SYSID_QSYS_END 0x17
#define SYSID_QSYS_ID 2899645186
#define SYSID_QSYS_TIMESTAMP 1653029485
#endif /* _ALTERA_HPS_0_H_ */
2.main.c
/*
* main.c
*
* Created on: 2022年5月20日
* Author: stark-lin
*/
//gcc标准头文件
#include <stdio.h>//标准输入输出
#include <unistd.h>//unix std
#include <stdlib.h>//头文件定义了四个变量类型、一些宏和各种通用工具函数
#include <fcntl.h>//是unix标准中通用的头文件, open,fcntl,shutdown,unlink,fclose
#include <sys/mman.h>//mmap所在头文件
//HPS厂家提供的底层定义的头文件
#define soc_cv_av//开发平台Cyclone V系列
#include "hwlib.h"
#include "socal/socal.h"
#include "socal/hps.h"
//与具体的HPS,看自己的设计,应用系统相关的硬件描述头文件
#include "hps_0.h"
#define HW_RGES_BASE (ALT_STM_OFST)//HPS外设地址段基地址
#define HW_RGES_SPAN (0x04000000)//HPS外设地址空间64MB
#define HW_RGES_MASK (HW_RGES_SPAN - 1)//HPS外设地址掩码
static volatile unsigned long *led_pio_base = NULL;//led地址指针,volatile避免优化
int fpga_init(int *virtual_base){
int fd;
void *per_virtual_base;
//打开mmu
fd = open("/dev/mem", (O_RDWR | O_SYNC));
if(fd == -1){
printf("ERROR: open is failed\n");
exit(0);
}
//外设地址映射到用户空间,mmap()
per_virtual_base = mmap(NULL, HW_RGES_SPAN, (PROT_READ | PROT_WRITE), MAP_SHARED,
fd, HW_RGES_BASE);
if(per_virtual_base == MAP_FAILED){
printf("ERROR: mmap is failed\n");
close(fd);
}
//外设地址 = 虚拟地址+外设偏移地址(mm_bridge + 桥上偏移地址)
led_pio_base = per_virtual_base + ((unsigned long)(ALT_LWFPGASLVS_OFST + LED_PIO_BASE) & (unsigned long)(HW_RGES_MASK));
*virtual_base = per_virtual_base;
return fd;
}
int main(){
int virtual_base;
int fd;
fd = fpga_init(&virtual_base);
//操作外设
while(1){
*(led_pio_base + 0) = 0x000000ff;
sleep(2);
*(led_pio_base + 0) = 0x00000000;
sleep(2);
}
//取消地址映射
if(munmap(&virtual_base, HW_RGES_SPAN) == -1){
printf("ERROR: munmap is failed\n");
close(fd);
}
//关闭mmu
close(fd);
return 0;
}