Forum: Mikrocontroller und Digitale Elektronik Interrupt am PC auslösen


von Daniel (Gast)


Lesenswert?

Hallo,

ich hätte eine grundsätzliche Frage wie ich bei einem Linux Rechner am 
besten eine Aktion aufgrund einer Veränderung am µC auslöse.
Beispiel:
Atmega8 prüft ob ein Schalter etc. gedrückt wird Kommando an den 
Rechner   Rechner führt Skript xy aus
Ich weis das es über RS232 möglich ist, ich denke mir nur das es etwas 
umständlich ist ständig den COM Anschluss zu überwachen (auch cpu 
lastig) oder liege ich da falsch?
Wie würdet ihr so etwas realisieren?  Eventuell über USB? Was wäre die 
eleganteste Methode?

Grüße Daniel

von Achim M. (minifloat)


Lesenswert?

Daniel schrieb:
> Ich weis das es über RS232 möglich ist, ich denke mir nur das es etwas
> umständlich ist ständig den COM Anschluss zu überwachen (auch cpu
> lastig) oder liege ich da falsch?

Sinn eines Interrupts ist es doch unter anderem, Polling zu vermeiden.
Jedesmal wenn ein neues Byte im Empfangspuffer einer COM-Schnittstelle 
liegt, kommt ein Interrupt, dass da neue Daten liegen. Die werden dann 
in einen Empfangspuffer kopiert, bis du sie abholst.
Oder du schaust, ob du eine USB-Impelmentierung in Software findest( 
http://www.obdev.at ), damit kann dein Mega8 über USB einen Interrupt 
auslösen. Damit kommen die benötigten Daten/PArameter/Sonstwas auch 
gleich zu deiner Applikation am Rechner.

Bei den heute verfügbaren Rechenleistungen ist es denk ich mal nicht so 
schlimm, alle 100-200ms mal "vorbeizusehen", ob da "was neues da" ist.
Brauchst du Echtzeit? Welche Verzögerungszeiten sind noch tolerierbar?

mfg mf

von Jan (Gast)


Lesenswert?

Daruf zu warten, ob am seriellen Port eines PCs etwas ankommt ist in der 
Regel nicht CPU-lastig. Dort wird auch nur ein Interrupt bei Empfang 
ausgelöst. Die Frage ist wie Betriebssystem und Anwendung arbeiten.

von Klaus T. (gauchi)


Lesenswert?

Um zu prüfen, ob an einer Schnittstelle was neues angekommen ist, gibt 
es select(2). Es ist vermutlich nicht ganz kostenlos, aber es wird nicht 
viel Rechenleistung verheizen.

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Daniel schrieb:

> Wie würdet ihr so etwas realisieren?  Eventuell über USB? Was wäre die
> eleganteste Methode?

Eher noch RS232, weil es da auf der Schnittstelle das Ring Indicator 
Signal gibt und das kann bei entsprechender Unterstützung auf dem PC 
durchaus als Unterbrechungsabforderung dienen.

USB ist nur scheinbar eleganter. Intern pollt (fragt) der PC laufend die 
angeschlossenen USB Geräte ab. Die melden von sich aus erstmal nix.

von micha (Gast)


Lesenswert?

Ich bevorzuge dafür den Parallelport.
Hab das mit einem kleinen Kernelmodul gelöst. Das Kernelmodul stellt die 
Syscalls read und write zur Vefügung. Im Kernelmodul wird die 
Readfunktion nun so lange blockiert bis der Interrupt aufgetreten ist.

Das Programm im Userspace versucht nun vom dem Gerät zu lesen. Es bleibt 
so lange an der Zeile mit dem read stehen, bis der Interrupt eingetreten 
ist. Während der Wartezeit wird das Programm vom Scheduler in die 
Warteschleife gelegt.

Nachdem das Programm über das read hinweg ist, sagt es kurz mit write im 
Kernelmodul bescheid. Das Kernelmodul blockiert nun wieder die 
read-Funktion und wartet auf dem nächsten Interrupt.

Ich hatte dabei Probleme mit dem parport Modul. Dieses darf während des 
Bootens nich geladen werden, ein späteres Entladen hat nicht geholfen. 
Bei Debian und Co gibt es dafür modconf. Bei Suse hab ich keine Ahnung. 
Da hab ich schnell nen Kernel ohne parport Modul gebaut.

von Daniel (Gast)


Lesenswert?

Danke für die schnelle Antwort, vielleicht war „Interrupt“ von mir 
falsch beschrieben, die Zeit ist mir eigentlich nicht wichtig, es können 
auch Sekunden vergehen bis etwas passiert, was mit wichtiger ist, wäre 
eine CPU schonende Variante und wenn möglich ohne COM Port, da ich auf 
diesem Board nur einen habe.

Grüße Daniel

von Achim M. (minifloat)


Lesenswert?

Daniel schrieb:
> da ich auf
> diesem Board nur einen habe.

Sicher? halte mal nach einem 10pin Header Ausschau. Meist gibt es zwei 
COM-Ports.

Manchmal gibt es einen Header für IRDA, der auch als serielle 
Schnittstelle brauchbar ist. Vorteil hierbei: Man spart sich den 
Pegelwandler.

Ganz dreckige Methode: Den SM-Bus anzapfen. Ist im Grunde nichts anderes 
als I2C. Damit werden z.B. die Timing-Parameter von RAM-Riegeln 
festgestellt. Der Ram-Riegel hat dazu in einer Ecke ein I2C-EProm. Dein 
Mega arbeitet dann als I2C Client.
siehe auch: http://www.maxim-ic.com/app-notes/index.mvp/id/476

mfg mf

PS: Ganz dreckige, gemeine Methode: Floppy-Port mißbrauchen. Dein Mega 
emuliert dann eine Floppy-Disk.

von micha (Gast)


Lesenswert?

Daniel schrieb:
> Danke für die schnelle Antwort, vielleicht war „Interrupt“ von mir
> falsch beschrieben, die Zeit ist mir eigentlich nicht wichtig, es können
> auch Sekunden vergehen bis etwas passiert, was mit wichtiger ist, wäre
> eine CPU schonende Variante und wenn möglich ohne COM Port, da ich auf
> diesem Board nur einen habe.

Der Parallelport braucht an Pin 10 lediglich eine steigende Flanke und 
schon wird im PC der Interrupt ausgelöst. Da kann man den Controller 
direkt dranlöten (bei TTL-Pegel).

Die oben beschriebene Lösung verbraucht keine zusätzliche Rechenzeit 
(ausser es kommt auf einstellige µs Reaktionszeit an). Blockierte 
Prozesse werden vom Scheduler in eine Warteliste gesteckt und dort erst 
wieder rausgeholt, wenn die Blockade vorbei ist.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.