使用 python mmap 强制 32 位访问?

use*_*290 5 python mmap 32bit-64bit

我在 64 位 Arm 处理器上运行 64 位 python。该处理器的 AXI 总线上的一个连接到 FPGA(FPGA 将总线和时钟域更改为 32 位宽总线)。这个硬件不喜欢 64 位访问......

我正在尝试通过 python mmap 访问该 FPGA,如下所示(在一个类中):

def __init__(self, base, len):
    self.base = base
    self.fd = open("/dev/mem", "r+")
    self.lw = mmap.mmap(self.fd.fileno(),
                        len,
                        mmap.MAP_SHARED,
                        mmap.PROT_READ | mmap.PROT_WRITE,
                        offset=base)

def get_U32(self, offset):
    s = self.lw[offset:offset+4]
    return struct.unpack("<I", s)[0]
Run Code Online (Sandbox Code Playgroud)

这个想法是get_U32()从总线读取一个 32 位字(因此偏移量为 offset+4 读取)。遗憾的是,看起来 mmap 无论如何都会执行对总线的 64 位访问(我假设是某种用于性能优化的缓存),然后执行 32 位“转换”。底层FPGA不高兴了……

在C程序中,我简单地写:

data = *((uint32_t *) address);
Run Code Online (Sandbox Code Playgroud)

...并且CPU似乎在其AXI总线上温和地执行32位访问,这是底层硬件更喜欢的...(所以现在,我有一个(缓慢的)解决方法,其中python需要一个C程序来连接硬件,通过管道)

有没有办法强制 64 位 python 执行 32 位访问,就像前面的 C 行显然成功了一样?

这里写的问题是关于读32位的,但是当然,写32位也是需要的......

use*_*290 2

基于 @martineau 的想法,可以使用 python ctypes 修复双探针,例如:

s = ctypes.c_uint32.from_buffer(self.lw, offset).value #read
Run Code Online (Sandbox Code Playgroud)

或者

types.c_uint32.from_buffer(self.lw, offset).value = s #write
Run Code Online (Sandbox Code Playgroud)

这确实似乎迫使 python 执行与 C 中相同的 32 位访问,并删除 32 位总线上的双读或写探针。

然而,遗憾的是,Python 似乎在每次写入之前都会进行读取。因此,上面的解决方案非常适合读取,但在写入时,我仍然在写入访问之前获得读取访问权限。在 C 中,我当然可以在写入时获得一次写入访问权限。

我将其发布给其他可能感兴趣的人。如果您对最后一个问题有解决方案(在编写之前先阅读),请发布。