使用ioctl在Python中写入USB设备

2 投票
2 回答
5943 浏览
提问于 2025-04-17 06:55

我正在用Python尝试通过ioctl向USB传感器写数据。我有很多关于如何直接从设备读取数据的例子,或者通过pyusb读取,或者简单的文件写入,但一旦涉及到更复杂的内容,就没什么资料了。

我需要使用control_transfer来写入功能报告消息。

这个命令是 ioctl(devicehandle, Operation, Args)

我遇到的问题是如何确定正确的Operation。Args我认为应该是一个包含设备功能报告的缓冲区?还有一个可变标志需要设置为true。

任何帮助或建议都非常感谢。

我还应该补充一下,使用Python的原因是代码必须与设备无关。

2 个回答

0

根据文档,ioctl()这个函数属于fcntl模块,是专门为Unix系统设计的,所以在Windows上是不能用的。不过,Windows有一个类似的函数叫DeviceIoControl(),它的功能也差不多。

IOCTL(输入输出控制)是由设备驱动程序或操作系统来定义的,所以我很怀疑在不同的操作系统上会有相同的IOCTL操作ID(IOCTL编号)和相同的参数。

如果你在使用Linux,可以查看特定设备驱动程序的头文件,或者可能还可以在一些USB核心的头文件中找到有效的IOCTL信息。

6

一个很好的例子是用于 Linux 的 linuxdvb 和 V4l2 的 Python 绑定。你可以在这里找到它们:http://pypi.python.org/pypi/linuxdvbhttp://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

撰写回答