如何正确地将C ioctl调用转换为python fcntl.ioctl调用?

问题描述:

resetting a serial port的例子在Linux中,我想翻译下面的代码片段如何正确地将C ioctl调用转换为python fcntl.ioctl调用?

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 documentation在这一点上并不是非常有用,因为它没有列出termios的可能属性。有关这种termios属性的示例,另请参见fcntl documentation

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

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

您可以搜索它并用实际值替换termios.USBDEVFS_RESET

+0

“USBDEVFS_RESET”的值为'_IO('U',20)'。我不需要尝试你的建议,看看这是行不通的。所以最初的问题仍然没有答案。也许你知道'_IO('U',20)'是什么?用'20'代替'termios.USBDEVFS_RESET'会给出错误:'IOError:[Errno 22] Invalid argument'。 – Alex

+0

@Alex然后看看'_IO'做了什么,如果它使用另一个宏来看看。最后一个整数将通过一些位操作来创建,并且该整数可以在Python中使用。 –

+0

你说得对,值'20'仅仅是个开始。我终于找到了'_IO'的正确实现,并得到了21780的值。但是,在我的示例代码中'termios.USBDEVFS_RESET'替换为'21780',我又收到错误'IOError:[Errno 22] Invalid argument''。我怀疑我错过了什么,或者'fcntl.ioctl'的第一个参数不是一个简单的整数值。 – Alex

我碰到这个来找怎么办USBDEVFS_RESET时,我想我会分享我发现了大约_IO: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

ioctl-optpypi)是一个小型的python模块,将需要的C预处理宏转换为python。 有关简单用法示例,请参阅此hidraw实现。

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

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