Pyhton, Raspberry und USB

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
cjung
User
Beiträge: 7
Registriert: Freitag 21. Februar 2014, 13:04

Hallo

ich habe ein größeres Problem, wo ich nichts zu im Netz finde und ich hoffe hier ist jemand, der mir dort helfen kann.
Ich arbeite in einer kleine Firma, die sich mit USB-Schnittelstellen befasst und wir wollen unsere Beispiele mit Python erweitern.

Nun habe ich einige Skripte unter Windows geschrieben, die auch anstandslos funktionieren.
Nun habe ich das ganze natürlich auf ausgelegt, das es unter Linux auch funtkionieren soll. Wenn ich meine VM mit Ubuntu laufen lasse
und das Skript dort starte bekomme ich auch Daten zurück aus den API-Funktionen.

Nun habe ich das ganze auch auf einem Raspberry versucht und dort Fehlanzeige. Dort kommt überall (außer bei IowKitGetVersion, da kommt ein String) nur 0 zurück. Ich gehe mal davon aus, das es am ARM-Prozessor liegt oder irgend etwas, was ich nicht importiert und umgewandelt habe.
Nun meine eigentliche Frage, weiß jemand Rat, was ich tun kann?

Hier mal ein einfaches Beispiel.

Code: Alles auswählen

#!/usr/bin/env python3.3
import os, sys, atexit, ctypes
from ctypes import *

# Defines
IOW_PIPE_IO_PINS = ctypes.c_ulong(0)
IOW_PIPE_SPECIAL_MODE = ctypes.c_ulong(1)

IOWKIT_PRODUCT_ID_IOW40 = 0x1500
IOWKIT_PRODUCT_ID_IOW24 = 0x1501
IOWKIT_PRODUCT_ID_IOW56 = 0x1503
IOWKIT_MAX_PIPES = ctypes.c_ulong(2)
IOWKIT_MAX_DEVICES = ctypes.c_ulong(16)
IOWKIT_SPECIAL_REPORT = ctypes.c_ubyte * 8
IOWKIT56_SPECIAL_REPORT = ctypes.c_ubyte * 64
IOWKIT56_IO_REPORT = ctypes.c_ubyte * 8
SERIAL_NUMBER_BUFFER = ctypes.c_ubyte * 9

try:
    if sys.platform == "linux2":
        _lib = ctypes.CDLL("libiowkit.so")
    if sys.platform.startswith("win"):
        _lib = ctypes.WinDLL('iowkit')
      
except:
    print("Fehler beim Laden der API")


_lib.IowKitOpenDevice.restype = c_ulong
_lib.IowKitOpenDevice.argtype = []
_lib.IowKitCloseDevice.argtypes = None
_lib.IowKitCloseDevice.argtypes = [c_ulong]
_lib.IowKitGetNumDevs.restype = c_ulong
_lib.IowKitVersion.restype = c_char_p
_lib.IowKitGetRevision.restype = c_ulong

#_lib.IowKitGetProductId.argtypes = [ctypes.c_voidp]
#_lib.IowKitGetProductId.restype = ctypes.c_ulong

#_lib.IowKitGetDeviceHandle.argtypes = [ctypes.c_ulong]
#_lib.IowKitGetDeviceHandle.restype = ctypes.c_voidp

#_lib.IowKitSetTimeout.argtypes = [ctypes.c_voidp, ctypes.c_ulong]

#_lib.IowKitWrite.argtypes = [ctypes.c_voidp, ctypes.c_ulong, ctypes.c_voidp, ctypes.c_ulong]
#_lib.IowKitRead.argtypes = [ctypes.c_voidp, ctypes.c_ulong, ctypes.c_voidp, ctypes.c_ulong]
#_lib.IowKitReadImmediate.argtypes = [ctypes.c_voidp, ctypes.POINTER(ctypes.c_ulong)]

# always close devices at exit
# maybe ensure driver version _lib.IowKitVersion() >= 1.4 ?
#atexit.register(_lib.IowKitCloseDevice, None)


print("OS: ", sys.platform)
print("Python Version: ", sys.version)
print("Library: ", _lib)
print("\r\n")
print("DLL Version: ",_lib.IowKitVersion())  #String kommt !
print("Handle: ",_lib.IowKitOpenDevice())

iow = _lib.IowKitOpenDevice()
print ("Handle: ", iow)

print("Revision: ", _lib.IowKitGetRevision(iow))
print("Found Devices: ", _lib.IowKitGetNumDevs())

if iow:
    handle = _lib.IowKitGetDeviceHandle(0)
    if not handle:
        print ("Error DeviceHandle")

    print ("IO-Warrior Handle: ", iow)

if not iow:
    print ("No Device Found")


_lib.IowKitCloseDevice(iow)
ich habe eine Raspberry Pi mit dem Aktuellen Wheezy und Python 3.2.3.

Vielen Dank für eure Hilfe
BlackJack

@cjung: Als erstes würde ich versuchen ob ein C-Programm welches das gleiche macht funktioniert.
cjung
User
Beiträge: 7
Registriert: Freitag 21. Februar 2014, 13:04

Oh hätte ich erwähnen sollen.
Der Selber C-Code läuft ohne Probleme
BlackJack

@cjung: Dann würde ich als nächstes schauen welcher Fehlercode gesetzt wird: `ctypes.get_errno()` und das `errno`-Modul um den in was lesbares umzuwandeln. Oder `os.strerror()`.
cjung
User
Beiträge: 7
Registriert: Freitag 21. Februar 2014, 13:04

