Programmiergerät für SD-Karten

  • Jetzt habe ich auch mal eine Frage...

    In Planung habe ich ein Programmiergerät für (Micro-)SD Karten,
    für mich ist das relativ einfach:

    Code
    sudo dcfldd if=~/image.img of=/dev/sdX


    Wobei das "X" für den Buchstaben des entsprechenden Devices steht.

    Aber, das Gerät soll bis zu 4 images gleichzeitig auf 4 karten kopieren können.
    Und es muss (sehr) DAU-freundlich sein.

    Angedacht ist eine Leiste mit 4 USB-Buchsen, die mit den Buchsen des RPis verbunden sind,
    zum einen weil die USB-Anschlüsse beim RPi zu dicht beienanderstehen, zum anderen ist es einfacher
    eine verschlissene Buchse samt Leitung zu tauschen als die Anschlüsse auf dem RPI.

    Die "Hilfskraft" steckt also die SD-Karte in einen der Anschlüsse, am RPi wechselt jetzt
    eine LED auf rot und wenn das Beschreiben beendet ist, auf grün.
    Danach kann man die SD-Karte herausziehen und eine neue einstecken.
    Soweit der Plan.

    An welchen USB-Port die Karte eingesteckt wurde findet man mit:

    Code
    lsusb -t


    heraus, das Erbebnis sieht dann etwa so aus:

    Code
    $ lsusb -t
    /:  Bus 01.Port 1: Dev 1, Class=root_hub, Driver=dwc_otg/1p, 480M
        |__ Port 1: Dev 2, If 0, Class=Hub, Driver=hub/5p, 480M
            |__ Port 1: Dev 3, If 0, Class=Vendor Specific Class, Driver=smsc95xx, 480M
            |__ Port 3: Dev 8, If 0, Class=Mass Storage, Driver=usb-storage, 480M
            |__ Port 4: Dev 9, If 0, Class=Mass Storage, Driver=usb-storage, 480M


    Port 1 ist das Netzwerk, auf Port 3 und 4 ist ein USB-Speicher.
    Sieht man in /var/log/syslog hinein, so sieht man, das die Laufwerke als sdb (Port 3) und sdc (Port 4) angemeldet wurden.
    Aber in der Reihenfolge des Einsteckens.
    So kann es sein, das Port 4 als sdb angemeldet sein kann und Port 3 als sdc.

    Ich suche also eine Möglichkeit, die Devicenamen mit dem entsprechenden Port zu "verknüpfen".
    Irgendwo sollte man das doch auslesen können.
    Ständig syslog zu scannen halte ich für ziemlich ressourcenfressend, es gibt bestimmt etwas eleganteres.

    Tante Google habe ich schon bemüht, entweder hatte ich die falschen Suchbegriffe und Fragen,
    oder ich bin der erste, der sich damit auseinandersetzt. Aber es muss ja funktionieren, denn der
    Kernel bekommt das ja auch hin.

    Vielleicht hat die hiesige Schwarmintelligenz ja eine Idee...

    MfG

    Jürgen

    Edit: War schon ein bißchen spät...

  • Zitat


    Der Kernel verwendet aber auch /proc und /sys
    /sys/block, /sys/dev/block, /sys/bus/usb/devices, proc/partitions u.A.

    Die Richtung war ungefähr richtig, mit:

    Code
    cat /proc/partitions | grep sd[a,b,c,d]


    bekommt man die Laufwerksbuchstaben fast in Echtzeit heraus.
    Mit:

    Code
    readlink -f /sys/class/block/sda/device


    dann auch die Ports:


    Der Rest ist "nur noch" ein Textfilter...

    MfG

    Jürgen

  • Udev hatte ich noch garnicht im Visier, allerdings kenne ich mich damit auch nicht besonders aus.
    Mit dem was ich bis jetzt herausgefunden hatte, habe ich schon eine Idee.
    Aber das wäre so etwas Ähnliches wie udev, warten auf ein Ereignis, ausführen einer Funktion und wieder beenden.

    Schaun wir mal, was Tante Google so auf der Pfanne hat...

    Ich bin in einer Ideen-Sammelphase, was ich davon wirklich verwende weiss ich noch nicht.
    Im Moment ist nur klar, wie das Gerät aussehen und funktionieren sollte.

    MfG

    Jürgen

    P.S.: Bin am schnuppern: https://wiki.ubuntuusers.de/udev/

  • Hallo Leute,

    ich bin noch an meinem Programmiergerät am basteln,
    nach dem Vorschlag von "Drachenauge" dreamshader mit Udev.
    Die ersten Versuche verliefen einigermaßen erfolgreich, bis auf ...
    Aber der Reihe nach:

    Erstmal die udev-Regel(n): "/etc/udev/rules.d/99-PROG.rules"

    Code
    ACTION=="add", KERNEL=="sd?1", SUBSYSTEMS=="usb", OPTIONS+="watch", OPTIONS+="event_timeout=1500", SYMLINK+="PROG_%k", RUN+="/bin/bash /usr/local/bin/PROG.sh add %k"
    ACTION=="remove", KERNEL=="sd?1", SUBSYSTEMS=="usb", RUN+="/bin/bash /usr/local/bin/PROG.sh remove %k"


    Soweit nichts besonderes, zu den "OPTIONS+" komme ich weiter unten.

    Dann das eigentliche Programmierscript: "/usr/local/bin/PROG.sh"


    Ist noch ein "bißchen" Prototyp, es kam mir erstmal auf den Weg an.

    Wenn man jetzt einen USB-Stick oder SD-Karte einsetzt, geschieht laut "/var/log/syslog" folgendes:


    Die (hier) SD-Karte wird erkannt, und wie man an Debug-Ausgabe an der 4.letzten Zeile erkennt, wird die Udev_Regel auch ausgeführt.
    Dann erfolgt ein Timeout, den ich mit "OPTIONS+="event_timeout=1500," zwar von ca. 30s auf hier 181s verlängern konnte, aber nicht mehr.
    Ein größerer Timeout wird einfach ingnoriert.
    Leider reicht die Zeit für das Programmieren einer 4 GByte-Karte nicht aus, erst recht nicht für größere Karten.
    Die "OPTIONS+="watch"," ist hier noch testweise drin, aber weder "watch" noch "nowatch" haben etwas geändert.
    Stichwort: man udev

    Hier noch die Ausgabe der Dummy Zeitschleife aus der WRITE-Funktion mit "tail -f -n 5 /tmp/PROG_1.tmp"

    Hat jemand eine Ahnung, wie ich den Timeout unterdrücken, besser "Bedienen" kann,
    so das er während des Programmierens nicht auslöst?
    Tante Google habe ich schon genervt, aber nicht so richtig etwas gefunden.

    MfG

    Jürgen

  • Hallo,

    ich habe das Problem mit dem Timeout mittlerweile gelöst.
    Der Trick besteht darin, das Programm nicht direkt aufzurufen,
    sondern über einen Service.
    Dazu legt man erstmal eine Udev-Regel an:

    /etc/udev/rules.d/99-PROG.rules

    Code
    KERNEL=="sd?1", ACTION=="add", SUBSYSTEMS=="usb", SYMLINK+="PROG_%k", RUN+="/bin/systemctl --no-block start PROG@%k.service"

    und danach den eigentlichen Service:

    /etc/systemd/system/PROG@.service

    Code
    [Unit]
    Description=SD-Programmer
    
    
    [Service]
    Type=simple
    ExecStart=/usr/local/bin/PROG.sh add %I

    Das "PROG.sh" vom vorherigen Post kann zum testen erstmal unverändert bleiben.

    Wenn man jetzt einen USB-Stick in einem der USB-Ports steckt, läuft das Programm los,
    vorerst nur als Dummy-Version:

    Dazu kann man mit:

    Code
    watch -n 2 'tail -n 1 /tmp/PROG_1.tmp ; tail -n 1 /tmp/PROG_2.tmp ; tail -n 1 /tmp/PROG_3.tmp ; tail -n 1 /tmp/PROG_4.tmp'


    das Geschehen mitverfolgen.
    Es wird ein Countdown von 5 sek ausgegeben und danach wird von 180 nach 0 heruntergezählt.
    Das Ganze sollte etwa so aussehen:


    Der Name "raspian_stretch_s_.img" ist bei mir eine ca. 4 GByte große Testdatei,
    die ich im Moment noch per Hand eingfügt habe. Das ist noch optimierungsbedürftig.

    Um die Programmierung scharf zu schalten muss man die "#" vor der Zeile (mit dem (pv ...) entfernen, etwa so:

    Code
    # Die eigentliche Programmierung
    (pv -n -p $PFAD/raspian_stretch_s_.img | sudo dd status=none of=/dev/$DEVICE bs=1M) 2>> /tmp/PROG_$PORT.tmp
     sync


    und das "sync" sollte man auch hinzufügen.
    Dann muss man auch noch die Dummy Zeitschleife auskommentieren, sie ist nur für die Tests gedacht.
    Achtung, ab jetzt wird jedes USB-Speichergerät gnadenlos überschrieben!
    Übrigens, statt von 180 auf 0 wird jetzt von 0 auf 100 (%) hochgezählt, also nicht wundern.

    Ebenfalls eine Empfehlung ist, das Verzeichnis /tmp Verzeichnis in eine Ramdisk zu legen:
    /etc/fstab

    Code
    tmpfs                 /tmp            tmpfs   nodev,nosuid,relatime 0       0


    Das entlastet die SD-Karte enorm, der Inhalt war bei mir gerade 36k, mit allen 4 PROG_?.tmp Files.
    Ich denke, das ist akzeptabel. Reboot nicht vergessen.

    Ein Test schaufelte 4*4 GByte auf 4 SD-Karten gleichzeitig,
    allerdings ging der Raspi2B mit einem 1min Load von 12-13 ziemlich in die Knie.

    Jetzt geht es an die Feinarbeit.

    Noch Fragen? Tips? Her damit.

    MfG

    Jürgen

Jetzt mitmachen!

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