fpga demo测试hello world

一 看下机器上是什么fpga设备

root@bms-airtrunk-b-s11fpgav2-app-10-169-58-141:/data/# sudo fpgainfo fme

Board Management Controller, microcontroller FW version unavailable (I/O error)

Last Power Down Cause: Q){

Last Reset Cause: Software reset

Watchdog timeout

//****** FME ******//

Object Id : 0xEC00001

PCIe s:b:d:f : 0000:D8:00:0

Device Id : 0x09C4

Socket Id : 0x00

Ports Num : 01

Bitstream Id : 0x123000200000185

Bitstream Version : 0x30201

Pr Interface Id : 69528db6-eb31-577a-8c36-68f9faa081f6

Board Management Controller, microcontroller FW version unavailable (I/O error)

Last Power Down Cause: Q){

Last Reset Cause: Software reset

Watchdog timeout

//****** FME ******//

Object Id : 0xEC00000

PCIe s:b:d:f : 0000:3B:00:0

Device Id : 0x09C4

Socket Id : 0x00

Ports Num : 01

Bitstream Id : 0x123000200000185

Bitstream Version : 0x30201

Pr Interface Id : 69528db6-eb31-577a-8c36-68f9faa081f6

二 Hello world demo代码

复制代码
#include <stdio.h>          // 引入标准输入输出库,用于 printf() 打印信息`
`#include <opae/fpga.h>      // 引入 OPAE FPGA API 头文件,提供 fpgaOpen/fpgaEnumerate/MMIO 等接口`
`#include <uuid/uuid.h>      // 引入 UUID 处理库,用于 uuid_parse() 解析 AFU GUID 字符串`

`/*`
` * CHECK_RES 是一个宏,用来检查 OPAE API 的返回值。`
` *`
` * OPAE API 通常返回 fpga_result 类型:`
` *   FPGA_OK 表示成功`
` *   其他值表示失败`
` *`
` * 如果 res 不是 FPGA_OK,就打印错误信息,并直接 return -1 退出程序。`
` */`
`#define CHECK_RES(res, msg) \`
`    if (res != FPGA_OK) { \`
`        printf("Error: %s (Result code: %d)\n", msg, res); \`
`        return -1; \`
`    }`

`int` `main()` `{`                                `// 程序入口函数`

`    fpga_result res;`                        `// 保存 OPAE API 调用的返回结果`

`    fpga_token token;`                       `// FPGA token,表示枚举到的某个 FPGA/AFU 对象`
                                            `// 后续 fpgaOpen() 需要用它来打开设备`

`    fpga_handle handle;`                     `// FPGA handle,表示已经打开的 AFU 句柄`
                                            `// 后续 MMIO 读写都通过这个 handle 完成`

    `uint32_t num_matches =` `0;`               `// 保存 fpgaEnumerate() 找到的匹配对象数量`

`    fpga_properties filter =` `NULL;`          `// FPGA 枚举过滤器`
                                            `// 用它指定"我要找什么类型的 FPGA 对象"`

`    fpga_guid afu_guid;`                     `// 保存 AFU GUID 的二进制形式`
                                            `// AFU GUID 用来精确匹配某个加速器`

    `/*`
`     * 创建一个 properties 对象。`
`     *`
`     * fpgaGetProperties(NULL, &filter) 的意思是:`
`     *   不基于已有 token 获取属性,`
`     *   而是创建一个空的 properties/filter 对象。`
`     *`
`     * 这个 filter 后面会被配置成:`
`     *   只查找 FPGA_ACCELERATOR 类型`
`     *   只匹配指定 AFU GUID`
`     */`
`    res =` `fpgaGetProperties(NULL,` `&filter);`
    `CHECK_RES(res,` `"Failed to get properties");`

    `/*`
`     * 设置枚举对象类型为 FPGA_ACCELERATOR。`
`     *`
`     * 这是这段代码里非常关键的一行。`
`     *`
`     * FPGA_DEVICE 表示整个 FPGA 设备/FME 层;`
`     * FPGA_ACCELERATOR 表示 Port 后面的 AFU 加速器。`
`     *`
`     * MMIO 读写通常是针对 AFU/Accelerator 做的,`
`     * 所以这里必须用 FPGA_ACCELERATOR。`
`     */`
`    res =` `fpgaPropertiesSetObjectType(filter, FPGA_ACCELERATOR);`
    `CHECK_RES(res,` `"Failed to set object type");`

    `/*`
`     * 把字符串形式的 AFU UUID 转成二进制 fpga_guid。`
`     *`
`     * 当前机器上 fpgainfo 显示的 Accelerator Id 是:`
`     *   331db30c-9885-41ea-9081-f88b8f655caa`
`     *`
`     * 这里用这个 GUID 来确保程序打开的是正确的 AFU。`
`     */`
    `if` `(uuid_parse("331db30c-9885-41ea-9081-f88b8f655caa", afu_guid)` `<` `0)` `{`
        `printf("Error: invalid AFU GUID\n");`    `// UUID 字符串格式不合法时打印错误`
        `return` `-1;`                              `// 退出程序`
    `}`

    `/*`
`     * 把 AFU GUID 设置到 filter 里。`
`     *`
`     * 这样 fpgaEnumerate() 只会返回 GUID 匹配的 Accelerator。`
`     */`
`    res =` `fpgaPropertiesSetGUID(filter, afu_guid);`
    `CHECK_RES(res,` `"Failed to set AFU GUID");`

    `/*`
`     * 枚举 FPGA 对象。`
`     *`
`     * 参数解释:`
`     *   &filter       :过滤条件数组,这里只有一个 filter`
`     *   1             :filter 数量`
`     *   &token        :输出参数,用来保存找到的第一个匹配 token`
`     *   1             :最多只取 1 个匹配结果`
`     *   &num_matches  :实际找到的匹配数量`
`     *`
`     * 成功后:`
`     *   token 会指向匹配到的 AFU`
`     *   num_matches 会表示找到几个匹配项`
`     */`
`    res =` `fpgaEnumerate(&filter,` `1,` `&token,` `1,` `&num_matches);`
    `CHECK_RES(res,` `"Failed to enumerate");`

    `/*`
`     * 枚举完成后,filter 已经不再需要,释放它。`
`     *`
`     * 注意:`
`     *   token 还要继续用,所以这里只释放 filter。`
`     */`
    `fpgaDestroyProperties(&filter);`

    `/*`
`     * 如果没有找到匹配的 AFU,说明:`
`     *   1. FPGA 上没有加载这个 AFU;`
`     *   2. GUID 写错;`
`     *   3. 当前环境看不到这个 accelerator;`
`     *   4. 驱动/设备节点有问题。`
`     */`
    `if` `(num_matches ==` `0)` `{`
        `printf("No matching FPGA accelerator found!\n");`
        `return` `-1;`
    `}`

    `/*`
`     * 打开枚举到的 AFU。`
`     *`
`     * fpgaOpen() 成功后会得到 handle。`
`     * 后面的 MMIO map/read/write 都基于这个 handle。`
`     *`
`     * 第三个参数 0 表示默认 open flags。`
`     */`
`    res =` `fpgaOpen(token,` `&handle,` `0);`
    `CHECK_RES(res,` `"Failed to open FPGA accelerator");`

    `/*`
`     * 映射 MMIO region 0。`
`     *`
`     * MMIO = Memory-Mapped I/O。`
`     * Host CPU 可以通过 MMIO 地址读写 FPGA 暴露出来的寄存器。`
`     *`
`     * 参数解释:`
`     *   handle :已经打开的 AFU handle`
`     *   0      :MMIO region index,这里使用 region 0`
`     *   NULL   :不返回直接 mmap 出来的指针`
`     *`
`     * 这里虽然传 NULL,但后面仍然可以使用:`
`     *   fpgaWriteMMIO32()`
`     *   fpgaReadMMIO32()`
`     *`
`     * 因为这些 API 内部会通过 handle 和 region index 完成访问。`
`     */`
`    res =` `fpgaMapMMIO(handle,` `0,` `NULL);`
    `CHECK_RES(res,` `"Failed to prepare MMIO region 0");`

    `/*`
`     * 设置要访问的 AFU 寄存器偏移。`
`     *`
`     * 这里的 0x100 不是 CPU 虚拟地址,`
`     * 而是 AFU MMIO region 0 内部的寄存器偏移。`
`     *`
`     * 是否有效取决于你的 AFU register map。`
`     */`
    `uint32_t offset =` `0x100;`

    `/*`
`     * 准备写入 FPGA 寄存器的数据。`
`     */`
    `uint32_t data_to_fpga =` `0x12345678;`

    `/*`
`     * 打印即将写入的数据。`
`     */`
    `printf("Host CPU is writing data to FPGA register: 0x%X\n", data_to_fpga);`

    `/*`
`     * 向 AFU 的 MMIO region 0 写一个 32-bit 数据。`
`     *`
`     * 参数解释:`
`     *   handle       :AFU handle`
`     *   0            :MMIO region index`
`     *   offset       :寄存器偏移,这里是 0x100`
`     *   data_to_fpga :要写入的数据`
`     *`
`     * 实际含义是:`
`     *   向 FPGA AFU 的 region 0 + 0x100 位置写入 0x12345678。`
`     */`
`    res =` `fpgaWriteMMIO32(handle,` `0, offset, data_to_fpga);`
    `CHECK_RES(res,` `"Failed to write MMIO");`

    `/*`
`     * 准备一个变量,用来保存从 FPGA 读回来的 32-bit 数据。`
`     */`
    `uint32_t data_from_fpga =` `0;`

    `/*`
`     * 从 AFU 的 MMIO region 0 读取一个 32-bit 数据。`
`     *`
`     * 注意:`
`     *   这里读的地址是 offset + 0x10,`
`     *   也就是 0x100 + 0x10 = 0x110。`
`     *`
`     * 也就是说:`
`     *   你写的是 0x100,`
`     *   读的是 0x110。`
`     *`
`     * 因此读回来的值不一定等于刚才写入的 0x12345678。`
`     *`
`     * 这是否正确,取决于你的 AFU register map。`
`     * 例如有些 AFU 设计是:`
`     *   0x100 是输入寄存器`
`     *   0x110 是输出寄存器`
`     */`
`    res =` `fpgaReadMMIO32(handle,` `0, offset,` `&data_from_fpga);`
    `CHECK_RES(res,` `"Failed to read MMIO");`

    `/*`
`     * 打印从 FPGA 读回来的数据。`
`     */`
    `printf("Host CPU read data from FPGA register: 0x%X\n", data_from_fpga);`

    `/*`
`     * 如果程序走到这里,说明:`
`     *   AFU 枚举成功;`
`     *   AFU 打开成功;`
`     *   MMIO map 成功;`
`     *   MMIO write 成功;`
`     *   MMIO read 成功。`
`     */`
    `printf("Hello World! Communication successful!\n");`

    `/*`
`     * 解除 MMIO region 0 的映射。`
`     *`
`     * 这是 fpgaMapMMIO() 的配套释放操作。`
`     */`
    `fpgaUnmapMMIO(handle,` `0);`

    `/*`
`     * 关闭 AFU handle。`
`     *`
`     * 这是 fpgaOpen() 的配套释放操作。`
`     */`
    `fpgaClose(handle);`

    `/*`
`     * 销毁 token。`
`     *`
`     * 这是 fpgaEnumerate() 返回 token 后的配套释放操作。`
`     */`
    `fpgaDestroyToken(&token);`

    `/*`
`     * 返回 0,表示程序正常结束。`
`     */`
    `return` `0;`
`}`
`
复制代码
创建 filter`
`→ 指定查找 FPGA_ACCELERATOR`
`→ 指定 AFU GUID`
`→ 枚举 AFU`
`→ 打开 AFU`
`→ map MMIO region 0`
`→ 写寄存器 0x100`
`→ 读寄存器 0x100`
`→ 释放资源`
`
相关推荐
nuoxin1149 小时前
BL-M8812CU3 无线 WiFi 模块-富利威
人工智能·嵌入式硬件·fpga开发·硬件工程·dsp开发
xiaojiaohuazi12 小时前
基于Zynq UltraScale+ MPSoC的PL DDR4直写多NVMe条带阵列(RAID 0)与exFAT高速采集存储系统
fpga开发
ALINX技术博客12 小时前
【黑金云课堂】FPGA技术教程Vitis开发:AXI总线
fpga开发·vitis
星夜离尘561 天前
UART 串口通信:从帧格式到收发回显(附完整 Verilog 实操)
fpga开发
仲南音1 天前
Xilinx FPGA—— DDR4读写
fpga开发
思尔芯S2C1 天前
思尔芯RCF RTL自动分割工具,助力大规模AI/HPC芯片原型验证
人工智能·fpga开发·内存模型·自动编译·ddr5·prototyping·原型验证
Terasic友晶科技2 天前
答疑解惑|Agilex 3 FPGA QSPI时钟设置注意事项
fpga开发·de23-lite·terasic·qspi flash
国科安芯2 天前
卫星星务计算机数据管理中SEU容错机制的技术实现研究——以AS32S601存储器ECC架构为例
网络·单片机·算法·fpga开发·架构·云计算·risc-v
国科安芯2 天前
卫星电推进系统阀门驱动控制中的宽温域高可靠MCU应用研究——基于AS32S601电气特性与辐照试验数据的工程分析
单片机·嵌入式硬件·fpga开发·云计算·信息与通信·卫星·抗辐射芯片
郝旭帅电子设计团队3 天前
图像处理是什么
图像处理·fpga开发·郝旭帅电子设计团队·郝旭帅