Python:在单个操作中写入内存 [英] Python: writing to memory in a single operation

查看:128
本文介绍了Python:在单个操作中写入内存的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个用于访问Python 3.5中的FPGA寄存器的用户空间驱动程序,该mmap是FPGA的PCI地址空间,获得了memoryview以提供对内存映射寄存器空间的直接访问,然后使用将32位值写入所选的32位对齐地址.

I'm writing a userspace driver for accessing FPGA registers in Python 3.5 that mmaps the FPGA's PCI address space, obtains a memoryview to provide direct access to the memory-mapped register space, and then uses struct.pack_into("<I", ...) to write a 32-bit value into the selected 32-bit aligned address.

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)

不幸的是,它出现执行memset(buf, 0, ...),以便在写入实际值之前清除寄存器.通过检查FPGA内的写操作,我可以看到在设置真值之前将寄存器设置为0x00000000,因此PCI总线上至少有两次写操作(实际上,对于32位访问,有三个,两个为零)写入,然后再写入实际数据(64位包含六次写入).这会产生一些副作用,有些寄存器会计算写操作的次数,有些寄存器会写时清除",或者在写操作时会触发某些事件.

Unfortunately, it appears that struct.pack_into does a memset(buf, 0, ...) that clears the register before the actual value is written. By examining write operations within the FPGA, I can see that the register is set to 0x00000000 before the true value is set, so there are at least two writes across the PCI bus (in fact for 32-bit access there are three, two zero writes, then the actual data. 64-bit involves six writes). This causes side-effects with some registers that count the number of write operations, or some that "clear on write" or trigger some event when written.

我想使用一种替代方法,以一次写入方式将寄存器数据写入内存映射的寄存器空间.我研究了ctypes.memmove,它看起来很有前途(尚不可行),但是我想知道是否还有其他方法可以做到这一点.

I'd like to use an alternative method to write the register data in a single write to the memory-mapped register space. I've looked into ctypes.memmove and it looks promising (not yet working), but I'm wondering if there are other ways to do this.

请注意,使用struct.unpack_from的寄存器 read 可以正常工作.

Note that a register read using struct.unpack_from works perfectly.

请注意,我还通过使用记录所有访问的QEMU驱动程序从中删除了FPGA-在写入数据之前,我看到了相同的双零写入访问.

Note that I've also eliminated the FPGA from this by using a QEMU driver that logs all accesses - I see the same double zero-write access before data is written.

推荐答案

也许这可以根据需要工作吗?

Perhaps this would work as needed?

mv[address:address+4] = struct.pack("<I", data)

更新:

从注释中可以看出,上面的代码不能解决问题.但是,它有以下变化形式:

As seen from the comments, the code above does not solve the problem. The following variation of it does, however:

mv_as_int = mv.cast('I')
mv_as_int[address/4] = data

不幸的是,对引擎盖下发生的事情以及为什么精确的记忆视图如此行为的精确理解已经超出了现代技术的能力,因此将为将来的研究人员敞开大门.

Unfortunately, precise understanding of what happens under the hood and why exactly memoryview behaves this way is beyond the capabilities of modern technology and will thus stay open for the researchers of the future to tackle.

这篇关于Python:在单个操作中写入内存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