PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : UART Interrupt in C möglich?



dremler
20.05.2013, 23:49
Kann ich beim RasPi irgendwie UART Interrupts auslösen und nutzen? Ich möchte das Ganze in einem C Programm nutzen und Polling umgehen, also nicht ständig in der TTY Datei rumlesen müssen.


Ich konnte nix finden:(

Kampi
20.05.2013, 23:57
Ich glaube das geht nicht (zumindest ist es nicht so einfach wenn es gehen sollte...).
Wollte den selber mal nutzen, aber am Polling kommst du nicht vorbei :(

dremler
21.05.2013, 09:53
Hm, das ist schade, weil unsauber:(

Nächste Frage (konnte es selbst noch nicht testen): Wenn ich eine Zeichenkette an das RasPi sende, z. B. "ABC", wird das dann "Zeichen für Zeichen" in die "Empfangsdatei" geschrieben, oder mit einem mal? Also sitzt davor noch ein Buffer oder lese ich im ungünstigsten Falle "AB" aus, weil der Empfang noch nicht fertig war?

Kampi
21.05.2013, 10:19
Es wird Zeichen für Zeichen empfangen.
Du musst also ein Programm schreiben, welches jedes Zeichen einließt, in einem String speichert und bei einem bestimmten Zeichen (z.B. CR) den String überträgt.

dremler
21.05.2013, 10:36
Ach sowas doofes, naja wird wohl ein Ringpuffer werden:)

Kampi
21.05.2013, 10:52
Hey,

also ich habe es mittlerweile so gelöst, dass ein Programm im Hintergrund läuft und alles was empfangen wird in eine Datei schreibt (quasi der selbe Ansatz wie bei Peterfidos Internetradio).

dremler
21.05.2013, 11:00
Interrupts mit Timern wird es dann in der RasPi C Programmierung auch nicht geben oder? Bleibt mir nur die Möglichkeit, alles zyklisch in der Hauptschleife aufzurufen?

Klebwax
21.05.2013, 11:16
Nächste Frage (konnte es selbst noch nicht testen): Wenn ich eine Zeichenkette an das RasPi sende, z. B. "ABC", wird das dann "Zeichen für Zeichen" in die "Empfangsdatei" geschrieben, oder mit einem mal? Also sitzt davor noch ein Buffer oder lese ich im ungünstigsten Falle "AB" aus, weil der Empfang noch nicht fertig war?

Das kommt drauf an, wie du das File behandelst. In Unix gibt es zwei Familien von Filefunktionen, gepuffert und ungepuffert. Schau dir mal die Filefunktionen, die mit f beginnen, wie fopen(), fgets() .. an.


also ich habe es mittlerweile so gelöst, dass ein Programm im Hintergrund läuft und alles was empfangen wird in eine Datei schreibt

Damit hast du also den vorhandenen Mechanismus des bufferd-IO neu erfunden. Wobei ich den Sinn nicht so recht verstehe, jetzt pollst du statt einem Device einen File.

Das UART selbst läuft mit Interrupt und blockiert mit Sicherheit nicht, das geht bei einem Multiuser/Multitasking System garnicht. Die Interrupte landen aber im Kernel. An diesen darf ein Userprozess auch nicht drehen, er könnte ja sonst das Gesamtsystem blockieren. Das was einem Interrupt im Usermode noch am ähnlichsten ist, ist ein Signal. Mache Treiber können ein Signal erzeugen, wenn sich beim IO etwas ändert, muß man mal nachlesen ob der tty-Treiber das macht.

Wenn man in Unix auf Input wartet, nutzt man gerne den select() Systemcall. Zusammen mit der Möglichkeit, einen Timeout zu setzen, kann man so auch State-Machines programmieren.

MfG Klebwax

Kampi
21.05.2013, 12:02
Das kommt drauf an, wie du das File behandelst. In Unix gibt es zwei Familien von Filefunktionen, gepuffert und ungepuffert. Schau dir mal die Filefunktionen, die mit f beginnen, wie fopen(), fgets() .. an.



Damit hast du also den vorhandenen Mechanismus des bufferd-IO neu erfunden. Wobei ich den Sinn nicht so recht verstehe, jetzt pollst du statt einem Device einen File.

Das UART selbst läuft mit Interrupt und blockiert mit Sicherheit nicht, das geht bei einem Multiuser/Multitasking System garnicht. Die Interrupte landen aber im Kernel. An diesen darf ein Userprozess auch nicht drehen, er könnte ja sonst das Gesamtsystem blockieren. Das was einem Interrupt im Usermode noch am ähnlichsten ist, ist ein Signal. Mache Treiber können ein Signal erzeugen, wenn sich beim IO etwas ändert, muß man mal nachlesen ob der tty-Treiber das macht.

Wenn man in Unix auf Input wartet, nutzt man gerne den select() Systemcall. Zusammen mit der Möglichkeit, einen Timeout zu setzen, kann man so auch State-Machines programmieren.

MfG Klebwax

Ah danke für die Erklärung.
Der Grund, warum ich das in eine Datei schreibe ist der, weil mehrere Ressourcen auf den Empfangenen Text zugreifen müssen.
Aber das der UART bereits über Interrupt läuft wusste ich nicht.
Hab es bisher so vermutet, dass wenn ich z.B. in Python mit dem "serial.read()" arbeite das er auch den UART einfach nur pollt.

dremler
26.06.2013, 13:51
Aus aktuellem Anlass nochmal die Frage: Gibt es in C auf dem Raspberry Pi die Möglichkeit, Timer Interrupts zu nutzen? Ich möchte nur sehr ungern Delay Schleifen nutzen...

Max Web
26.06.2013, 15:25
Hallo,

das wird so vermutlich auch nicht gehen. Allerdings gibt es unter sys/time.h einige sehr nützliche Tools zum Thema Timer.
Außerdem bekommst Du drei Timer, die Du mit getitimer() und setitimer() kontrollieren kannst. Diese lösen verschiedene Signale aus, auf die Du reagieren kannst.
Das ist zwar nicht ganz so toll wie das direkte Benutzen von Interrupts, aber sicherlich ein interessanter Ansatz.

schorsch_76
27.06.2013, 11:38
Das ist normale C Programmierung. Timer werden in der Regel über separate Threads gelöst welche diese Zeit eben im sleep sind. Persönlich mache ich sowas mit boost (http://boost.org) in C++, aber unter C geht das prinzipiell genauso. Direkte Interrupts wie du sie auf den AVRs kennst werden in Linux auf PCs anderst gelöst.... eben mit Threads. Siehe dazu auch [1] [2]

Ereignisgesteuert auf UART zu reagieren geht auch mittels select [5] . Unter C++ würde ich das mit boost::asio [3] [4] lösen
Gruß
Georg

[1] http://en.wikipedia.org/wiki/POSIX_Threads
[2] https://computing.llnl.gov/tutorials/pthreads/
[3] http://www.boost.org/doc/libs/1_53_0/doc/html/boost_asio.html
[4] http://www.boost.org/doc/libs/1_53_0/doc/html/boost_asio/reference/serial_port.html
[5] http://stackoverflow.com/questions/11986998/select-does-not-seem-to-work-on-tty

TheDarkRose
27.06.2013, 14:10
C Programmierung am Pi ist normale Linuxprogrammierung -> ergo ganz normale C/C++ Programme möglich, Schnittstellen können einfach wie Dateien gelesen werden, ohne Probleme. Interrupts gibt es generell nicht, außer man programmiert ein Kernelmodul. Dafür gibt es aber Threads und Prozesse.