强制使用python mmap进行32位访问?

时间:2019-03-07 08:31:25

标签: python 32bit-64bit mmap

我在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]

想法是get_U32()将从总线读取32位字(因此,偏移量为offset + 4的读数)。 可悲的是,mmap似乎仍然执行对总线的64位访问(我认为是某种用于性能优化的缓存),然后执行32位“广播”。底层的FPGA不满意...

在C程序中,我只写:

data = *((uint32_t *) address);

...并且CPU似乎在其AXI总线上进行了32位访问,而底层硬件则更喜欢...。 (所以现在,我有一个(缓慢的)解决方法,其中python需要一个C程序通过管道与硬件接口)

有没有一种方法可以强制64位python执行32位访问,因为上一条C行显然成功了?

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

2 个答案:

答案 0 :(得分:0)

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

s = ctypes.c_uint32.from_buffer(self.lw, offset).value #read

types.c_uint32.from_buffer(self.lw, offset).value = s #write

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

但是,可悲的是,python似乎在每次写入之前都要进行一次读取。 因此,上述解决方案非常适合读取,但是在写入时,我仍然在写入访问之前获得了读取访问权限。在C语言中,我当然可以在编写时获得一个写访问权限。

我将其发布给其他有兴趣的人。如果您对上一期问题有解决方案(写之前先阅读),请发布它。

答案 1 :(得分:0)

关于此thread的解决方案

你可以尝试这样的事情:

 def __init__(self,offset,size=0x10000):
    self.offset = offset
    self.size = size
    
    mmap_file = os.open('/dev/mem', os.O_RDWR | os.O_SYNC)
    mem = mmap.mmap(mmap_file, self.size,
                    mmap.MAP_SHARED,
                    mmap.PROT_READ | mmap.PROT_WRITE,
                    offset=self.offset)
    os.close(mmap_file)
    self.array = np.frombuffer(mem, np.uint32, self.size >> 2)
    
def wread(self,address):
    idx = address >> 2
    return_val = int(self.array[idx])
    return return_val
    
def wwrite(self,address,data):
    idx = address >> 2
    self.array[idx] = np.uint32(data)