如何正确将C中的ioctl调用转换为Python中的fcntl.ioctl调用?

10

我想翻译一下关于在Linux中重置串口的示例。以下是需要翻译的片段:

fd = open(filename, O_WRONLY);
ioctl(fd, USBDEVFS_RESET, 0);
close(fd);

将其转换为有效的Python代码。到目前为止,这是我尝试过的内容。
file_handler = open(self._port, 'w')
fcntl.ioctl(file_handler, termios.USBDEVFS_RESET)
file_handler.close()

出现错误'module' object has no attribute 'USBDEVFS_RESET'。在这一点上,termios文档并不是很有帮助,因为它没有列出termios的可能属性。请参阅fcntl文档,了解此类termios属性的示例。

我如何正确地将C代码转换为python2.7代码?

3个回答

12

我在查找如何执行USBDEVFS_RESET时发现了这个,想分享一下我对_IO的发现:https://web.archive.org/web/20140430084413/http://bugcommunity.com/wiki/index.php/Develop_with_Python#Introduction_to_ioctl_calls_in_python

到目前为止,我的成果如下:

from fcntl import ioctl

busnum = 1
devnum = 10

filename = "/dev/bus/usb/{:03d}/{:03d}".format(busnum, devnum) 

#define USBDEVFS_RESET             _IO('U', 20)
USBDEVFS_RESET = ord('U') << (4*2) | 20

fd = open(filename, "wb")
ioctl(fd, USBDEVFS_RESET, 0)
fd.close()

你可以从 lsusb 中获取 busnumdevnum

编辑:上面的链接已经失效,URL被替换为最后一个存档版本。


6

ioctl-opt (pypi)是一个小的Python模块,将需要的C预处理宏转换为Python。

有关简单使用示例,请参见此hidraw实现。

请注意,可能需要定义ctype结构(取决于调用类型),以便您可以实际传递参数。

披露:我是这两个模块的作者。


0

USBDEVFS_RESET在某个系统头文件中定义。

您可以搜索并将termios.USBDEVFS_RESET替换为实际值。


价值为 USBDEVFS_RESET 的值具有值 _IO('U', 20)。我不需要尝试您的建议就能看出这行不通。因此,原始问题仍然没有得到回答。也许您知道 _IO('U', 20) 是什么?仅将 termios.USBDEVFS_RESET 替换为 20 就会出现错误:IOError: [Errno 22] Invalid argument - Alex
@Alex 然后看看 _IO 做了什么,如果它使用了另一个宏,请查看该宏。最终通过一些位操作将创建一个整数,并且该整数可以在 Python 中使用。 - Some programmer dude
你说得对,值“20”只是开始。我最终找到了正确的_IO实现,并获得了21780的值。然而,在我的示例代码中,将termios.USBDEVFS_RESET替换为21780后,我再次收到错误“IOError:[Errno 22]无效参数”。我怀疑我漏掉了什么,或者fcntl.ioctl的第一个参数不是简单的整数值。 - Alex
这个变量看起来只是一个简单的整数,所以肯定有其他问题。 - Alex

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接