【发布时间】:2019-04-28 18:47:39
【问题描述】:
我正在编写一个用户空间驱动程序,用于在 Python 3.5 中访问 FPGA 寄存器,mmaps FPGA 的 PCI 地址空间,获得一个 memoryview 以提供对内存映射寄存器空间的直接访问,然后使用 @987654324 @ 将 32 位值写入选定的 32 位对齐地址。
def write_u32(address, data):
assert address % 4 == 0, "Address must be 32-bit aligned"
path = path.lib.Path("/dev/uio0")
file_size = path.stat().st_size
with path.open(mode='w+b') as f:
mv = memoryview(mmap.mmap(f.fileno(), file_size))
struct.pack_into("<I", mv, address, data)
不幸的是,appears struct.pack_into 做了一个 memset(buf, 0, ...) 在写入实际值之前清除寄存器。通过检查 FPGA 中的写操作,我可以看到寄存器在设置真值之前设置为 0x00000000,因此 PCI 总线上至少有两次写入(实际上对于 32 位访问,有 3 个,两个 0写入,然后是实际数据。64 位涉及六次写入)。这会对一些计算写入操作次数的寄存器产生副作用,或者一些“写入时清除”或在写入时触发某些事件。
我想使用另一种方法将寄存器数据一次性写入内存映射寄存器空间。我查看了ctypes.memmove,它看起来很有希望(尚未工作),但我想知道是否还有其他方法可以做到这一点。
请注意,使用struct.unpack_from 的寄存器读取 效果很好。
请注意,我还通过使用记录所有访问的 QEMU 驱动程序消除了 FPGA - 在写入数据之前,我看到了相同的双零写入访问。
【问题讨论】:
-
我研究过使用
ctypes,尤其是ctypes.from_buffer和ctypes.memmove。前者在一定程度上有效,但它会进行初步阅读。后者逐字节写入,因此不合适。我觉得我很接近 - 有没有办法,也许使用 ctypes 指针,对指针引用的地址进行原子写入?
标签: python struct fpga mmap memoryview