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?

Alex
  • 41,580
  • 88
  • 260
  • 469

3 Answers3

12

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.

Lila Viollette
  • 926
  • 9
  • 9
Tim Tisdall
  • 9,914
  • 3
  • 52
  • 82
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.

vpelletier
  • 901
  • 7
  • 6
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.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • 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`. – Alex Jan 31 '13 at 14:03
  • @Alex 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. – Some programmer dude Jan 31 '13 at 14:28
  • 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. – Alex Jan 31 '13 at 14:32
  • The variable seem to be a simple int, so something else is wrong. – Alex Jan 31 '13 at 14:45