Software Interrupt Atmega8

Gast #3338630
Lesenswert?

Clemens Trunner schrieb:

> Wie im Betreff schon steht würde ich gerne wissen ob es möglich ist mit
> dem Atmega8 einen Software Interrupt an INT0 zu realisiern

Natürlich.

> und wenn ja
> dann wie mach ich da in C?

Du tust es einfach.

Allerdings: Der Sinn des Unterfangens ist reichlich nebulös. Ein 
Interrupt ist letztlich nichts anderes, als eine Funktion, die durch 
äußere Ereignisse nebenläufig zu beliebiger Zeit aufgerufen werden kann. 
Wenn er aber von der Software selber ausgelöst wird und nicht durch 
äußere Ereignisse, dann wird er einigermaßen sinnlos, denn statt der 
Auslösung des Interrupts könnte die Software ja auch gleich den 
Interrupthandler direkt aufrufen. Wozu also den Interrupt-Overhead in 
Kauf nehmen? Das ist weitgehend sinnlos.

Die einzige Ausnahme sind eigentlich Debugger-Funktionalitäten. Die sind 
darauf angewiesen, auch an die Stelle der kleinstmöglichen Instruktion 
zu passen. Nur hier ergibt ein solcher "Software-Interrupt" einen Sinn, 
sonst nicht.
Gast #3339057
Lesenswert?

Die bisherigen Antworten kamen am Nachmittag, da haben wohl
noch alle geschlafen, oder waren noch im Schlaumeier-Mode.

Schaut doch einfach in's Datenblatt!

Gleich zu Anfang im Kapitel "External Interrupts" steht:

> The external interrupts are triggered by the INT0, and INT1 pins.
> Observe that, if enabled, the interrupts will trigger even if the
> INT0..1 pins are configured as outputs. This feature provides a
> way of generating a software interrupt.

Wie macht man das in C?
Da ich nur in ASM arbeite, kann ich jetzt nicht den C-Code
liefern - ansonsten machst du es ...
- So, wie du den INT0 als HW-Interrupt initialisierst.
- Dann setzt du den Port D2 als Ausgang, und schaltest den
  genau so, wie ein externes Signal den INT0 auslösen würde.
#3339090
Lesenswert?

Bernie schrieb:
> Die bisherigen Antworten kamen am Nachmittag, da haben wohl
> noch alle geschlafen, oder waren noch im Schlaumeier-Mode.
>
> Schaut doch einfach in's Datenblatt!
>
> Gleich zu Anfang im Kapitel "External Interrupts" steht:
>
>> The external interrupts are triggered by the INT0, and INT1 pins.
>> Observe that, if enabled, the interrupts will trigger even if the
>> INT0..1 pins are configured as outputs. This feature provides a
>> way of generating a software interrupt.

Erhebt sich immer noch die Frage: Wozu, wenn man anstatt den Interrupt 
auszulösen, die Funktion auch direkt aufrufen kann, wenn es notwendig 
ist?
Gast #3339101
Lesenswert?

Karl Heinz Buchegger schrieb:

> Erhebt sich immer noch die Frage: Wozu, wenn man anstatt den
> Interrupt auszulösen, die Funktion auch direkt aufrufen kann,
> wenn es notwendig ist?

Wenn der SW-Interrupt laut Hersteller problemlos machbar ist,
muss man ihn doch nicht als "Sowas tut man nicht!"
verheimlichen...

Theoretisch könnte man ihn vielleicht zur Fehlerbehandlung
nutzen.

Allerdings hätte ICH keine Ahnung, wie sich bei einem Direkt-
Aufruf das "reti" auswirkt. - Wäre für mich eher die "Finger-
weg!" Variante...
Gast #3339403
Lesenswert?

>Wozu, wenn man anstatt den Interrupt auszulösen, die Funktion auch direkt
>aufrufen kann, wenn es notwendig ist?

Weil beides im Detail verschiedene Aktionen bewirkt und es Situationen 
gibt, wo es auf diese Unterschiede ankommt.

Beim Aufrufen der Funktion mit rcall wird:
    - simultan die Returnadresse auf dem Stack abgelegt und
      der PC (program counter) mit der Adresse der Funktion geladen,
      was den Ansprung der Funktion bewirkt.

Beim Auslösen des Interrupts wird:
     - erstmal nur das zugehörige INTF-Flag gesetzt und
sobald die Interrupts global enabled sind (i-Flag = 0):
     - simultan das i-Flag gesetzt (*),
       die Returnadresse auf dem Stack abgelegt und
       der PC mit der Interrupt-Einsprungadresse geladen.

Der wesentliche Unterschied ist der mit (*) markierte. Durch das 
automatische Setzen des i-Flags wird der Code in der ISR geschützt, d. 
h. nicht durch andere Interrupts unterbrechbar ausgeführt. Man kann das 
auch nicht erreichen, indem man ein rcall mit vorangesetztem sei 
macht, denn das ist nicht atomar. Ein zu diesem Zeitpunkt anstehender 
Interrupt würde die Programmausführung unerwünschterweise zwischen sei 
und rcall unterbrechen.

