使用ioctl在Python中写入USB设备
我正在用Python尝试通过ioctl向USB传感器写数据。我有很多关于如何直接从设备读取数据的例子,或者通过pyusb读取,或者简单的文件写入,但一旦涉及到更复杂的内容,就没什么资料了。
我需要使用control_transfer来写入功能报告消息。
这个命令是 ioctl(devicehandle, Operation, Args)
我遇到的问题是如何确定正确的Operation。Args我认为应该是一个包含设备功能报告的缓冲区?还有一个可变标志需要设置为true。
任何帮助或建议都非常感谢。
我还应该补充一下,使用Python的原因是代码必须与设备无关。
2 个回答
根据文档,ioctl()
这个函数属于fcntl模块,是专门为Unix系统设计的,所以在Windows上是不能用的。不过,Windows有一个类似的函数叫DeviceIoControl()
,它的功能也差不多。
IOCTL(输入输出控制)是由设备驱动程序或操作系统来定义的,所以我很怀疑在不同的操作系统上会有相同的IOCTL操作ID(IOCTL编号)和相同的参数。
如果你在使用Linux,可以查看特定设备驱动程序的头文件,或者可能还可以在一些USB核心的头文件中找到有效的IOCTL信息。
一个很好的例子是用于 Linux 的 linuxdvb 和 V4l2 的 Python 绑定。你可以在这里找到它们:http://pypi.python.org/pypi/linuxdvb 和 http://pypi.python.org/pypi/v4l2,不过这些库的用法并不是特别符合 Python 的风格。而且它们只适用于 Linux 或 Unix 系统。
你需要把 ARGS
这个结构转换成 Python 能理解的格式,这个过程需要用到 ctype
这个模块。Operation
的值和 C 语言中的是一样的。
对应于一个 C 语言的调用
struct operation_arg {
int fields1;
int fields2;
}
struct operation_arg Args;
Args.field1 = data1;
Args.field2 = data2;
devicehandle = open("/dev/my_usb", O_RDWR);
retval = ioctl(devicehandle, Operation, &Args);
/* check retval value */
你需要在 Python 中定义与 struct operation_arg
对应的 Ctype。这将会生成这样的代码:
import ctypes
import linuxdvb
import fcntl
class operation_arg(ctypes.Structure):
_fields_ = [
('field1', ctypes.c_int),
('field2', ctypes.c_int)
]
Args = operation_args()
Args.field1 = data1;
Args.field2 = data2;
devicehandle = open('/dev/my_usb', 'rw')
# try:
fcntl.ioctl(devicehandle, operation, Args)
# exception block to check error