如何在Python中的Linux设备文件上执行低级I/O?

Anm*_*rma 9 python linux posix

我有一个设备,它返回一个字符串,以响应写入设备文件的命令.我能够向设备写入命令并在C中读取返回字符串,代码如下所示:

int dev = open("/dev/USBDev251", O_RDWR);
write(dev, data, sizeof(data));
read(dev, buff, 16);
Run Code Online (Sandbox Code Playgroud)

尝试在python中执行相同的操作:

dev = os.open("/dev/USBDev251", os.O_RDWR)
os.write(dev, data)
os.read(dev, 16)
Run Code Online (Sandbox Code Playgroud)

写入成功但仅返回空字符串.我在这里错过了什么?

Ada*_*eld 8

根据os.write文件:

注意:此函数用于低级I/O,必须应用于由os.open()或返回的文件描述符pipe().要编写由内置函数返回一个"文件对象" open()popen()fdopen()sys.stdoutsys.stderr,使用它的write()方法.

你不应该在这里混合和匹配.如果使用全局函数open()打开文件,则必须仅使用文件对象read()write()方法.相反,如果您使用os.open()打开文件,那么您只能使用os.read()os.write().

因此,尝试更换您的来电open()os.open(); 或者,保持open()通话,并更换os.write(dev, ...)dev.write(...)和替换os.read(dev, ...)dev.read(...).


小智 6

添加一个os.lseek()以返回到您编写的字符串的开头。当前您写入了 16 个字节,使指针前进。当您阅读时,您从当前指针开始阅读,因此您需要将其备份到您所写入内容的开头。

这对我有用:

#!/usr/bin/python
import os

data = "xxxxxxxxxxxxxxxx"
dev = os.open("/dev/sdp1", os.O_RDWR)
os.write(dev,data)
os.lseek(dev,0,os.SEEK_SET)
print os.read(dev,16)
Run Code Online (Sandbox Code Playgroud)


Anm*_*rma 1

结果发现问题出在设备驱动程序上。该read()方法在驱动程序file_operations调用时注册copy_to_user(),但随后返回0而不是复制到用户空间的字节数。

上面的 C 代码“有效”,因为它实际上没有检查返回值,read()而是buff用响应填充。