Ich hab folgendes in mein Skript eingefügt:

Code: Alles auswählen

_lib = ctypes.CDLL("libiowkit.o", use_errno=True)
und dann unter die Open() Funktion, die mir ein Handle zurückliefern sollte

Code: Alles auswählen

iow = _lib.IowKitOpenDevice()
print(os.strerror(cytpes.get_errno()))
Und das Ergebnis ist "No such File or Directory".

War das oben korrekt eingegeben? Ich bin noch recht unbeholfen mit Python. Bin Eher der C-Programmierer
Sirius3
User
Beiträge: 17747
Registriert: Sonntag 21. Oktober 2012, 17:20

@cjung: .o-Dateien können normalerweise nicht geladen werden. Entweder ist die Datei ist einfach falsch benannt, oder Du mußt Dir die passende .so-Datei besorgen.
BlackJack

@cjung: Hm, dann scheint die Bibliothek aus irgendwelchen Gründen die entsprechenden Dateien unter /dev/usb/ nicht zu finden, vermute ich mal. Ich denke da würde ich bei der Suche als nächstes wie bei C mit ``strace`` weitermachen um heraus zu finden welche Datei genau da versuchst wird zu öffnen.
cjung
User
Beiträge: 7
Registriert: Freitag 21. Februar 2014, 13:04

@Sirius3: Das mit dem .o ist ein Tippfehler hier im Forum. Im Code ist es libiowkit.so. Sie wird ja auch geladen so wie es scheint.

@BlackJack: Ich versteh nicht, warum Python es nicht findet, wenn ich das gleiche in einem C-Programm problemlos aufrufen kann.

Das Kuriose ist, ich habe mir ein Cubietruck board besorgt und dort das gleiche Skript mit dem selben Python laufen lassen und dort
läuft es.

Gibt es evtl. bekannte Probleme mit Python, USB und Raspberry? Oder liegt es vielleicht am Wheezy, was drauf läuft?
BlackJack

@cjung: Mir ist da nichts bekannt. Wie gesagt, ich würde schauen was genau passiert, also welche Datei da versucht wird zu öffnen wo das dann fehl schlägt. Und das dann auch mit dem C-Programm vergleichen.

Ist denn sonst alles gleich bei den beiden Programmen, also wurden die vom gleichen Verzeichnis aus mit dem gleichen Benutzer und der gleichen Umgebung aufgerufen? Und auch zeitlich naheliegend, also nicht das C-Programm letzte Woche und das Python-Programm jetzt, und jetzt ist halt irgendetwas anders, zum Beispiel das Kernelmodul für IOWarrior nicht geladen oder so? Sind die entsprechenden Dateien unter /dev/usb/ denn vorhanden wenn man das Verzeichnis auflistet?
cjung
User
Beiträge: 7
Registriert: Freitag 21. Februar 2014, 13:04

@BlackJack: Ich werd am Montag mal schauen was versucht wird zu laden.

Bei beiden Systemen ist alles außer das Linux gleich Raspberry = Wheezy, Cubietruck = Fedora 20) und beides in der aktuellen Version. Alle Rechte sind die Selben und auch der Benutzer (root).
Das C-Programm und das Python-Programm hab ich am selben Tag erstellt und auch jeweils auf den Systemen mit GCC kompiliert.
Die IO-Warrior sind fest im Kernel integriert und mit modprobe auch geladen. Vor der Seite aus gibt es anscheinend keine Probleme.

Ich werd am Montag mal ein anderes System auf den Raspberry spielen um auszuschließen, dass es am Linux selber liegt.
cjung
User
Beiträge: 7
Registriert: Freitag 21. Februar 2014, 13:04

So ich habe mal geschaut wo der eigentliche Pfad ist, wo die IO-Warrior abgelegt werden. Der ist unter /dev/usb/ und dort dann dein einzelnen "Datein".
In der libiowkit.so ist dieser Pfad auch hinterlegt und es wird vom C-Programm auch korrekt geladen.

Ist das vielleicht irgend etwas mit den Rechnten, wenn Python sowas überhaupt berücksichtigt?
BlackJack

@cjung: Ob ein Programm Rechte berücksichtigt oder nicht kann nicht das Programm entscheiden. Wenn man in Programmiersprache X ein verwehrtes Zugriffsrecht einfach umgehen könnte, dann wäre das Konzept der Zugriffsrechte schliesslich sinnfrei weil dann einfach die Schadsoftware in Programmiersprache X geschrieben würde.

Deswegen fragte ich ja ob die Benutzer und die Umgebung gleich ist.

Und wie schon gesagt, würde ich mit ``strace`` mal vergleichen was die beiden Programme jeweils genau versuchen zu öffnen.
cjung
User
Beiträge: 7
Registriert: Freitag 21. Februar 2014, 13:04

So das ganze "Problem" hat sich nun geklärt.
Es lag daran, dass Windows sich mit Geräten anders Verhält als Linux. Unter Linux muss man das ganze als root oder mit sudo ausführen, damit es geht.
Das es mit dem C-Programm funktionierte lag daran, dass es von vornherein mit root-Rechten gestartet wurde und ich das erst jetzt bemerkt habe.

Danke für eure Hilfe und eure Zeit
Antworten