Die wichtigste Bedeutung von Software-Interrupts liegt in der 
Realisierung von sogenannten Exceptions oder Traps.
#3340334
Lesenswert?

Karl Heinz Buchegger schrieb:
> Erhebt sich immer noch die Frage: Wozu, wenn man anstatt den Interrupt
> auszulösen, die Funktion auch direkt aufrufen kann, wenn es notwendig
> ist?

Genau.
Einen SW-Interrupt braucht man nur, um andere Programme (OS, 
Device-Treiber) aufzurufen, ohne ihre Adresse zu kennen.
Beim AVR kann man aber nicht mehrere Programme ausführen, es gibt nur 
ein Main und daher ist jede Adresse zur Linkzeit bekannt.

Einen Portpin zu opfern, nur weil SW-Interrupt schick klingt, ist also 
Unsinn.
Gast #3340622
Lesenswert?

LostInMusic schrieb:

> Man kann das
> auch nicht erreichen, indem man ein rcall mit vorangesetztem /sei/
> macht, denn das ist nicht atomar.

Das ist doppelt falsch.

Zum einen schachlich-logisch, denn das ist wirklich kein Ersatz für eine 
Interruptauslösung, weil dafür natürlich cli und nicht sei zu verwenden 
wäre.

Und obendrein ist auch noch die Begründung falsch, daß die Folge sei, 
rcall nicht atomar wäre, sie IST es. Siehe AVR instruction set 
reference: "The instruction following SEI will be executed before any 
pending interrupts".

Und auch die korrekte Umsetzung mit cli, rcall ist atomar. Wieder Zitat 
aus derselben Quelle: "The interrupts will be immediately disabled. No 
interrupt will be executed after the CLI instruction, even if it occurs 
simultaneously with the CLI instruction."

Was bleibt also von deiner Argumentation pro Software-Int? Nichts, nur 
heiße Luft.
#3340651
Lesenswert?

Das einzige was ich praktisch sehe ist, dass ein SBI an einem 
Portregister ein 2 Clock Befehl ist (ATMega16), während für CLI + RCALL 
ein paar Clocks mehr zusammen kommen. Dafür hat man beim SBI + Interrupt 
noch die Interrupt Latenz drinnen und wird in den meisten Fällen dann 
auch noch einen Sprung vom Interruptvektor zur eigentlichen 
Funktionalität brauchen.
Bleibt noch die Programmlänge. Gut da hat der einzelne SBI die Nase 
vorn. Ist ein Programm gespickt mit derartigen immer gleichen Aufrufen, 
dann kann der SW-Interrupt helfen, ein paar Bytes einzusparen.

Aber abgesehen davon, sehe ich noch immer nicht, wozu ich einen 
SW-Interrupt bei einem Tiny oder Mega benutzen würde, bzw. welchen 
Vorteil das hätte.
#3340675
Lesenswert?

Karl Heinz Buchegger schrieb:
> Aber abgesehen davon, sehe ich noch immer nicht, wozu ich einen
> SW-Interrupt bei einem Tiny oder Mega benutzen würde, bzw. welchen
> Vorteil das hätte.

Vielleicht in einer Entwicklungsphase: Normalerweise kommt das Signal 
von der Peripherie, die nocht nicht existiert|funktioniert. Da könnte 
man per Software schon mal das Verhalten testen.

Evtl. auch als zusätzliche Quelle?
#3340685
Lesenswert?

Karl Heinz Buchegger schrieb:
> Aber abgesehen davon, sehe ich noch immer nicht, wozu ich einen
> SW-Interrupt bei einem Tiny oder Mega benutzen würde, bzw. welchen
> Vorteil das hätte.

Um ihm zum ersten mal aufzurufen. Angenommen du hast eine 
Interruptgesteuerte Ausgaberoutine in der bekommst du den ersten 
Interrupt erst dann wenn das erste Zeichen ausgegeben wurde also must du 
den ersten Ausgabeinterrupt per Software anstossen damit die 
Ausgaberoutine weitere Interrupts generieren kann.
Gast #3340720
Lesenswert?

Karl Heinz Buchegger schrieb:

> Aber abgesehen davon, sehe ich noch immer nicht, wozu ich einen
> SW-Interrupt bei einem Tiny oder Mega benutzen würde, bzw. welchen
> Vorteil das hätte.

Wie ich schon weiter oben angemerkt habe, macht das eigentlich nur für 
Debug-Geschichten einen Sinn, also eine Verwendung des SW-Int-Auslösers 
als Quasi-Breakpoint. Man könnte damit z.B. einen netzwerkfähigen 
in-circuit-Debugger basteln.
#3340759
Lesenswert?

