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

发布于 2024-11-27 06:21:57 字数 1263 浏览 0 评论 0原文

首先,我是 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是来自open的文件描述符。

我是否以正确的方式处理这个问题,或者使用更好的函数/调用?我意识到我可以编写一个内核模块来做到这一点,但我不想现在就进入内核模块编程。

如果有帮助,我可以将代码粘贴一段时间,但我并不是真的在批评代码,只是提供一些关于最佳方法的建议。

如果我缺少任何细节,请询问。

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

谢谢

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

我遵循的步骤如下:

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

First off i'm new to Linux programming so apologies if this makes no sense or I'm barking up the wrong tree, point me in the correct direction.

I'm trying to write a cpp app to talk to a FPGA over a pci bus, in userland.

The code I have written so far, enumerates over the directories in /sys/bus/pci/devices checking the device and vendor files to locate the correct one.

Once I've found the device I know that the mapped regions I need to write to are somehow represented by resource[n] files, but i'm not sure how to use them to read/write some values.

From the code written for another OS I know I want to talk to BAR1 of the PCI device, the way i've (tried to) do this is with mmap (is this the right way to go about it?). First I get a filehandle to /sys/bus/pci/devices/[device_addr]/resource1 with O_RDWR, then call mmap like so:

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

Where fd is the file descriptor from open.

Am I going about this the correct way or are the better functions/calls to use? I realise I could write a kernel module to do this, but I'd rather not have to get into kernel module programming just yet.

If it helps I can pastebin the code for a short while, but i'm not really after a critique of the code, just some pointers on the best method to do it.

If there are any details i'm missing just ask.

I'm using a 2.6 Linux kernel, based on ubuntu 11.04 (running on a live usb), the hardware is x86 based.

Thanks

UPDATE:
After even more googling about and trial and error with the code I got it working.

The steps I followed where:

  • Identify device using /sys/bus/pci/devices/[device]/[vendor|device]
  • Parse /sys/bus/pci/devices/[device]/resource, for each line the first
    column is the start address and the second is the end address of the
    mapped region. I wanted BAR1 so the second line had the values I
    needed.
  • open("/dev/mem", O_RDWR) to get file descriptor fd
  • call mmap as above, but pass in the start address as the offset (last
    argument) and use the start and end address to get the mapped regions
    size (second argument).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

空袭的梦i 2024-12-04 06:21:57

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

That's a perfectly acceptable mmap call and should work correctly.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文