How to properly convert a C ioctl call to a python fcntl.ioctl call?
Asked Answered
A

3

10

Following an example on resetting a serial port in Linux I wanted to translate the following snippet

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

into valid python code. Here is what I have tried so far

file_handler = open(self._port, 'w')
fcntl.ioctl(file_handler, termios.USBDEVFS_RESET)
file_handler.close()

which ends with an error 'module' object has no attribute 'USBDEVFS_RESET'. The termios documentation is not very helpful in this point, as it does not list the possible properties of termios. See also the fcntl documentation for an example of such a termios property.

How to I 'convert' the C code to python2.7 code correctly?

Abomb answered 31/1, 2013 at 12:59 Comment(0)
C
13

I came across this when looking how to do a USBDEVFS_RESET and thought I'd share what I found about _IO: https://web.archive.org/web/20140430084413/http://bugcommunity.com/wiki/index.php/Develop_with_Python#Introduction_to_ioctl_calls_in_python

So, what I have so far is the following:

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()

You can get the busnum and devnum from lsusb.

EDIT: above link was dead, URL was replaced to the last archived version.

Colitis answered 22/10, 2013 at 1:43 Comment(0)
B
6

ioctl-opt (pypi) is a small python module translating needed C preprocessor macros to python. For a simple usage example, see this hidraw implementation.

Note that defining ctype structures can be needed (depending on call type) so you can actually pass parameters.

Disclosure: I am the author of both modules.

Barabarabarabas answered 13/2, 2015 at 7:28 Comment(0)
G
0

The macro USBDEVFS_RESET is defined in a system header file somewhere.

You can search for it and replace termios.USBDEVFS_RESET with the actual value.

Ginnygino answered 31/1, 2013 at 13:6 Comment(4)
The value USBDEVFS_RESET has the value _IO('U', 20). I do not need to try your suggestion to see that this won't work. So the original question remains unanswered. Maybe you know what _IO('U', 20) is? Replacing termios.USBDEVFS_RESET simply by 20 gives the error: IOError: [Errno 22] Invalid argument.Abomb
@Abomb Then look what _IO does, and if it uses another macro look at that. In the end an integer will be created through some bit manipulation, and that integer can be used in Python.Ginnygino
You are right, the value '20' is just the beginning. I finally found the correct implementation of _IO and got a value of 21780. HOWEVER, with termios.USBDEVFS_RESET in my example code replaced by 21780 I again get the error IOError: [Errno 22] Invalid argument. I suspect that I miss something, or that the first argument to fcntl.ioctl is not a simple integer value.Abomb
The variable seem to be a simple int, so something else is wrong.Abomb

© 2022 - 2024 — McMap. All rights reserved.