【问题标题】:c++ code convert in python with ctypes and mmap使用 ctypes 和 mmap 在 python 中转换 c++ 代码
【发布时间】:2018-10-12 17:33:29
【问题描述】:

我正在尝试将 c++ 代码转换为 python。

int fd_vdma = open("/dev/mem", O_RDWR|O_SYNC);  // open uiox device for vdma access
    if (fd_vdma < 1) {
        printf("Invalid mem device file\n");
    }
    // mmap the vdma device for vdma access

    unsigned int *ptr_vdma;
    ptr_vdma = (unsigned int*)mmap(NULL, VDMA_MAP_SIZE,PROT_READ|PROT_WRITE, 
    MAP_SHARED, fd_vdma, VDMA_ADDR);
    printf("DMA 1 virtual address: 0x%08x \n",ptr_vdma);

    *(ptr_vdma+5) = FRBUF_ADDR_0;
    *(ptr_vdma+7) = 2;  // use internal fifos to trigger xfer
    *(ptr_vdma+8) = 20480;
    *(ptr_vdma+6) = (75 << 16) + (HORIZ_PIXELS_SMALL+75);
    *(ptr_vdma+0x0D) = 200;  // no. FIFO threshhold .. max.. 240

到目前为止,我已经完成了,

# vdm memory check
try:
    fd_vdm_path = "/dev/mem"
    mode = "rb+"
    fd_vdm =  open(fd_vdm_path, mode)
    # print(fd_vdm.fileno())
    print("[INFO] " + fd_vdm_path + " checked")

except Exception as error:
    print("{}".format(error))

 # mmap the VDMA device for VDM access
vdma_buf = mmap.mmap(fd_vdm.fileno(), int(VDMA_MAP_SIZE), 
mmap.MAP_SHARED, mmap.PROT_READ|mmap.PROT_WRITE, 0)

ptr_vdm = ctypes.c_uint.from_buffer(vdma_buf)
print(type(ctypes.addressof(ptr_vdm)))
print("[INFO] " + fd_vdm_path + " has allocated virtual address : " + 
hex(ctypes.addressof(ptr_vdm)))

但是我一直卡在这里,我不知道如何在python中执行以下操作。

*(ptr_vdma+5) = FRBUF_ADDR_0;
*(ptr_vdma+7) = 2;  // use internal fifos to trigger xfer
*(ptr_vdma+8) = 20480;
*(ptr_vdma+6) = (75 << 16) + (HORIZ_PIXELS_SMALL+75);
*(ptr_vdma+0x0D) = 200;  // no. FIFO threshhold .. max.. 240

我尝试vdma_buf.write(FRBUF_ADDR_0),但它不起作用,我在互联网上找不到任何东西(可能我没有很好地搜索它) 你能帮忙解决这个问题还是给我一些链接或教程?

【问题讨论】:

  • 我的 Python 非常弱,但你可以利用 *(ptr_vdma+5)ptr_vdma[5] 相同的优势。
  • 我之前试过了,它抛出了一个名为TypeError: 'c_ulong' object does not support item assignment的错误

标签: c++ python-3.x cython ctypes debian-jessie


【解决方案1】:

您可以使用memoryviewstruct.pack

...
mm = memoryview(vdma_buf)

mm[5*4:6*4] = struct.pack("I", FRBUF_ADDR_0)
mm[7*4:8*4] = struct.pack("I", 2)
mm[8*4:9*4] = struct.pack("I", 20480)
mm[6*4:7*4] = struct.pack("I", (75 << 16) + (HORIZ_PIXELS_SMALL+75))
mm[0x0D*4:0x0E*4] = struct.pack("I", 200)

memoryview 表示字节序列,如果要写入其他类型到内存中,必须使用struct.pack 将其转换为字节。

所以,假设您想在索引 N 处写入一个无符号整数。 首先,您调用struct.pack("I", ...) 来获取int 的字节表示。然后你必须计算目标内存地址。因为 unsigned int 的大小是 4 个字节,所以地址等于 N*4

memoryview 支持 slicing,所以你可以写:

mm[StartAddress:EndAddress] = BytesYouWantToWrite

其中 StartAddress 等于 N*4,EndAddress 为 (N+1) * 4

【讨论】:

  • 当我使用 memoryview 时,它会抛出一个名为 TypeError: cannot make memory view because the object does not have the buffer interface 的错误我做 mmap 错了吗?或者我需要在使用 memoryview 之前做一些步骤?
  • 你使用python 3吗?此错误出现在 python 2.7 中:bugs.python.org/issue9229
  • 对不起,我使用的是虚拟环境,我不在虚拟环境中。这就是为什么我有那个错误。但即使在 python3 中,我也收到此错误 ValueError: memoryview: invalid value for formate 'B' ,当我使用 mm[5]= FRBUF_ADDR_0 (FRBUF_ADDR_0 = 0x1E000000) 时,似乎我只能在其中写入有限的值(0xff)缓冲区。
  • 我已经添加了一些解释,希望现在更清楚了。
  • 非常感谢,已经很完美了,我已经尝试解决这个问题3天了,你做的这么简单。
猜你喜欢
  • 1970-01-01
  • 2017-08-30
  • 1970-01-01
  • 1970-01-01
  • 2012-05-07
  • 1970-01-01
  • 1970-01-01
  • 2019-10-21
  • 1970-01-01
相关资源
最近更新 更多