- LiTime Speicher und Akkus         
Ergebnis 1 bis 10 von 96

Thema: C++ fstream GPIO Trigger/Interrupt

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    10.04.2005
    Ort
    Bad Aibling
    Beiträge
    212

    C++ fstream GPIO Trigger/Interrupt

    Hi Mädels ... Jungs ...

    Ich baue mir gerade eine C++ Klasse für den Raspberry um einfacher mit den GPIO arbeiten zu können. Das konfigurieren und je nachdem ob Out/In kann ich den GPIO auch lesen und schreiben. Nur den als Trigger zum Auslösen von Funktionen zu benutzen habe ich Probleme. Die meisten anderen benutzen nicht fstream dafür was meiner Meinung nach Grund genug ist den zu benutzen oder es zumindest mal zu probieren.

    Hier ist die Klasse zu finden: https://git.hts-software.de/index.ht.../Gpio/Gpio.hpp in der Funktion checkTrigger ist ein unvollständiges Beispiel mit poll.

    Um aber einen GPIO als Trigger zu benutzen muss man überwachen ob dieser sich verändert. Normal macht man das mit z.B. poll, epoll. Der benötigt aber leider den Filedeskriptor den ich bei einem fstream ja nicht habe. Ich vermute mal das auch ein fstream eine Möglichkeit hat um abzufragen ob sich dieser verändert hat. Leider habe ich das auch nach längerer Suche nicht gefunden. Man findet da irgendwie immer nur die C Lösung mit poll oder besser epoll.

    Grüße
    Alexander

  2. #2
    Erfahrener Benutzer Roboter-Spezialist Avatar von schorsch_76
    Registriert seit
    25.03.2012
    Ort
    Kurz vor Neuschwanstein
    Alter
    47
    Beiträge
    456
    Hallo Alexander,

    ich würde die Datei einfach mit open() öffnen. Auf den GPIO schreibst du ja keine Datei sondern nur mal 1/0. Dann geht auch epoll/select/poll.

    Siehe zur Konvertierung OStream->file descriptor
    https://gcc.gnu.org/ml/libstdc++/2000-q1/msg00049.html

    > So will the new libstdc++ provide such a way?

    If you compile the current CVS libstdc++ with _STREAM_COMPAT, you get
    a filedesc() method on an fstream object, returning the file
    descriptor. Alternatively, you can use fstream::rdbuf()->fd()
    (which filedesc() is a short-hand for).

    Regards,
    Martin
    Vielleicht hat ja die aktuelle libstdc++ diese Methode da der Post von ca 2000 ist, muss das nicht mehr stimmen.

    Gruß
    Georg

    - - - Aktualisiert - - -

    Siehe auch https://www.ginac.de/~kreckel/fileno/

  3. #3
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    10.04.2005
    Ort
    Bad Aibling
    Beiträge
    212
    Mit open und poll/epoll weiß ich ja wie es geht. Deshalb mal der Versuch es anders zu machen. Bei solchen Experimenten sind schon manches mal erstaunliche Dinge entdeckt worden.

    Das erste hatte ich auch schon gefunden geht aber leider nicht:
    Code:
    ../Gpio.hpp:117:55: Fehler: »std::basic_fstream<char>::__filebuf_type {aka class std::basic_filebuf<char>}« has no member named »fd«
           pollIntPort.fd      = fileIntPortValue.rdbuf()->fd();
    Das zweite müsste ich mal probieren es sieht aber ein bisschen merkwürdig aus.

    Eigentlich dachte ich würde ein fstream das können aber scheinbar halten das die Macher der Standards für nicht wichtig das ein Programm über die Ankunft neuer Daten in Kenntnis gesetzt wird. Merkwürdig ...

    Vielleicht gibt es ja den Weg anders herum das ich zuerst mit open das File öffnen und dann den Deskriptor einem fstream übergebe. Oder so ähnlich ...

    Also nicht wirklich was ich mir vorstelle aber der Theorie nach kann man zum lesen Dateien ja auch mehrfach öffnen. Dann könnte man einfach schreiben und Daten lesen über den fstream und das überwachen für den Trigger mit open und epoll. Auch nicht wirkllich gut die Idee ...

  4. #4
    shedepe
    Gast
    Ich würde vorschlagen, dass man sich die Arbeit spart selbst eine GPIO implementierung für den Pi zu schreiben und stattdessen WiringPi verwenden. Das kann auch die Sache mit den Interrupts (http://wiringpi.com/reference/priori...s-and-threads/). Jetzt kann man sagen: ohh ok das verwendet ja einen Thread um den Zustand im Hintergrund zu pollen. Ja das stimmt. Wenn man sich aber mal anschaut wie so ein GPIO Interrupt implementiert werden kann ist das aber auch nicht tragisch. Für Interrupts gibt es prinzipiell zwei Möglichkeiten wenn man das mal aus der HighLevel Ebene von der wir kommen betrachtet. Die Erste ist: Die Hardware merkt, der Pin Zustand hat sich geändert und unterbricht des Datenfluss der CPU und springt dafür an eine hinterlegte Interrupt Addresse. Die Zweite ist: Naja dein Betriebssystem tut so als ob es ein Hardwareinterrupt ist, nimmt dir aber nur das Polling ab. Ich vermute stark dass die zweite Variante beim Raspberry verwendet ist (Ohne Garantie). Allein aus Sicherheitsgründen als auch dass die Implementierung einfacher ist.

    Ob jetzt aber das Betriebssystem für dich Pollt oder du selber (Was WiringPi macht) ist letztendlich egal (auch mit Einschränkungen - weil das Betriebssystem kann das unter Umständen besser. Deshalb meine Empfehlung: Erfinde das Rad nicht neu und verwende WiringPi dafür.

    Um dein Vorgehen aber auch noch zu diskutieren. Zum einen solltest du wissen, das Dateisystem unter /proc (wo man hintschreibt um die GPIOs zu steuern) ist nur ein virtuelles Filesystem. D.h. eigentlich wird im Hintergrund ein Syscall des Kernels aufgerufen und irgendwas gemacht. Das gleiche gilt auch fürs Lesen. Da müsste man sowie so erst mal Recherchieren ob man das überhaupt mit den normalen Methoden die es gibt um eine Änderungen des FIles mitzubekommen funktioniert (Mein Tipp wäre ja).

    Bezüglich deines Filedescriptors: Mein Vorschlag wäre: Nimm direkt die C API (also open()). Das wäre zumindest der schöne weg.
    Wenn du unbedingt fstream verwenden willst ist vermutlich das hier deine Rettung: http://www.cpptips.com/fstream

    Ich würde dabei auch darauf achten, dass ich für C++11 und nicht C++98 kompiliere.


    TLDR Nimm WiringPi und leb damit dass es dort in einem Thread gepollt wird. Ansonsten -> Nimm die C Api

    EDIT. Zum Thema: Die Macher des Standards halten etwas nicht für wichtig. Doch das tun sie, aber sie achten noch wesentlich mehr darauf dass es Plattform übergreifend funktioniert
    EDIT2: Wenn ich mir WiringPi noch mal anschaue: Vllt pollen die noch nicht mal sondern verwenden den System interrupt
    EDIT3: Schau dir eventuell auch die filesystem Erweiterung aus C++17 an: http://en.cppreference.com/w/cpp/experimental/fs


    Geändert von shedepe (15.01.2018 um 11:44 Uhr)

  5. #5
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    10.04.2005
    Ort
    Bad Aibling
    Beiträge
    212
    WiringPi ist meines Wissens C und eher weniger C++ auch wenn C vollständiger Sprachbestandteil von C++ ist.

    Das Rad neu erfinden in dem Sinn würde ich nur wenn ich das in C und Funktionsbasiert machen würde wie eben WiringPi es macht.

    Ob man aus dem User Space oder Kernel Space pollt ... der Unterschied könnte nicht größer sein. Wenn stimmt was geschrieben steht ist epoll die schnellste Variante und eine Kernel Schnittstelle. Das ich es jetzt anders zu machen versuche ist nicht unbedingt Performance mein erstes Ziel. Sondern nicht Funktions- sondern Objektorientier programmieren die Klassen leicht anwendbar zu machen und Fehlertoleranz, Fehleranalyse und Fehlerhandling besser zu machen.

    Über das proc fs die GPIO zu konfigurieren und zu benutzen ist nicht die schnellste Version aber aus Kernel sicht vollkommen in Ordnung. Ein Unix Grundsatz wenn nicht vielleicht sogar einer der wichtigsten alles ist eine Datei und genau auf diese weiße anzusprechen. Memory Mapped IO wäre die schnellste Version ... auch wieder wenn es stimmt was geschrieben steht. Ich habe es bisher nicht ausprobiert. Man spart sich hier den Filesystem Overhead.

    "Das wäre zumindest der schöne weg." => Das wäre der übliche Weg ... darauf können wir uns einigen.

    Compiler Option c++11 benutze ich im Moment.

    Von der Architektur her sehe ich nicht wirklich einen Unterschied zwischen der C API und WireingPi.

    http://www.cpptips.com/fstream Das ist das gleiche wie der erste Vorschlag vom schorsch_76.
    Wie bereits oben geschrieben funktioniert das bei mir nicht. Soweit mir bekannt haben die libc++ Entwickler alles nicht Standardkonforme entfernt was eigentlich sehr löblich ist.

    Zum Standard muss ich sagen ich bin mir zwar nicht ganz sicher aber relativ ... jedes Moderne Betriebsystem unterstützt solche Sachen wie poll auf die eine oder andere Art. Das glaube ich ist nicht der Grund warum es nicht vorhanden ist. Den Streams konnte man vor c++11 nur char* als Dateinamen übergeben ich hatte nie verstanden warum nicht auch einen std::string. Kaum wartet man einige Jahre und schon gibt es c++11 und man darf auch std::string übergeben ...

    Ja stimmt das mit dem filesystem aus c++17 sollte ich mir anschauen. Wollte ich auch schon aber immer wieder vergessen ...

  6. #6
    HaWe
    Gast
    soweit ich weiß, ist Linux (samt Kernel-Funktionen) in C geschrieben, nicht in C++, und der kernel besitzt ja die GPIOs - aber ich bin da absolut kein Fachmann.
    Wenn es dir nur darum geht, im Userspace auf GPIOs zuzugreifen, würde ich shedepe in jedem Falle Recht geben, dass das mit wiringPi sehr einfach und failsafe möglich ist.
    Wenn du aber schnellere Funktionen, die direkt den kernel nutzen, verwenden möchtest, wäre auch pigpio eine sehr gute Quelle, denn sie sind großenteils noch deutlich schneller als die von wiringPi.

    Ich selber verwende pigpio nicht, mir langt die wiringPi Performance, aber wenn du im RaspberryPi.org Forum nachfragst,
    https://www.raspberrypi.org/forums/v...832e3a42a7309e
    wirst du sicher sehr schnell sehr professionelle Hilfe bekommen: denn hier sind auch die Original-Autoren der beiden Libs (Henderson, Joan) sowie Mitarbeiter und Entwickler des Pis präsent und werden dir möglicherweise direkt antworten.

  7. #7
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    10.04.2005
    Ort
    Bad Aibling
    Beiträge
    212
    Oh das neue Forum ist schon zäh in der Benutzung. Angehängte Dateien darf ich nun scheinbar nicht mehr lesen ... und die Benachrichtigung über neue Beiträge ging auch nicht mehr.
    <edit>Das alte Forum gibt es ja noch da darf ich auch die Datei herunterladen ... </edit>

    Ich habe jetzt mal meine alte Klasse aufgeteilt. In die I2C Kommunikation und die Implementierung für die spezielle I2C Hardware wie Sensoren, Porterweiterungen, Wandler, usw.

    https://git.hts-software.de/cgit.cgi...a-Api/tree/I2c

    Sehr weit bin ich noch nicht gekommen ich hatte mit dem Gentoo Update auf dem Raspberry das Problem das er immer während dem Update abstürzte. Das lag an einer nicht ganz Stabilen Stromversorgung. Irgendwie das Netzteil kaputt gegangen.

    Was ich nicht wirklich verstehe ist warum man neue Projekte wie wiringPi mit total veralteter Software Architektur überhaupt anfängt. Die Software Branche Programmiert noch wie vor 30 Jahren und Wundert sich das nichts vorangeht. Wegen den Ports noch also meine Pis haben unter Linux immer die gleichen Nummern. Nur zwischen verschiedenen Platinen weicht das ab. Also z.B. Gnublin und Raspi was aber normal ist un kaum zu verhindern.
    Geändert von alexander_ro (18.11.2018 um 12:12 Uhr)

Ähnliche Themen

  1. Benötige Hilfe zu AT32U3C und GPIO
    Von xrzr im Forum AVR Hardwarethemen
    Antworten: 1
    Letzter Beitrag: 10.11.2015, 19:54
  2. Respberry Pi GPIO mit C++ und QT
    Von Basti1204 im Forum Raspberry Pi
    Antworten: 0
    Letzter Beitrag: 06.03.2013, 00:01
  3. [ERLEDIGT] Raspberry Pi GPIO
    Von Kampi im Forum Raspberry Pi
    Antworten: 4
    Letzter Beitrag: 04.11.2012, 23:45
  4. GPIO-Register Ansprechen
    Von kmrish im Forum Microcontroller allgemeine Fragen/Andere Microcontroller
    Antworten: 7
    Letzter Beitrag: 14.07.2011, 10:45
  5. schmitt-trigger an interrupt
    Von Bluesmash im Forum Sensoren / Sensorik
    Antworten: 2
    Letzter Beitrag: 19.06.2005, 23:46

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

LiTime Speicher und Akkus