内核版本:4.19
Python 版本:3.5.6
平台:Xilinx Ultrascale+ Zynq
我正在开发一些可以读取和写入UIO设备的python代码。我找到了一种有效的方法,也找到了一种无缘无故失败的方法,我能理解。我担心这意味着这整个方法中有一些东西我错过了,将来会回来咬我。
对于我的初始测试,我正在读取和写入 PL 中的单个寄存器,该寄存器具有 5 个 LSB 处于活动状态。 这是工作代码:
>>> import mmap
>>> fid= open('/dev/uio0', 'r+b', 0) # read/write, binary, non-buffered
>>> regs= mmap.mmap(fid.fileno(), 4)
>>> regs.read(4)
b'x1cx00x00x00'
>>> regs.seek(0)
>>> regs.write(b'xF3x00x00')
>>> regs.seek(0)
>>> regs.read(4)
b'x13x00x00x00'
下面是两个失败代码的示例:
仅使用标准读取函数失败
>>> fid= open('/dev/uio0', 'r+b', 0) # read/write, binary, non-buffered
>>> fid.read(4)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OSError: [Errno 5] Input/output error
使用 os 也会失败,但我可以为 mmap 提供文件描述符,一切正常。
>>> fid= os.open('/dev/uio0', os.O_SYNC | os.O_RDWR)
>>> os.read(fid, 4)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OSError: [Errno 5] Input/output error
>>> import mmap
>>> regs= mmap.mmap(fid, 4)
>>> regs.read(4)
b'x13x00x00x00'
>>> regs.seek(0)
>>> regs.write(b'x65x00x00x00')
>>> regs.seek(0)
>>> regs.read(4)
b'x05x00x00x00'
谁能解释为什么其他两种方法失败了?从我坐的地方看,它们看起来是等价的。
提前谢谢。
根据设计,UIO使用:
mmap()
读取和写入设备地址空间read()
收到中断通知
所以你观察到的行为是正确的。
请参阅内核文档中的 UIO HOWTO。