HPS_FPGA之间的地址映射学习
- HPS 如何对FPGA外设进行操作?
hardware:在Qsys中将外设连接到AXI bridge上
software:映射外设物理地址到到应用程序可以操作的虚拟地址,应用程序通过得到的虚拟地址入口控制外设。- 为什么要进行地址映射?
内存映射就是讲内核空间的一部分区域映射到用户空间,用户对这段内存空间的修改可以反映到内核空间。可以将内核空间的一段地址映射到多个进程,以实现线程间的内存通信。系统调用mmap()就是进行地址映射。mmap是将一个文件(linux下设备也被看做是文件)或其他对象映射进内存。munmap执行相反的操作,删除特定地址区域的对象映射。
转自:http://bbs.eeworld.com.cn/thread-458492-1-1.html
地址映射要用到mmap函数,映射物理地址到内存空间(即虚拟地址,因为操作系统只能访问虚拟地址[应用层])。
相关的虚拟地址已经可以直接到应用的层级,相关的设定已经在embedded中给出:轻量级别的由总线下来的第一个偏移地址已经由别人提供,是hps.h中的ALT_LWFPGASLVS_OFST。在此基础上加上在Qsys中的基地址就可以完全对应一个ip部件并对其进行相关的操作。只需要调用相应的.h调用即可,lw在此基础上得到了很大的实惠。而HPS内部的调用直接用地址就可以,只需要在Qsys中设定其基地址就可以构造其虚拟地址在C中编程。
首先打开硬件设备映射器,在其中限定其可访问的范围,这个值在Qsys中已经设定,在C中的设定只要是在Qsys设定的范围内都可以接受,对其进行相关的设定后,就可以在C中操作了。其意义就是将对象搬到HPS中来进行处理,并通过控制IP来对相应的数据进行操作,即对IP的调用以达到对数据的控制操作,作为轻量级别的和其基地址来接受控制。
物理地址是CPU芯片地址引脚(假定内存控制器没有集成在CPU中)发出的访存地址,物理地址还要被内存控制机构(一般在北桥芯片中)进行译码或映射(映射的一个例子见本文最后17部分提到的“物理内存回收”),可能实际指向DRAM(就是前面提到的内存条),也可能通过一些外部总线(比如PCI)指向各种外部设备。对外部设备的这种访问一般也称为MMIO:Memory Mapped I/O——内存映射I/O。
另外特别提一下,x86支持用I/O指令(IN、OUT)寻址的另外的独立64K I/O地址空间,该地址空间不要和这里物理内存地址混淆。
采用共享内存进行通信的优点是效率高,直接读写内存不需要进行数据拷贝。
通常使用mmap有三种情况,1、提高I/O效率 2、匿名内存映射 3、共享内存进程通信。
mmap用于内存映射的一种方式是打开或创建一个文件,然后调用mmap().(另一种方式如下:进程A和进程B都将该页映射到自己的地址空间,当进程A第一次访问该页中的数据时产生一个缺页中断,内核此时读入这一页到内存并更新页表使之指向它,当进程B访问同一页发生缺页中断时,该页已经在内存中,内核只需要将进程B的页表登记项指向此页即可)
一开始的时候没有找到硬件手册,于是傻傻地跑去看了由uboot.scr产生,在目录project direction\software\spl_bsp\generated\sdram下有一个sdram_config.h文件,其中描述了各个FPGA接口的地址,其中有这么一段:
说明FPGA写入DDR3的数据是从0xFFFF0000开始写的,用这个作为偏移量就可以访问DDR3啦!
不过总感觉这么干有点怪怪的……