C++ 应用程序使用 mmap 通过 PCI 在用户区与 FPGA 通信

标签 c++ linux-kernel pci-bus

首先,我是 Linux 编程的新手,如果这没有意义,或者我找错了树,请向我指出正确的方向,我深表歉意。

我正在尝试编写一个 cpp 应用程序,以在用户区通过 pci 总线与 FPGA 通信。

到目前为止,我编写的代码枚举了 /sys/bus/pci/devices 中的目录,检查设备和供应商文件以找到正确的文件。

找到设备后,我知道我需要写入的映射区域以某种方式由资源 [n] 文件表示,但我不确定如何使用它们来读取/写入某些值。

从为另一个操作系统编写的代码中,我知道我想与 PCI 设备的 BAR1 对话,我(尝试)这样做的方式是使用 mmap(这是正确的方式吗?)。首先,我使用 O_RDWR 获取到 /sys/bus/pci/devices/[device_addr]/resource1 的文件句柄,然后像这样调用 mmap:

char *map = (char*)mmap(NULL, FPGA_MEM_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);

fd 是打开的文件描述符。

我的处理方式是否正确,还是使用更好的函数/调用?我意识到我可以编写一个内核模块来执行此操作,但我宁愿暂时不必进入内核模块编程。

如果有帮助,我可以将代码粘贴一小段时间,但我并不是真的在对代码进行评论之后,只是提供一些关于最佳方法的指示。

如果我遗漏了任何细节,请直接询问。

我使用的是 2.6 Linux 内核,基于 ubuntu 11.04(在 live usb 上运行),硬件是基于 x86 的。

谢谢

更新: 在对代码进行更多谷歌搜索和反复试验后,我让它工作了。

我遵循的步骤是:

  • 使用 /sys/bus/pci/devices/[device]/[vendor|device] 识别设备
  • 解析 /sys/bus/pci/devices/[device]/resource,对于每一行的第一行 列是起始地址,第二列是结束地址 映射区域。我想要 BAR1 所以第二行有我的值 需要。
  • open("/dev/mem", O_RDWR)获取文件描述符fd
  • 如上调用mmap,但传入起始地址作为偏移量(last 参数)并使用起始地址和结束地址来获取映射区域 大小(第二个参数)。

最佳答案

这是一个完全可以接受的 mmap 调用,应该可以正常工作。

关于C++ 应用程序使用 mmap 通过 PCI 在用户区与 FPGA 通信,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6874945/

相关文章:

c++ - 使用 OpenMP atomic 并行更新矩阵列

c - Ext2 - 文件是如何创建的

linux - 内核中关于工作队列的一些标志

linux - Linux Virtual Box 上的恢复

winapi - 通过 Windows 的 API(用户模式)检索 PCI 坐标

c++ - 如何动态更改 Qt 应用程序中的字体?

c++ - 模板化的 Barton 和 Nackman 技巧问题

c++ - 是否可以在 Qt Creator IDE 中设置 wxWidgets 库?

Linux Kernel 4.7 (Arch ARM64) 不在/sys/bus/pci/devices/*/中为 PCI BAR0 创建 "resource0"文件