Lesen von seriellen Daten ohne hohe CPU-Verwendung

Ich soll das Lesen von Nachrichten, gesendet von einem Arduino über den FTDI (serial) Schnittstelle in einem einfachen C-oder C++ - Programm unter Linux. Der Arduino sendet eine von zwei Zeichen, 'header', einem Kommando-byte, gefolgt von ein paar bytes von Daten abhängig vom Befehl.

Mein Erster Versuch war einfach die Umfrage die Daten mit open() und read (), aber dies führt dazu, dass etwa 12% CPU-Nutzung. Dies scheint nicht der geeignete Weg, Dinge zu tun.

Zweiten lese ich bis auf libevent auf implementiert eine event-Schleife löst ein Ereignis aus, wenn Daten auf dem file-Deskriptor. Meine cpu-Auslastung war weiter nichts, konnte ich aber nicht Lesen Sie die gesamte Nachricht, bevor ein anderes Ereignis genannt wurde. Die Ereignisse nicht ausgelöst, wenn eine komplette Nachricht empfangen wurde, aber sobald alle/einige Daten auf den file-descriptor. Es suchen mehr, es war offensichtlich, dass dies nicht ganz so, wie ich es wollte. Dies ist mein event code: http://pastebin.com/b9W0jHjb

Dritte, das ich umgesetzt habe eine gepufferte Veranstaltung mit libevent. Es schien zu funktionieren etwas besser, aber immer noch geteilt, einige der Nachrichten auf. Mein event code: http://pastebin.com/PQNriUCN

Vierten ausgegeben ich libevent und ausprobiert, Boost ASIO-Klasse. Das Beispiel, das ich hatte war http://www.webalice.it/fede.tft/serial_port/serial_port.html. Es schien zu funktionieren gut, aber die "Ereignis-Schleife" eine "while(1) {}", die verursacht die CPU-Auslastung wieder nach oben gehen. Die Schleife prüft nur für Fehler-status beim seriellen Lesen passiert bei einem callback auf einen anderen thread. Ich habe ein usleep(1) die while-Schleife und es brachte meine CPU-Auslastung auf 2%, das ist ok, aber scheint noch immer schwer für solch ein Licht-Programm.

Meisten Beispiele von libevent und auch die zugrunde liegenden epoll die Verwendung von TCP-sockets, die nicht scheinen, Verhalten sich ganz die gleiche wie die serielle Schnittstelle.

Also meine wichtigste Frage ist: was ist eine gute leichte Art und Weise das Lesen von Nachrichten aus einem seriellen Anschluss, ohne schwere polling? (in linux mit C oder C++)

Waren Sie mit non-blocking read()? Tut Sperrung read() nicht für Sie arbeiten?
Der Aufruf read ist ein blockierender Aufruf. Können Sie eigentlich beweisen, dass der Aufruf zu read war verantwortlich für 12% CPU-Nutzung, oder waren Sie nur auf der Suche auf ein system-monitor? Wenn es richtig ist, die CPU-intensiv sind, versuchen Sie Sie durch gprof um zu sehen, wo der Engpass ist.
Normalerweise verwende ich die Qt-Bibliotheken für die meisten Dinge, aber es schien ein wenig schwer für diese kleine Aufgabe. Plus ich Liebe das lernen über die "untere" Ebene der API. Mein Erster Versuch verwendet, eine blockierende read (), während meine libevent versucht, benutzt eine nicht-blockierende read(). Ich werde prüfen, in gprof und mit einem einfachen blockierende read () - morgen und Bericht meine Erkenntnisse zurück.
Unter Windows können Sie die low-level-FTDI-SDK-Bibliothek unter Umgehung der system-Treiber für seriellen Anschluss insgesamt. Nicht sicher, wenn vorhanden, auf linux, aber wenn das so ist dann könnte man probieren.

InformationsquelleAutor darkadept | 2011-08-12

Schreibe einen Kommentar