跳转至

DMA使用说明

注意所有的内存、地址单位都是 Byte!没有特例!

首先 FPGA 是有一份内存的,在编写 HiLinux 这边的程序的时候,不需要考虑 FPGA 的部分,因为这部分内存只有 FPGA 才能访问得到。这部分内存的正式名字应该是 DMA。

我们需要先使用 int _aligned_malloc(void **memptr, size_t size); 来申请 HiLinux 和 FPGA 能够共同访问的内存。考虑到输入输出都可以使用这个共享内存,我们取两者的最大值初始化这片内存就好了。比如传 2 * 4096 * 4096 B 的数据,size 给这个值就可以了。

在将数据从 HiLinux 写入到 FPGA 的 DMA 时,我们使用的函数是 int XPcie_DMA_Write(int fd, uint32_t addr, char *buffer, size_t size);。这里的 buffer 需要给入共享内存。

在将数据从 FPGA 的 DMA 读取到 HiLinux 的内存中时,我们使用的函数是 int XPcie_DMA_Read(int fd, uint32_t addr, char *buffer, size_t size);,这里的 buffer 需要给入共享内存。

读取之后,HiLinux 程序可以直接读取共享内存中的数据,这就是 FPGA 返回的处理结果存储的地方。

程序结束时,需要注意使用 void _aligned_free(void *buf); 释放共享内存

附 XPcie_Lib.h

#include <unistd.h>
#include <assert.h>
#include <fcntl.h>
#include <getopt.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#ifdef XPCIE_DLL_EXPORTS
#define XPCIE_DLL_API
#else
#define XPCIE_DLL_API
#endif

//板卡信息
#define MAX_CARDNUM 8
typedef struct{
    int nBoardNum;
    struct {
        unsigned short vendor;
        unsigned short device;
        int nBoardID;
    } BOARDINDEX[MAX_CARDNUM];
} XPCIE_BOARDINFO, *PXPCIE_BOARDINFO;

#ifdef __cplusplus
extern "C" {
#endif
    /*-
    Function name     : _aligned_malloc
    Description       : 申请通道缓冲区
    Parameter
    @ memptr          : 缓冲区指针
    @ size            : 缓冲区大小
    * Return          : 失败返回<0
    -*/
    int _aligned_malloc(void **memptr, size_t size);

    /*-
    Function name     : _aligned_free
    Description       : 释放通道缓冲区
    Parameter
    @ buf             : 缓冲区指针
    * Return          : 
    -*/
    void _aligned_free(void *buf);

    /*-
    Function name     : XPcie_GetBoardListInfo
    Description       : 获取板卡列表信息
    Parameter
    @ pXPcieBoardInfo : 板卡信息
    * Return          : 
    -*/
    XPCIE_DLL_API void XPcie_GetBoardListInfo(PXPCIE_BOARDINFO pXPcieBoardInfo);

    /*-
    Function name : XPcie_Device_Open
    Description   : 打开板卡
    Parameter
    @ fd          : 板卡号
    * Return      : 成功返回要打开的板卡号,失败返回-1
    -*/
    XPCIE_DLL_API int XPcie_Device_Open(int fd);

    /*-
    Function name : XPcie_Device_Close
    Description   : 关闭板卡
    Parameter
    @ fd          : 板卡号
    * Return      : 成功返回0
    -*/
    XPCIE_DLL_API int XPcie_Device_Close(int fd);

    /*-
    Function name : XPcie_DMA_Read_Init
    Description   : 接收通道初始化
    Parameter
    @ fd          : 板卡号
    @ size        : DMA大小
    * Return      : 成功返回0,否则<0
    -*/
    XPCIE_DLL_API int XPcie_DMA_Read_Init(int fd, size_t size);

    /*-
    Function name : XPcie_DMA_Read
    Description   : 接收通道传输数据
    Parameter
    @ fd          : 板卡号
    @ addr        : DDR地址(未使用,可随意传)
    @ buffer      : 上行数据接收缓冲区
    @ size        : DMA大小
    * Return      : 成功返回传输数据长度,否则<0
    -*/
    XPCIE_DLL_API int XPcie_DMA_Read(int fd, uint32_t addr, char *buffer, size_t size);

    /*-
    Function name : XPcie_DMA_Write_Init
    Description   : 接收通道初始化
    Parameter
    @ fd          : 板卡号
    @ size        : DMA大小
    * Return      : 成功返回0,否则<0
    -*/
    XPCIE_DLL_API int XPcie_DMA_Write_Init(int fd, size_t size);

    /*-
    Function name : XPcie_DMA_Write
    Description   : 发送通道传输数据
    Parameter
    @ fd          : 板卡号
    @ addr        : DDR地址(未使用,可随意传)
    @ buffer      : 下行数据接收缓冲区
    @ size        : DMA大小
    * Return      : 成功返回传输数据长度,否则<0
    -*/
    XPCIE_DLL_API int XPcie_DMA_Write(int fd, uint32_t addr, char *buffer, size_t size);

    /*-
    未使用
    Function name : XPcie_Write_Reg
    Description   : 写寄存器
    Parameter
    @ fd          : 板卡号
    @ addr        : 寄存器地址
    @ value       : 写入寄存器的值
    * Return      : 成功返回0,失败返回-1
    -*/
    XPCIE_DLL_API int XPcie_Write_Reg(int fd, long addr, unsigned int value);

    /*-
    未使用
    Function name : XPcie_Read_Reg
    Description   : 读取寄存器
    Parameter
    @ fd          : 板卡号
    @ addr        : 寄存器地址
    * Return      : 成功返回寄存器里的值,失败返回-1
    -*/
    XPCIE_DLL_API unsigned int XPcie_Read_Reg(int fd, long addr);

    /*-
    Function name : XPcie_Reset_Device
    Description   : FPGA复位
    Parameter
    @ fd          : 板卡号
    * Return      :
    -*/
    XPCIE_DLL_API void XPcie_Reset_Device(int fd);
#ifdef __cplusplus
}
#endif  /* end of __cplusplus */