Peter Dannegger schrieb:
> Karl Heinz Buchegger schrieb:
>> Das einzige was ich praktisch sehe ist, dass ein SBI an einem
>> Portregister ein 2 Clock Befehl ist (ATMega16), während für CLI + RCALL
>> ein paar Clocks mehr zusammen kommen.
>
> Du vergißt die Push/Pop Arie, die jeder Interrupt machen muß, die
> entfällt bei einem schlichten Funktionsaufruf weitgehend.

Ich wollte jetzt explizit das In-Assembler-Programmiert-Zugeständnis 
machen (hätte ich erwähnen sollen), bei der das dann nicht ganz so 
schlimm ist.
#3340768
Lesenswert?

Helmut Lenzen schrieb:

> Um ihm zum ersten mal aufzurufen. Angenommen du hast eine
> Interruptgesteuerte Ausgaberoutine in der bekommst du den ersten
> Interrupt erst dann wenn das erste Zeichen ausgegeben wurde also must du
> den ersten Ausgabeinterrupt per Software anstossen damit die
> Ausgaberoutine weitere Interrupts generieren kann.

Ja, ok. Ich sehe worauf du hinaus willst.

Allerdings ging es hier ja um eine spezielle Form, bei der ein externer 
Interrupt dadurch getriggert wird, in dem man den Portpin nicht extern, 
sondern per Programm umstellt, um so die Flankentriggerung und in 
weiterer Folge den zugehörigen Interrupt auszulösen.

Ganz ehrlich: Ich denke, dass das eigentlich ein Nebeneffekt ist. Die 
Hardware-Logik reagiert auf den Wechsel am Portpin und man wollte bei 
Atmel da nicht auch noch Zusatzlogik einbauen, um dann auch noch zu 
verhindern, dass diese Triggerlogik nur von aussen ausgelöst werden 
kann. Im DB wird das dann als Feature verkauft.

Ich hab ja grundsätzlich kein Problem damit. Nicht falsch verstehen. Wem 
es gefällt, der soll das machen.
Gast #3340877
Lesenswert?

Peter Dannegger schrieb:

> In Assembler findet man das Konzept der Scratchpad-Register nur selten,
> da wird oft gepusht/gepopt, bis der Arzt kommt, egal ob Interrupt oder
> Funktion.

Ich weiß ja nicht, welche Asm-Programme du als Quelle deiner Weisheiten 
benutzt, vermutlich Programme, die für Lehr- oder Anschauungszwecke 
gemacht wurden. Da macht man's natürlich "ordentlich" und kitzelt nicht 
noch den letzten Takt raus.

Bei praktischen Programmen aber natürlich sehr wohl. Allerdings wird man 
auch da i.d.R. selektiv vorgehen und nur dort optimieren, wo die 
Optimierung lohnt.

Bei einem DDS-Funktionsgenerator etwa ist mir scheißegal, wenn in den 
Routinen für die Benutzerinteraktion oder für die Initialisierung der 
Waveform möglicherweise ein paar überflüssige pushs und pops drinne 
sind. Hauptsache, die eigentliche DDS-Routine braucht eine konstante und 
möglichst geringe Anzahl von Takten. Dafür wird natürlich alles in 
Registern gehalten.
Gast #3342069
Lesenswert?

Peter Dannegger schrieb:
> Man könnte auch ganz profan ein Flagh setzen und es am Ende testen.
> Dann muß man nicht für länger alle Interrupts sperren.

"Und fuer jedes Threadbeispiel faellt
denen auch immer ein Gegenbeispiel ein, wie es ohne geht."

Wenn ihr Controller designen wuerdet, koennten sie gar nichts. Weil es 
fuer jedes Feature irgendeinen Ersatz gibt, mit dem man sich behelfen 
kann.
#3342088
Lesenswert?

Quak schrieb:
> Wenn ihr Controller designen wuerdet, koennten sie gar nichts. Weil es
> fuer jedes Feature irgendeinen Ersatz gibt, mit dem man sich behelfen
> kann.

Tja, es gibt halt noch Leute die Ihren Kopf benutzen moechten und nicht 
nur "vorgekaute" Szenarien der Chiphersteller neu verpacken.

Denn wenn man deine Einstellung ins Extreme fortfuehrt, dann hat man 
fuer alles single-purpose chips und braucht gar keine Universalmaschinen 
(sagen wir Mikrocontroller) mehr...

Hier geht es um Kreativitaet - nicht um Wirtschaftlichkeit.

MfG
#3342166
Lesenswert?

Quak schrieb:
> Wenn ihr Controller designen wuerdet, koennten sie gar nichts. Weil es
> fuer jedes Feature irgendeinen Ersatz gibt, mit dem man sich behelfen
> kann.

Hier will sich niemand behelfen, es geht einfach nur um die 
Sinnhaftigkeit.

Du weißt sicher nicht, was ein ATmega8 ist?
Für den ist ein SWI so unbrauchbar, wie für einen Kinderwagen ein 
Vergaser.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren