首先,我是 Linux 编程的新手,所以如果这没有意义或者我在吠叫错误的树,请向我指出正确的方向。
我正在尝试在用户空间中编写一个 cpp 应用程序以通过 pci 总线与 FPGA 通信。
到目前为止,我编写的代码枚举目录以/sys/bus/pci/devices
检查设备和供应商文件以找到正确的文件。
找到设备后,我知道我需要写入的映射区域以某种方式由资源 [n] 文件表示,但我不确定如何使用它们来读取/写入一些值。
从为另一个操作系统编写的代码中,我知道我想与 PCI 设备的 BAR1 交谈,我(尝试)这样做的方式是使用 mmap(这是正确的方式吗?)。首先我得到一个文件句柄/sys/bus/pci/devices/[device_addr]/resource1
with O_RDWR
,然后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)
获取文件描述符 fdmmap
如上所述调用,但传入起始地址作为偏移量(最后一个参数)并使用起始地址和结束地址来获取映射区域的大小(第二个参数)。