首先,我是 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/