2013-01-31 10 views
7

następstwie przykład na resetting a serial port w Linuksie chciałem przetłumaczyć następujący fragmentJak poprawnie przekonwertować wywołanie C ioctl na wywołanie Pythona fcntl.ioctl?

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

do ważnego kodu Pythona. Oto, co starałem tak daleko

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

który kończy się błędem 'module' object has no attribute 'USBDEVFS_RESET'. The termios documentation nie jest bardzo pomocny w tym punkcie, ponieważ nie wyszczególnia możliwych właściwości termios. Zobacz także przykład fcntl documentation dla przykładu takiej właściwości termios.

Jak poprawnie przekonwertować kod C na kod Pythona2.7?

Odpowiedz

0

Makro USBDEVFS_RESET jest zdefiniowane gdzieś w pliku nagłówkowym systemu.

Możesz go wyszukać i zastąpić termios.USBDEVFS_RESET rzeczywistą wartością.

+0

Wartość "USBDEVFS_RESET" ma wartość "_IO (" U ', 20) ". Nie muszę wypróbowywać twojej sugestii, aby zobaczyć, że to nie zadziała. Pierwotne pytanie pozostaje bez odpowiedzi. Może wiesz co to jest "_IO (" U ', 20) "? Zastąpienie 'termios.USBDEVFS_RESET' po prostu przez' 20' daje błąd: 'IOError: [Errno 22] Invalid argument'. – Alex

+0

@Alex Następnie sprawdź, co "_IO" ma, i jeśli używa innego makro spojrzeć na to. W końcu liczba całkowita zostanie utworzona poprzez trochę manipulacji bitami, a ta liczba całkowita może być użyta w Pythonie. –

+0

Masz rację, wartość "20" to tylko początek. W końcu znalazłem poprawną implementację '_IO' i uzyskałem wartość 21780. JEDNAKĄ, z' termios.USBDEVFS_RESET' w moim przykładowym kodzie zastąpionym przez '21780' ponownie pojawia się błąd' IOError: [Errno 22] Invalid argument'. Podejrzewam, że czegoś mi brakuje, lub że pierwszy argument do 'fcntl.ioctl' nie jest prostą wartością całkowitą. – Alex

9

natknąłem to patrząc jak zrobić USBDEVFS_RESET i pomyślałem, że podzielę się co znalazłem o _IO: http://bugcommunity.com/wiki/index.php/Develop_with_Python#Introduction_to_ioctl_calls_in_python

Więc, co mam tak daleko jest następujące:

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

Możesz uzyskać busnum i devnum z lsusb.

5

ioctl-opt (pypi) to mały moduł python tłumaczący potrzebne makra preprocesora C na pytona. Aby uzyskać prosty przykład użycia, zobacz tę implementację hidraw.

Należy pamiętać, że konieczne może być zdefiniowanie struktur ctype (w zależności od typu wywołania), aby można było przekazywać parametry.

Ujawnienie: Jestem autorem obu modułów.