LIBUSB_ERROR_TIMEOUT und andere Verbindungsprobleme unter Linux

    • LIBUSB_ERROR_TIMEOUT und andere Verbindungsprobleme unter Linux

      Hallo!

      Ich verwende eine CEBO LC in einem Schaltschrank zusammen mit einem Revolution Pi (basiert auf RPi Compute Module 3) und steuere diese über die Python-API an. Kontinuierliche Messung mit 2000 Hz auf zwei Analogkanälen, abgerufen in Blöcken von 100 Frames.

      Leider treten immer wieder während der Messung Probleme auf, für die ich keine sinnvolle Erklärung finde. Am häufigsten und scheinbar willkürlich findet sich solch eine Meldung:

      Quellcode

      1. Traceback (most recent call last):
      2. File "/home/pi/src/bsp/bsp_ts/measure-cpu/pump_logic/adc_cebo.py", line 74, in acquire
      3. frames = device.readBlocking(self.BLOCK_SIZE)
      4. File "/home/pi/src/teststand-venv/lib/python3.5/site-packages/CeboMsrApiPython.py", line 1018, in readBlocking
      5. _ReadBlocking(self._handle, vvalues, values, frameCount)
      6. File "/home/pi/src/teststand-venv/lib/python3.5/site-packages/CeboMsrApiPython.py", line 95, in _checkError
      7. }.get(errorClass, NotImplementedError("(internal) Unhandled error: " + error))
      8. OSError: Failed to read data from device (using bulk transfer).: LIBUSB_ERROR_TIMEOUT

      Manchmal ist beim nächsten Aufruf von readBlocking() wieder alles okay, manchmal dauert es ein paar Minuten und manchmal geht danach gar nichts mehr. Der Datenabruf erfolgt in einem separaten Thread, der nichts anderes tut, als startContinuousDataAcquisition() und danach in einer Schleife readBlocking().

      Manchmal folgt dem Fehler noch eine Flut von Meldungen bzgl. Pufferüberlauf. Das ist allerdings zu erwarten, wenn das Abrufen der Daten länger nicht geklappt hat:

      Quellcode

      1. Traceback (most recent call last):
      2. File "/var/lib/revpipyload/bsp_ts/measure-cpu/pump_logic/adc_cebo.py", line 74, in acquire
      3. frames = device.readBlocking(self.BLOCK_SIZE)
      4. File "/usr/local/lib/python3.5/dist-packages/CeboMsrApiPython.py", line 1018, in readBlocking
      5. _ReadBlocking(self._handle, vvalues, values, frameCount)
      6. File "/usr/local/lib/python3.5/dist-packages/CeboMsrApiPython.py", line 95, in _checkError
      7. }.get(errorClass, NotImplementedError("(internal) Unhandled error: " + error))
      8. OSError: Buffer overflow.

      Zur gleichen Zeit (aber nur einmalig) fand sich im Kernel-Log die folgende Meldung:

      Quellcode

      1. [Wed Feb 24 03:26:27 2021] WARN::dwc_otg_hcd_urb_dequeue:639: Timed out waiting for FSM NP transfer to complete on 1

      Insbesondere nachdem solch ein LIBUSB_ERROR_TIMEOUT-Fehler auftrat, allerdings auch mal ohne erkennbare Ursache, kann die Karte dann erst gar nicht geöffnet werden und behauptet eine falsche Firmware-Version zu haben. Stimmt natürlich nicht, es wurde nichts am Setup verändert währenddessen.

      Quellcode

      1. Traceback (most recent call last):
      2. File "/home/pi/src/bsp/bsp_ts/measure-cpu/pump_logic/runner.py", line 35, in start
      3. self.adc.start()
      4. File "/home/pi/src/bsp/bsp_ts/measure-cpu/pump_logic/adc_cebo.py", line 44, in start
      5. self.init_device()
      6. File "/home/pi/src/bsp/bsp_ts/measure-cpu/pump_logic/adc_cebo.py", line 30, in init_device
      7. device.open()
      8. File "/home/pi/src/teststand-venv/lib/python3.5/site-packages/CeboMsrApiPython.py", line 832, in open
      9. _Open(_toString23(self._ident), byref(handleb))
      10. File "/home/pi/src/teststand-venv/lib/python3.5/site-packages/CeboMsrApiPython.py", line 95, in _checkError
      11. }.get(errorClass, NotImplementedError("(internal) Unhandled error: " + error))
      12. OSError: The firmware of this device is not supported.
      Alles anzeigen

      Das alles klingt mir nach gelegentlichen Übertragungsproblemen am USB. Verkabelung ist jedoch sehr gewöhnlich: 0,5 m USB-Kabel gut geschirmt inkl. Ferrit, im Schaltschrank drumherum ist sonst nichts aktiv, was ggf. EMV-Störungen aussendet. Die Probleme treten bei mehreren Systemen an unterschiedlichen Standorten auf. Der Rechner ist wie gesagt eine industrielle Implementierung des Raspberry Pi Compute Module 3 (RevPi Connect) mit realtime-Kernel. Ich sehe keinen Grund, warum dieser auf dem USB Probleme bereiten sollte.

      Wie kann ich so einen Fehler weiter diagnostizieren? Geben die Fehlermeldungen für die Cesys-Leute Aufschluss über eine mögliche Fehlerursache? Insbesondere bei der Meldung The firmware of this device is not supported. muss ja etwas im Treiber schief laufen.

      Über jegliche Hilfestellung wäre ich sehr dankbar. Wir haben bereits in drei CEBO LC investiert und müssten notfalls (und ungern) den Hersteller wechseln, wenn kein robuster Betrieb erreicht werden kann.

      Vielen Dank im Voraus!
      André
    • Hallo André,

      auf den ersten Blick sehe ich nicht, woher dieses Problem kommt.
      Einen generellen Hinweis habe ich aber zunächst: Nicht selten
      kommen solche sonderbaren Probleme mit Raspberry Pis dadurch
      zustande, dass die Spannungsversorgung des Raspberry Pis zu
      schwach oder zu instabil ist. Es könnte einige Tage dauern, bis
      wir mit einem ähnlichen Aufbau hier versuchen können, dieses
      Problem nachzustellen.

      Viele Grüße

      Manfred R.
      Software Development
      Cesys GmbH
    • Hallo Manfred,

      vielen Dank für die Antwort. Ich glaube nicht, dass die Spannungsversorgung bei uns in Betracht gezogen werden muss. Das Compute Module sitzt in einem Revolution Pi, welches als industrietaugliche Komponente mit allerlei Zertifizierungen bzgl. Umgebungsbedingungen verkauft wird. Das Gerät wird mit 24 Volt aus einem 10-A-Schaltnetzteil versorgt und stellt daraus die Spannung für's Compute Module bereit. Die zwei USB-Ports können laut Datenblatt in Summe 1 A bereitstellen, woraus lediglich die CEBO LC versorgt wird. Der zweite USB-Port hängt an einem Bildschirm mit integriertem Hub für Tastatur und WLAN-Stick.

      Gibt es ggf. die Möglichkeit, dem Treiber unter Linux eine höhere CPU-Priorität zuzuweisen, falls es an konkurrierenden Kernel-Threads liegt?

      Schöne Grüße
      André
    • Hallo André,

      die Fehlermeldung LIBUSB_ERROR_TIMEOUT bedeutet zunächst genau einen
      Timeout in der Kommunikation mit der CEBO-LC über USB, wobei als
      Timout-Zeitwert 1 Sekunde eingestellt ist.

      Wir haben bisher nicht beobachtet, dass die Firmware der CEBO-LC abstürzt,
      hängt oder verzögert, ausser bei wesentlicher Störstrahlung in der Umgebung
      durch Spannungen im Kilovolt-Bereich. Ein Software-Fehler auf der Seite des
      Raspberry-Pi, der diesen Timeout-Fehler verursacht, wäre auch eher
      unwahrscheinlich.

      Dann bleiben hier als naheliegende Ursache Probleme rund um
      Spannungsversorgung, Kabel, Stecker und andere Störeinflüsse. Wir werden
      hier in den nächsten Tagen noch einen Dauertest mit einem Raspberry Pi
      aufbauen, um uns zu vergewissern, dass es nicht an der Software liegt.

      Viele Grüße

      Manfred R.
      Software Development
      Cesys GmbH
    • Hallo Manfred,

      wie gesagt, Störeinstrahlung und Spannungsprobleme schließe ich eher aus. Der Aufbau ist sehr simpel und elektrisch sauber ausgeführt, in kontrollierter Umgebung.

      Ich kann mir abseits der Firmware auch nicht erklären, woher ein Timeout von einer ganzen Sekunde überschritten werden sollte. Allenfalls, dass die Überprüfung des zugehörigen Timestamps ggf. erst später passiert?

      Wir arbeiten hier mit einer Software, wie gesagt in Python geschrieben, die viele verschiedene Aufgaben "parallel" in Threads erledigt. Da Python aber Threads prinzipiell nur abwechselnd auf einem einzigen CPU-Kern ausführt, kommt es sicher zu unvorhersehbaren Wartezeiten während die CeboMsrApi bedient wird. Der Hinweis aus der API-Dokumentation, readBlocking() in einem separaten Thread auszuführen, löst das Problem eben nur teilweise. Mich würde nicht wundern, wenn ihr bei Cesys das Problem nicht reproduzieren könnt, solange eine simple Testsoftware mit wenigen Threads verwendet wird. Eine solche könnte ich auch gern mal ein paar Tage auf unserem System zum Vergleich laufen lassen.

      Insofern vermute ich die Ursache momentan eher aufseiten unserer Software. Die spannende Frage bleibt allerdings, wie man die CeboMsrApiPython richtig verwendet, wenn parallele Vorgänge in Python abgearbeitet werden müssen. Vielleicht habt ihr da Erfahrungen, z.B. mit dem multiprocessing- statt des threading-Moduls?

      Unsere Messaufgabe hat an sich keine sonderlich hohen Anforderungen: Die 2 Analogkanäle müssen blockweise statistisch beurteilt werden, auf die Ergebnisse davon muss der Rest der Anwendung dann (weniger schnell) reagieren. Zudem sollen die Werte in einer CSV-Datei mit transparenter bz2-Kompression aufgezeichnet werden. Allein schon die Kompression führt aktuell aber regelmäßig zu einem Buffer Overflow, da dies in Python scheinbar auch den Cebo-Thread lahmlegt, bis ein Block fertig komprimiert ist. Solche Buffer Overflows sind zu erwarten und dafür finden wir sicher eine Lösung. Der LIBUSB_ERROR_TIMEOUT hingegen sollte nicht durch blockierte Threads passieren - dass er doch auftritt, könnte somit auf einen Bug in der API hindeuten?

      Bin weiterhin dankbar für jeden Hinweis, das Problem einzugrenzen.

      Vielen Dank und freundliche Grüße
      André