i2c Modul funktioniert nach "halt" Befehl nicht mehr

Heute ist Stammtischzeit:
Jeden Donnerstag 20:30 Uhr hier im Chat.
Wer Lust hat, kann sich gerne beteiligen. ;)
  • Hallo,

    da ich nun schon länger an diesem Problem hänge, wollte ich es mal bei euch versuchen.

    Ich habe auf dem Raspberry Pi ein Python Script geschrieben, welches mit Hilfe des Adafruit Breakout Boards, NFC Karten lesen und dann LED's ansteuern, sowie die gescannte ID über Serielle Schnittstelle senden kann. Dieses Script soll auch beim booten des Pi's gestartet werden. Das ganze funktionierte auch bei meiner SD-Karte unter Rasbian einwandfrei, weswegen ich angefangen habe das ganze zu dokumentieren und reproduzierbar zu machen. Beim Aufsetzen einer neuen SD-Karte mit Rasbian kam dann das Problem:

    Dieses Script funktioniert nun ohne Probleme wenn ich es manuell, mit

    Code
    sudo python3 /home/pi/ordner/script.py


    starte. Auch kann ich den Pi rebooten und komplett vom Netz trennen, nach einem Neustart kann ich das Script wieder starten.

    Wenn ich es aber automatisch beim booten mit Hilfe von /etc/rc.local in Form von

    Code
    ...
    
    
    # Starten des Scripts
    (sleep 5;python3 /home/pi/Ordner/Script.py)&
    
    
    exit 0


    starten lasse, dann funktioniert es erstmal nach einem reboot, benutze ich aber einen "halt" Befehl und starte den Pi neu, wird das Breakout Board mit

    Code
    i2cdetect -y 1


    (bzw generell kein i2c Gerät mehr) erkannt und das Script hängt sich beim konfigurieren des BB auf.

    Dieses Problem kann ich nur beheben wenn ich danach den Start Befehl aus der /etc/rc.local entferne und das i2c-dev modul mit

    Code
    sudo modprobe -r i2c-dev  #bzw sudo rmmod i2c-dev
    sudo modporbe i2c-dev


    neu hinzufüge.
    Nach einem Neustart wird das BB wieder erkannt und ich kann das Script nochmal normal starten.

    Ich habe Rasbian geupdatet, den Kernel aktualisiert und selbst das komplette System mehrmals neu aufgesetzt. Alles klappt solange bis ich das Python-Script beim booten starten lasse. Auch habe ich es über ein Launcher-Batch-Script, crontab und die bachrc versucht zu starten. Dabei macht immer nur der Teil des Scriptes mit i2c Probleme.

    Ich benutze dabei die py532lib von HubCityLabs und folgendes vereinfachtes Script:

    Spoiler anzeigen


    Ich hoffe ich hab das Problem ausführlich und verständlich beschrieben.

    Weiß jemand einen Vorschlag, woran das liegen könnte oder braucht Ihr noch weitere Infos?

    Grüße TDog

  • i2c Modul funktioniert nach "halt" Befehl nicht mehr? Schau mal ob du hier fündig wirst!

  • Wo bzw wie hast du das laden des i2c Kernel Modules denn eingebunden?
    Vielleicht reichts ja das Module direkt vor dem Ausführen des Python Scripts zu laden :huh:


    Das Script macht so wie es geschrieben ist nicht soo viel Sinn für /etc/rc.local oder Crontab, weil "clear" wird nicht wirklich gehen da das Script dann nicht über eine tty Konsole ausgeführt wird. Mal davon abgesehen das man os.system nicht mehr benutzen sollte ;)

    Es wäre auch besser du würdest auch zur python3 Binary den vollständigen Pfad angeben, denn es kann gut sein das zu dem Zeitpunkt der Ausführung noch keine PATH environment variable gesetzt wurde und das System somit vergeblich danach "sucht" bzw eben nicht danach suchen kann..

    Auch der Shebang " #!/usr/bin/env Python3 " wird so nicht funktionieren da es kein Python3 gibt sondern nur python3 ... GROSS-/kleinschreibung ist bei Linux enorm wichtig!

    Bei einigen print() Zeilen wär ich mir auch nicht so sicher ob die wirklich python3 kompatibel sind... gerade beim mischen von str und int 's ist python3 etwas pingelig

  • Ich habe i2c beim ersten start mit "raspi-config" aktiviert und i2c-dev in /etc/modules eingetragen.

    Der Raspberry Pi ist über HDMI an einen Monitor angeschlossen und der "clear" Befehl soll eben den Bildschirm von unnötigen Informationen befreien. Auch sind die ganzen "print" Befehle momentan nur für ein visuelles Feedback für mich drin.

    Warum benutzt man denn "os.system" nicht mehr, bzw was ist denn die alternative?


    Ist denn der Pfad "/home/pi/ordner/script.py" nicht vollständig?
    Jedenfalls startet er das Script ja, nur stoppt bei dem Befehl:

    Code
    Pn532_i2c().SAMconfigure()

    Das mit der Shebang hab ich schonmal geändert, danke.

    Die "print" Befehle funktionieren eigentlich alle, aber bei welchen hast du denn Bedenken?
    Die ID kommt als Bytearray an und wird dann zu einem geordneten str umgewandelt und zu cardID.


    Grüße TDog

  • Der Raspberry Pi ist über HDMI an einen Monitor angeschlossen und der "clear" Befehl soll eben den Bildschirm von unnötigen Informationen befreien. Auch sind die ganzen "print" Befehle momentan nur für ein visuelles Feedback für mich drin.

    Wie gesagt, wenn das Script über /etc/rc.local oder /etc/crontab oder "crontab -e" ausgeführt wird, gibt es keine Ausgabe auf deinem Bildschirm oder allg. Konsole! Deshalb macht das für einen der genannten "automatischen Start"-Möglichkeiten keinen Sinn ;)

    Warum benutzt man denn "os.system" nicht mehr, bzw was ist denn die alternative?

    Weil das veraltet ist und durch subprocess ersetzt wurde


    Ist denn der Pfad "/home/pi/ordner/script.py" nicht vollständig?

    Nicht den Pfad zum Script, sondern der Pfad zur Binary: python3

    Jedenfalls startet er das Script ja, nur stoppt bei dem Befehl:

    Code
    Pn532_i2c().SAMconfigure()

    Dass das Script ansich startet war schon klar - nur hast du ja geschrieben das es ausschließlich nach einem "halt" Probleme mit dem i2c Kernel Module gäbe und nur ein erneutes laden des Modules das Problem beheben würde :huh:

    Deshalb würde ich einfach mal probieren das Module stattdessen direkt vor dem laden des Scripts zu laden - bzw alle dafür benötigten Module. Denn es kann gut sein dass das Script zu früh geladen wird zu einem Zeitpunkt wo das Kernel Module noch nicht geladen ist.

  • Da die visuellen Befehle später wieso entfernt werden, wäre das kein Problem. Wobei sich der Rasperry Pi auch automatisch auf den Benutzer pi einloggt und so das Script auf dem Bildschirm angezeigt wird.
    Ich werde mir aber trotzdem mal das subprozess modul ansehen. :thumbs1:

    Die /etc/rc.local hab ich jetzt ergänzt


    die Zeit zum laden der Module erhöht und die Module i2c-dev und i2c-bcm2708 nochmals davor laden lassen. Da bei den Befehlen ja kein & Zeichen dahinter steht, müssten die nächsten Befehle ja warten, bis diese ausgeführt sind.


    Jedenfalls hilft das erneute Laden des i2c-dev Modules und entfernen des Eintrages in der rc.local, zusammen mit einem neustart, i2c wieder zum laufen zu bekommen.
    Deswegen bin ich mal davon ausgegangen, dass es an diesem Modul liegt. :denker:


    Leider klappt es damit immer noch nicht. Das Script startet zwar noch, aber es bleibt an der selben stelle hängen. Aber dieses Problem hatte ich ja auch mit den anderen Methoden für das automatische starten eines Scriptes.

    Was ich vergessen hatte zu erwähnen:
    Der Befehl i2cdetect -y 1 spuckt folgendes aus, egal ob der nfc chip gelesen wird oder nicht

    Spoiler anzeigen


    Grüße TDog

  • "/usr/bin/env python3" solltest du an der Stelle nicht nutzen da es nicht das Problem behebt... Ich erinner noch mal an den Grund:

    Es wäre auch besser du würdest auch zur python3 Binary den vollständigen Pfad angeben, denn es kann gut sein das zu dem Zeitpunkt der Ausführung noch keine PATH environment variable gesetzt wurde und das System somit vergeblich danach "sucht" bzw eben nicht danach suchen kann..

    Den absoluten Pfad zur Binary findest du mithilfe des Befehls which heraus, also: which python3

    Und das selbe Spiel erneut für den modprobe Befehl ...


    In /etc/rc.local wird kein sudo benötigt da die Datei bzw das Script bereits als root ausgeführt wird.

    Desweiteren werden Scripts von oben nach unten abgearbeitet. Erst nachdem das laden der Module abgeschlossen ist wird die nächste Zeile ausgeführt, vorallem da du diesen Zeilen auch kein "&" angehängt hast. Das sleep in deiner Befehlsgruppierung solltest du dir also eigentlich auch sparen können.

    Ich würde lieber etwas mehr Code dazu basteln, was aber in einem separeten bash Script besser aufgehoben wäre.
    Also:

    /etc/rc.local:
    [code=php]# Starten des Scripts
    /bin/bash /home/pi/Ordner/i2c_startup.sh &

    exit 0[/php]

    /home/pi/Ordner/i2c_startup.sh:
    [code=php]
    /sbin/modprobe -r i2c-dev >/dev/null 2>&1

    while true; do
    if [ -z "$(/sbin/lsmod | /bin/grep i2c-dev)" ]; then
    /sbin/modprobe i2c-dev >/dev/null 2>&1
    else
    break
    fi
    /bin/sleep 3
    done

    /sbin/modprobe i2c-bcm2708 >/dev/null 2>&1
    /bin/sleep 5
    /usr/bin/python3 /home/pi/Ordner/Script.py &

    exit 0
    [/php]

    Was das macht ist schnell erklärt:
    Erst entläd es das i2c-dev Module.
    Dann dreht sich die while Schleife solange im Kreis bis das Module über lsmod aufgelistet wird - was ein Indikator für fertig geladen sein sollte.
    Wenn das Module über lsmod auftaucht wird die Schleife via break unterbrochen. Erst danach wird der nachfolgende Code ausgeführt:
    Laden des anderen Modules und danach das starten des Python Scripts.


    Was aber auch noch sein könnte ist dass das python Script vielleicht gar nicht mehr läuft? Hast du das mal kontrolliert? -> ps aux | grep Script.py


    //EDIT: Pfade im Script etwas angepasst..


  • ...
    if [ -z "$(lsmod | grep i2c-dev)" ]; then
    ...


    konsequenterweise wäre es wohl sinnvoll, dann auch für lsmod und grep die absoluten Pfade, also:

    Code
    if [ -z "$(/sbin/lsmod | /bin/grepi2c-dev)" ]; then


    anzugeben.
    Inwiefern die Kürzel für das test-Kommando auch einen Pfad benötigen, sei mal dahingestellt.
    Sicherheitshalber könntest Du auch

    Code
    if /usr/bin/[ -z "$(/sbin/lsmod | /bin/grepi2c-dev)" ]; then


    schreiben.
    Ich persönlich würde allerdings einfach den Pfad entsprechend erweitern und den ganzen Kram mit absoluten Pfadangaben weglassen ... ohne export ist der Pfad nach Beenden des scripts eh unverändert.

    cu,
    -ds-

  • Code
    if /usr/bin/[ -z "$(/sbin/lsmod | /bin/grepi2c-dev)" ]; then

    Da fühl ich mich jetzt ein bisschen veräppelt :fies:

    Oder ist das nur ein Flüchtigkeitsfehler?
    Also nicht das vergessene Leerzeichen sondern das /usr/bin/ vor [ :huh:
    die if Schleife ist Teil von bash, und das wurde aus der /etc/rc.local mit absolutem Pfad aufgerufen

  • wieso veräppelt???
    Schon mal nachgeschaut?

    Code
    pi@raspberrypi ~ $ which [
    /usr/bin/[

    btw: das Leerzeichen ist irgendwo verschütt' gegangen ... k.A. wo ...

    //EDIT: vielleicht noch der Vollständigkeit halber: ich glaube mich zu erinnern, dass die Kurzform (also die eckige Klammer) früher - unter Unix bzw. BSD - mal ein harter link auf /usr/bin/test war.

    cu,
    -ds-

  • Hm, Oke... Man lernt nie aus :thumbs1:

    http://superuser.com/questions/3345…how-do-i-use-it

    Zitat

    Note that [ is both a shell built-in and a external program with the same (or similar) usage. In bash, when you run [ or test you are invoking the built-in.

    Wir haben also quasi beide Recht :D
    Entweder /usr/bin/[ nutzen, oder die built-in von bash (nicht sh!)

    Aber in diesem Fall nutzen wir die build-in von bash, genauso wie "while" oder "break" usw

  • Hi,
    es geht doch nicht um recht haben oder nicht ... :fies: ... mir jedenfalls nicht ... deswegen ja das 'sei mal dahingestellt'.
    Ich seh' das mehr als ein wenig zusätzliche "Bildung" nebenbei bzw. Vermittlung von Hintergrund-Wissen ...

    wobei wir jetzt mal wieder so was von OT sind ...
    cu,
    -ds-

  • Danke erstmal für das Feedback.


    Zitat von meigrafd

    "/usr/bin/env python3" solltest du an der Stelle nicht nutzen da es nicht das Problem behebt...


    Da hab ich wohl etwas verwechselt.

    Habe jedenfalls das Script

    Spoiler anzeigen


    getestet und die /etc/rc.local angepasst.
    Das Bash Script fügt i2c-dev hinzu und startet dann das Python Script wie gewünscht, nur bleibt es trotzdem an der gleichen stelle stehen.

    ps aux | grep TEST.py gibt dann folgendes heraus:

    Code
    root      2191 10.0  1.3   9464  6244 ?        D    08:56   3:50 /usr/bin/python3 /home/pi/project/TEST.py
    pi        2661  0.0  0.1   4144   852 pts/2    S+   09:35   0:00 grep --color=auto TEST.py

    Wenn ich dann das Script gleichzeitig manuell starte und es dann an dieser Stelle abbreche kommt diese Fehlermeldung:

    Spoiler anzeigen


    Grüße TDog

    Einmal editiert, zuletzt von TDog (3. Februar 2015 um 15:02)

Jetzt mitmachen!

Du hast noch kein Benutzerkonto auf unserer Seite? Registriere dich kostenlos und nimm an unserer Community teil!