GPIO-Aktionen zu langsam

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

    vor kurzem habe ich ein (neues) kleines Hobbyprojekt mit dem RasPi angefangen. Im Grunde ist es ein Netzwerkprogramm dass über die GPIOs funktionieren soll (ich will kein SSH umlegen, sondern meine eigenen Programme für das Netzwerk schreiben und nutzen, soll ja Spaß machen :P).
    Soweit ganz gut, funktionieren tut es, aber die Geschwindigkeit... für eine Datei von 1155 Byte brauche ich über 3min (knapp 160ms/Byte, entspricht pro GPIO-Aktion (insgesamt 3x lesen und 3x schreiben für 1 Bit) ganze 3ms) und ich verstehe nicht ganz warum. Als Schnittstelle zu den GPIOs verwende ich wiringPi (eingebaut in eine Proxy-Class).

    Die Frage ist eig, ob das normal ist oder ob ich etwas falsch mache. Ist wiringPi vielleicht nicht die beste Wahl sondern eine andere Schnittstelle?

    Bei Bedarf gebe ich auch gerne den Code nach, es sind nur 2x 200 Zeilen (mit Kommentaren&Leerzeilen). Sei aber dazu gesagt, dass ich eigentlich Java gelernt habe (laufendes Studium) und erst seit dem Projekt (knapp 6 Tage) mich an C++ versuche, entsprechend "stümperhaft" wird der Code sein (was in meinen Augen aber nicht der Grund für die Geschwindigkeit sein kann).

    Ich würde mich über Antworten freuen,
    mfg Narase

  • Bitteschön. Gpio() ist der Proxy, hinter dessen Methoden stehen nur Aufrufe der wiringPi-API


    • Offizieller Beitrag

    Wenn ich das also richtig verstehe, wandelst du eine Datei in ein Byte Array um und sendest es dann über die GPIOs an einen anderen Pi?
    Da würde ich auf jeden Fall verstehen, wieso diese serielle Schnittstelle dann nicht so flott ist..
    Die Pins gehen doch dann nur auf Low High,...
    Das dauert..

    Oder verstehe ich was falsch?

    <woltlab-metacode data-name="align" data-attributes="WyJjZW50ZXIiXQ=="><p><span style="font-size: 10pt">Ein "Gefällt mir" oder die Bewertung im Profil ist eine nette Geste für die Hilfe die wir hoffentlich waren oder sind.</span></p></woltlab-metacode>


  • Wenn ich das also richtig verstehe, wandelst du eine Datei in ein Byte Array um und sendest es dann über die GPIOs an einen anderen Pi?
    Da würde ich auf jeden Fall verstehen, wieso diese serielle Schnittstelle dann nicht so flott ist..
    Die Pins gehen doch dann nur auf Low High,...
    Das dauert..

    Oder verstehe ich was falsch?


    Nein, du hast es genau erfasst. Warum dauert es aber so lange? Oder um die Antwort für mich verständlicher zu machen, warum ist USB/Ethernet so viel schneller darin seine Leitungen zu schalten?

    Nachtrag:
    Laut diesem Artikel hier sind mit C 22MHz möglich. Das ist Welten von dem entfern was ich erreiche. Selbst die Shell kommt auf 3,4kHz, auch ein schönes Stück schneller als mein Code.
    (http://codeandlife.com/2012/07/03/ben…-pi-gpio-speed/)

    Einmal editiert, zuletzt von Narase (10. Februar 2015 um 22:03)

  • Servus Narase,


    Warum dauert es aber so lange? Oder um die Antwort für mich verständlicher zu machen, warum ist USB/Ethernet so viel schneller darin seine Leitungen zu schalten?

    Für USB 2.0 sind im µP (SoC) des RaspberryPi entsprechende Schaltungen enthalten, die das USB-Protokoll direkt umsetzen. Dafür ist kein einziges Byte Code notwendig. Es werden (vermutlich) lediglich einige Steuerregister durch den Code gesetzt, um bestimmte Funktionen anzusteuern. Bei USB 2.0 läuft das mit einer Datenrate von 480MBit/s. Allerdings sind das nicht nur Nutzdaten, es muss auch ein Overhead für das USB-Protokoll mitgeschickt werden. In die Kie geht's erst, wenn mehrere Geräte (über USB-Hubs) am USB-Basisknoten hängen. Die müssen sich nämlich die 480MBit/s teilen. Kurz und gut, in jedem Fall um Welten besser!

    Bei Ethernet ist es ähnlich. Am RasPi sind "nur" 100MBit/s möglich, also kein Gigabit-LAN, da die Ethernet-Funktionalität über ein (auf der Leiterplatte integriertes) USB-Device realisiert ist. Der Chip dieses USB-Ethernet-Devices wurde für die Netzwerkkommunikation entwickelt und kommt ebenfalls mit ganz wenig Prozessorcode zur Steuerung aus. Für 100MBit/s reichen die 480MBit/s von USB 2.0 allemal.

    Ich weiß, das hilft Dir noch nicht viel, um Dein Programm zu verbessern.
    Versuch es doch über UART: Die GPIO-Pins 8 und 10 lassen sich für die Verwendung als UART-Schnittstelle verwenden, Pin8=TxD und Pin10=RxD. Bei UART handelt es sich um das Protokoll, das auch an der seriellen Schnittstelle am PC (COM1, COM2 etc. an den 9-poligen DSUB-Steckern) zur Anwendung kommt. Am PC sind Übertragungsraten von 9600Bit/s - 115200Bit/s möglich. Bei 9600 Bit/s (oder Baud) dauert die Übertragung eines Bytes knapp 1ms, 1 kByte wird somit in ca. 1 Sekunde übertragen, bei 115200 Baud dann 12x so schnell.
    Zum Anschluss des RasPi an den PC über die serielle Schnittstelle brachst Du noch einen entsprechenden Pegelumsetzer als Hardware. Verwende dafür einen IC von MAXIM mit der Bezeichnung MAX232 oder einen artverwandten. Der TxD-Pin vom RasPi (Pin 8) muss auf den RxD-Pin vom PC (Pin 2 des DSUB-Steckers) und der RxD-Pin vom RasPi (Pin 10) auf TxD vom PC (Pin 3). Die Leitungen müssen also gekreuzt werden!

    Da ich meinen RasPi erst ein paar Tage habe, habe ich sowas noch nicht in der Praxis getestet, aber da dürften wenig Probleme auftreten. Wichtig ist, dass die Parameter auf beiden Seiten gleich sind:
    Baudrate (z.B. 9600 Bit/s)
    Parity (NONE, ODD, EVEN, MARK SPACE)
    Data Bits (7 oder 8)
    Stop Bits (1, 2)

    Vielleicht hilft Dir das?

    Peter

    Wichtig:

    Bei der UART-Verbindung auf den PC muss natürlich neben den Datenleitungen auch die Masse von PC und RaspberryPi verbunden werden! Am PC liegt die Masse auf dem 9-poligen DSUB-Stecker an Pin 5

    Peter

  • > Kann trotzdem jemand erklären warum im Artikel die Anschlüsse im MHz-Bereich verwendet werden konnten?
    Die haben nicht gewartet bis das Bit uebernommen wurde !

    Wie schnell laeuft der Code wenn echoDelay leer ist ?

    - - - - - - -

    Und die ganz hohen Frequenzen haben sie erreicht, als sie am Kernel
    vorbei direkt auf die Hardware zugegriffen haben.

    Allerdings provoziert dann jeder Interrupt einen Aussetzer in der Messkurve ...

    Also Timer-Interrupt aus, Netzwerk-Interrupt aus, USB-Interupt aus, und
    wohl noch ein paar mehr.

    Richtig, der PI ist dann vollkommen tot, er macht nur noch eine Rechteckkurve :fies:

  • Gut, ich hab dann mal aus purer Neugierde meine Raspis neu aufgesetzt (System neu überspielt, nur wiringPi installiert und Programme rüber). War wohl irgendwas im System nicht mehr so wie es sein sollte. Erster Testlauf ergab dann nämlich 90kByte/s (eine 10MByte-Datei in 110s), macht im großen und ganzen 2.160.000 Pin-Aktionen pro Sekunde.
    Damit kann ich auf jeden Fall zufrieden sein =).

    Zitat

    root@raspberrypi:~# time ./SendC
    fileLengthBytes_s gesendet
    Sende 10000000 Bytes
    Uebertragung abgeschlossen

    real 1m49.905s
    user 1m49.230s
    sys 0m0.330s

    Ich bedanke mich ganz herzlich bei allen die mir helfen wollten, letztendlich konnte natürlich niemand ahnen dass ich mein System irgendwann mal geschossen hatte.
    mfg Narase

    Einmal editiert, zuletzt von Narase (11. Februar 2015 um 12:19)

  • "schlizbäda" hat Dein Problem eigentlich sehr schön beschrieben und auch Lösungsmöglichkeiten angedacht.

    "wiringpi" ist sicher nicht die Lösung, um eine effiziente Datenübertragung zu erreichen, dafür ist es auch gar nicht gedacht.

    Gruß, mmi

Jetzt mitmachen!

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