Forum: Mikrocontroller und Digitale Elektronik Funktionsaufruf aus naked-Routine


von AVR-Nutzer (Gast)


Lesenswert?

Hallo,

ich programmiere einen ATmega mit avr-gcc. ich möchte auf ein Interrupt 
möglichst schnell reagieren. Um den Code aber einfach zu halten, will 
ich vermeiden, die komplette Routine in Assembler zu schreiben.

Ist es sicher, aus einer "naked"-Routine einen Funktionsaufruf zu 
starten?
1
ISR( PCINT2_vect, ISR_NAKED ){
2
    PORTC = GPIOR1;
3
    isr_more_logic();
4
    reti();
5
}

von Einer K. (Gast)


Lesenswert?

AVR-Nutzer schrieb im Beitrag #4897532:
> Ist es sicher, aus einer "naked"-Routine einen Funktionsaufruf zu
> starten?
Natürlich nicht!
Zumindest "SO" nicht.

von Programmierer (Gast)


Lesenswert?

AVR-Nutzer schrieb im Beitrag #4897532:
> Ist es sicher ...

Was meinst du mit "sicher"?
Rechnest du mit Viren auf deinem ATmega? ;-)

von Stefan E. (sternst)


Lesenswert?

Schon das PORTC = GPIOR1 ist nicht "sicher", weil das nicht ohne 
Zuhilfenahme eines Registers funktioniert, welches wegen des naked ja 
nicht gesichert und wiederhergestellt wird.

von Bla (Gast)


Lesenswert?

Du kannst aus einer ISR_NAKED eine ISR aufrufen, dann sichert der 
Compiler dann die Register und du kannst beliebig Funktionen aufrufen.

Siehe dazu diesen sehr interessanten Beitrag (englisch) auf Stack 
Overflow: 
http://arduino.stackexchange.com/questions/8758/arduino-interruption-on-pin-change

Der Mensch bekommt genau das hin was du auch versuchst, schnellstmöglich 
auf ein Port-Register zuzugreifen.

von Bla (Gast)


Lesenswert?

P.S.: nicht vom “Arduino“in der URL irritieren lassen, der Autor geht 
tief in die Materie rein und schafft es durch modifizieren der 
Interrupt-Tabelle auf eine Latenz von fünf Takten zu kommen.

von Frank (Gast)


Lesenswert?

Dumme Frage, aber ist die isr_more_logic(); inline?

von AVR-Nutzer (Gast)


Lesenswert?

Hallo,

da ist mir wohl leider zu später Stunde doch ein Fehler passiert. 
Natürlich greift PORTC = GPIOR1; auf ein weiteres Register zu, dass ich 
hätte sichern müssen. Meine Frage zielte daraufhin ab, in wie weit ein 
Aufruf einer void-Funktion Register ändert, ohne den Ursprungszustand 
wieder herzustellen.

Der Link von "Bla" scheint da wohl die wesentlichen Antworten zu bieten. 
Ich werde das mal durchlesen.

von Jim M. (turboj)


Lesenswert?

AVR-Nutzer schrieb im Beitrag #4897842:
> Meine Frage zielte daraufhin ab, in wie weit ein
> Aufruf einer void-Funktion Register ändert, ohne den Ursprungszustand
> wieder herzustellen.

Das sagt Dir das C ABI. Die "Clobber" Register werden nicht 
wiederhergestellt, d.h. es gibt Register die eine Funktion beliebeig 
ändern darf. Die müsste man im ISR vorher alle sichern.

Eventuell ist C ohne "naked" effizienter - wenn der Compiler nämlich den 
Inhalt der Funktion kennt und nur benötigte Register sichert.

von c-hater (Gast)


Lesenswert?

Bla schrieb:

> P.S.: nicht vom “Arduino“in der URL irritieren lassen, der Autor geht
> tief in die Materie rein und schafft es durch modifizieren der
> Interrupt-Tabelle auf eine Latenz von fünf Takten zu kommen.

Hallooo! Konstante Latenz! Die ist nahezu immer das kleinere Problem.

Überdies klappt selbst das nur bei den ATMegas und auch bei denen nur, 
wenn sie mehr als 8K Flash haben. Denn nur dann ist genug Platz in der 
Vektortabelle für zwei Befehlswörter pro Vektor.

Der Nutzen so einer Konstruktion ist überdies sowieso recht zweifelhaft. 
Denn wie oben schon angemerkt, gibt es neben der konstanten 
Interuptlatenz auch noch die variable.

Das fängt schon damit an, das jedes Wald- und Wiesenprogramm, selbst 
wenn es sich komplett in main() abspielt, mit an Sicherheit grenzender 
Wahrscheinlichkeit auch Instruktionen enthält, die mehr als nur einen 
Takt zur Ausführung erfordern. Jeglicher SRAM-Zugriff z.B. mindestens 
zwei Takte, jeder Datenzugriff auf den Flash drei und jedes "ret" sogar 
mindestens vier. Allein damit bist du dann im ungünstigsten Fall 
schonmal bei 9 Takten Latenz.

Aber es geht natürlich noch viel weiter: Jeder konkurrierende Interrupt 
(jedenfalls der Teil des ISR-Codes, der exclusiv läuft) und jeder 
cli()-sei()-Block erhöht die variable Latenz um eben seine eigene 
Laufzeit.

Fazit: ein optimiertes Interruptsystem kann nicht daraus bestehen, 
eine ISR hochgradig zu optimieren. Das ist nutzloser Bullshit.

von bla (Gast)


Lesenswert?

c-hater schrieb:
> Der Nutzen so einer Konstruktion ist überdies sowieso recht zweifelhaft.
> Denn wie oben schon angemerkt, gibt es neben der konstanten
> Interuptlatenz auch noch die variable.

Lieber c-hater! Damit hast du natürlich Recht. Es geht dem Autor 
zweifelsfrei nur darum, im Rahmen einer akademischen Übung zu 
demonstrieren, wo die rein technischen Grenzen des Atmega liegen. 
Bestimmt ist auch dir beim sorgfältigen Lesen des Beitrags aufgefallen, 
dass der Autor mehrmals sagt "hier ist genug optimiert, du kannst das 
Lesen aufhören. Aber was wäre wenn..."

Außerdem ist bestimmt jedem fortgeschrittenem Entwickler klar: wenn die 
Performance so bitter nötig ist, dass zu so unorthodoxen Methoden 
gegriffen werden muss, ist ein Wechsel zu einem System mit 
ausgefeilterem (N)VIC naheliegend, die Cortexe sind ja preislich nicht 
so weit von den Atmegas weg. Da der TO in Kenntnis von "naked" ISRs ist, 
zählt er bestimmt auch schon als fortgeschritten. Dadurch musste er uns 
allen bewusste Konzepte wie variable Latenz und Interruptprioritäten 
nicht erwähnen.

Sicherlich bist du auch schon ein fortgeschrittener Entwickler und dir 
dieser Tatsachen selbstredend bewusst, so dass dein Kommentar bestimmt 
nur unterhaltend gemeint war.

> Fazit: ein optimiertes Interruptsystem kann nicht daraus bestehen,
> eine ISR hochgradig zu optimieren. Das ist nutzloser Bullshit.

Nein, nein, das mit der überschriebenen Vektortabelle ist nur eine 
harmlose Grenzwertbetrachtung, rein interessehalber. Dein Beitrag 
hingegen

> Das ist nutzloser Bullshit.

Glücklicherweise ist die Anfangsfrage des Threads ja beantwortet, damit 
können wir uns zu den irrelevanteren Diskussionspunkten bewegen.

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.