mikrocontroller.net

Forum: PC-Programmierung Linux Interruphandler in "normalem" Programm


Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich hätte eine frage an die Linux Spezis.
Kann ich in normalen (main) Programmen einen Interrupthandler
implementieren? Speziell gehet es um die serielle Schnitstelle(ttyS0).
Ich google schon einige Zeit kann aber nichts finden, bzw. nur wie es
in Kernelmodulen funktioniert.
Ich polle im moment ständig mit read nach einem neuen Zeichen, da wäre
es doch viel sinnvoller wenn ich das ganze mit einem Inerrupt lösen
könnte?

gruss Thomas

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Kann ich in normalen (main) Programmen einen Interrupthandler
> implementieren?

Nein. Interrupts gibt's nur im Kernel. Aber vielleicht reicht dir ein
Signalhandler aus.

> Ich polle im moment ständig mit read nach einem neuen Zeichen, da
> wäre  es doch viel sinnvoller wenn ich das ganze mit einem
> Inerrupt lösen könnte?

Eigentlich sollte read blockieren, bis ein neues Zeichen kommt.

Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>> Kann ich in normalen (main) Programmen einen Interrupthandler
>> implementieren?
>
>Nein. Interrupts gibt's nur im Kernel. Aber vielleicht reicht dir
ein
>Signalhandler aus.

Danke, ich denke das geht, habe ich gar nicht dran gedacht. ;-)

>> Ich polle im moment ständig mit read nach einem neuen Zeichen, da
>> wäre  es doch viel sinnvoller wenn ich das ganze mit einem
>> Inerrupt lösen könnte?
>
>Eigentlich sollte read blockieren, bis ein neues Zeichen kommt.

Würde es auch, aber ich habe es expliziet auf non blocking gesetzt, da
das Programm auch noch was anderes zu tun hat.

Danke, gruss Thomas

Autor: Tobi H. (tobi-) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dann solltest du das read in einen Thread packen. Ist die sauberste und
effizienteste Methode

Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
das habe ich zuerst auch gedacht, als ich gemerkt habe dass das mit dem
Interrupt nicht funktioniert, ich habe es jetzt aber mit einem
Sighandler gelöst, dieser wird ausgeführt sobald ein Zeichen an das
ttyS0 geschickt wird, dort kann ich dann einlesen biss kein zeichen
mehr im puffer ist, bzw. gesendet wird.

gruss Thomas

Autor: Martin #### (martin-)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Thomas
Kannst du mir kurz beschreiben wie du es jetzt gelöst hast, oder wenns
geht den Code posten ?
Mich interesiert einfach wie du es gelöst hast, weil ich hätte es nicht
lösen können.

Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Kannst du mir kurz beschreiben wie du es jetzt gelöst hast, oder
wenns
> geht den Code posten ?

Habe den Code angehängt, erklärt sich selbst.
Es fehlen Zeilennummern da ich die Sachen rausgelöscht habe die nichts
mit der schnittstelle u tun haben.

jetzt habe ich aber ein weiters Problem. Ich verwende GTK als
Graphische Oberfläche für mein Programm. allerdings sobald der
Sighandler aufgerufen wurde Springt Reagiert das Programm nicht mehr.
Wie Kann ich die Unix Sighandler und die GTK sighandler zur
zusammenarbeit uüberreden?

gruss Thomas

Autor: Martin #### (martin-)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>>Habe den Code angehängt
Danke Thomas aber da ist wohl bei dem Anhängen was schief gelaufen

>>Ich verwende GTK
Ach so. Wenn du GTK verwendest dann gibt es einen, wie ich finde viel
besseren Weg das zu lösen: GIOChannel
http://developer.gnome.org/doc/API/glib/glib-io-ch...
Der Link ist für GTK 1.2 aber in GTK 2.x hat sich nur in so fern was
geändert das neue funktionen dazugekommen sind.

Hier ein Beispiel wie man es vervendet:
/*hier ganz normal Schnittstele öffnen und ggf. einstellen*/
int fd = open(.....)

/*GIOChannel einrichten*/
GIOChannel *channel;
channel =  g_io_channel_unix_new(fd); /*fertig*/

/*jetzt mit g_io_add_watch bestimmen auf welche Ereignisse bei fd
reagiert werden soll*/
/*z.B falls Beits zum lesen vorhanden sind zu entsprechenden Funktion
springen incomming_data(..)*/
g_io_add_watch(channel, G_IO_IN, incomming_data, user_data);

/*In der Funktion incomming_data dann die Daten lesen*/
int size;/*für Anzahl der gelesen Bytes*/
char buffer[32]; /*für Daten*/
g_io_channel_read(source,buffer,32,&size)


Ich kann die auch kompletes Programm posten, das diese Methode
verwendet (ein simples Terminal-Programm).

Autor: Thomas (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
hallo, danke das wäre super.
Das anhängen hat irgenwie nicht geklappt ich veruche es nochmal.
Das Programm wurde zuerst ohne gtk geschrieben, da ich jetzt aber eine
GUI haben will, habe ich gtk dazugenommen leider mit dem beschriebenen
problem.
Wäre super wenn du mir das progamm anhängen könntest.

gruss Thomas

Autor: Martin #### (martin-)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Ok im Anhang ist ist der Source-Code.
Interessant für dich sind die Funktionen in callbacks.c:
on_oeffnen_clicked - hier wird ein GIOChannel erstellt
on_schliessen_clicked - hier wird es wieder freigegeben

Und ich main.c:
incomming_data - Diese Funktion ist an das GIOChannel gebunden und wird
aufgeruffen wenn Daten zum Lesen vorhanden sind.

Ich hoffe, dass dieses Beispiel verständlich ist.

Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

Ich habe ein Problem mit den IO-Channels, sobald ich

channel =  g_io_channel_unix_new(fd);

aufrufe bekommen ich follgende Fehlermeldung, und das Programm wird mit
einem Speicherzugriffsfehler abgebrochen.

(process:1395): GLib-GObject-CRITICAL **: gtype.c:2254: initialization
assertion failed, use IA__g_type_init() prior to this function

kann jemad was damit anfangen, konne nichts finden dazu.

gruss Thomas

Autor: Martin #### (martin-)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja zu diesem Fehler findet man nicht wirklich was hilfreiches, und ich
hatte diesen Fehler noch nicht.
Gegenfrage : In Wenn du mein Programm compilierts und ausführst kommt
der Fehler auch ?
Wenn ja, das dann liegt das Problem in der Konfiguration von Gtk, dann
kann ich dir nicht helfen.
Anderfalls liegt das am Quellcode (Vorausgesetzt du verwendest auch gtk
1.2, aber "GObject" das ist wohl gtk 2.0)

Autor: Martin #### (martin-)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielleicht hilft es vorher g_type_init() aufzurufen.

Autor: Feadi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mit select ist das so eine Sache, wenn man nebenher noch eine Event-Loop
eines GUI-Toolkits laufen hat. Normalerweise kommt man, wenn man nicht
grad auf Multithreading ausweichen will, nicht drumrum die Funktionen
des Toolkits zu nutzen, um auf die Daten zu warten.

Autor: Feadi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Rolf:

Ich habe übersehen dass GTK ein eigenen main-Loop hat. Aber hier ist
ein Workaround:

http://www.gtk.org/tutorial/x1791.html

Gruß, Feadi

Autor: Martin #### (martin-)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Thomas
Konntest du das mit initialization assertion failed lösen.
Hat aufrufen von g_type_init was gebracht ?
Ich würde es gerne für zukunft wissen ob es was bringt oder man kann
sich sparen das jemandem vorzuschlagen.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.