【发布时间】:2020-07-30 17:59:12
【问题描述】:
我正在尝试通过 mmap 优化通过 pcie 读取数据。当时我们有一些工具允许从 PCIe 通信中读取/写入一个单词,但我想在一个请求中获取/写入尽可能多的单词。
我的项目使用 PCIe Gen3 和 AXI 桥接器(2 个 PCIe 条)。
我可以从总线上成功读取任何单词,但在请求数据时我注意到了一种模式:
- 在地址0请求数据:AXI master请求4个地址的数据,初始地址为0
- 请求地址0和1的数据:两个AXI请求:第一个和上面类似,后面是3个地址数据的读请求,初始addr为1
- 从地址0到2请求数据:3个AXI请求:前两个和前一个类似,后面是2个地址数据的读请求,初始addr为2
该模式一直持续到 addr 是 4 的倍数。似乎如果我请求第一个地址,AXI 会发送前 4 个值。有什么提示吗?这可能在我正在使用的驱动程序上吗?
这是我使用 mmap 的方法:
length_offset = tmp_offset_rw & ~(sysconf (_SC_PAGESIZE)-1);
mmap_offset = (u_long)(tmp_barx_rw << 12) + length_offset;
mmap_len = (u_long)(tmp_size * sizeof(int));
mmap_address = mmap(NULL, mmap_len + (int)(tmp_offset_rw) - length_offset,
PROT_READ | PROT_WRITE, MAP_SHARED, fd, mmap_offset);
close(fd);
// tmp_reg_buf = new u_int[tmp_size];
// memcpy(tmp_reg_buf, mmap_address , tmp_size*sizeof(int));
// for(int i = 0; i < 4; i++)
// printf("0x%08X\n", tmp_reg_buf[i]);
for(int i = 0; i < tmp_size; i++)
printf("0x%08X\n", *((u_int*)mmap_address + (int)tmp_offset_rw - length_offset + i));
【问题讨论】:
-
我不明白问题的措辞。在每种情况下,您要读取多少字节,地址的对齐方式是什么?请发布一些您用于从内存映射区域读取的代码。
-
感谢您的回复。我想说的是,我想通过一个请求从 PCIe 内存中读取多个整数。看来内核只支持单个读/写转换可能是这种情况吗?即使很难,它也清楚地发送了 4 的倍数的数据请求。
-
您的代码明确表示一次读取 4 个字节,那么您为什么会期待不同的内容呢?您是否尝试过使用读取超过 4 个字节的指令?
-
您描述的行为听起来像 memcpy 的行为(您已在示例代码中注释掉)。 Memcpy 被定义为执行字节访问,并不真正适合访问 MMIO。如果您的描述与您的代码匹配,则更容易回答您的问题。
-
内核不参与这些访问。这只是您的软件和硬件。