Forum: Compiler & IDEs zeitkritische Interrupts


von Dingens (Gast)


Lesenswert?

hi,

ich habe eine avr applikation als frequenzzähler mit entsprechend
zeitkritischem externen interrupt. bisher in assembler mit dem avr
studio programmiert, dementsprechend war das
interrupt-ansprech-verhalten determiniert und im datenblatt nachlesbar.
bin jetzt auf avr-gcc umgestiegen um komfortabler die menüführung
programmieren zu können. nun habe ich festgestellt, dass der compiler
ernorm viele freiheiten hat und z.B. selbst dann noch, wenn ich meine
interrupt-funktion in assembler schreibe die freiheit hat, vor der
ausführung der funktion noch diverse register zu pushen und andere
spässchen zu machen, sprich ich hab keine ahnung nach wieviel takten
nach interruptauslösung im kompilierten programm meine
interruptfunktion abgearbeitet wird. auf diese weise habe ich eine
nicht einschätzbare zähler-ungenauigkeit.

gibt es eine möglichkeit beim avr-gcc determiniertes interruptverhalten
zu erzwingen? kann ich irgendwie bewirken, dass aus der
interruptvektortabelle direkt und ohne zwischensprünge, ohne vorheriges
gepushe oder sonstirgendwas mein assembler-code angesprungen wird?

oder kann man irgendwie "invertiert" arbeiten und den programmkörper
samt interruptvektortabelle wie gewohnt manuell in assembler
programmieren und dann für bestimmte aufgaben c-funktionen einbinden?

danke,
dingens

von Jörg Wunsch (Gast)


Lesenswert?

Nun, das Verhalten des Compilers ist natürlich schon
deterministisch. ;-)

Aber das willst Du sicher gar nicht.  Du willst ja wohl eigentlich
eher eine ISR in Assembler.  Dann tu's doch einfach.  Die register
usage conventions stehen in der avr-libc Doku drin (in der FAQ,
genauer gesagt).  Es gibt auch in Kapitelchen über reine
Assemblerprogrammierung dort.

Ganz davon abgesehen, ich habe auch schon Frequenzen mit dem AVR
gezählt, aber je nach Lage der Meßfrequenz zur Referenzfrequenz finde
ich dabei input capture oder einfaches Mitzählen der externen Frequenz
deutlich praktikabler.  Mit Deiner Methode dürftest Du ja keinen
einzigen weiteren Interrupt in der Applikation haben um
sicherzustellen, daß die ISR für den externen Interrupt wirklich immer
dieselbe Bearbeitungszeit hat.

von Gottfried Bremer (Gast)


Lesenswert?

Weitere Interrupts darf es dabei eigentlich schon geben(nur die Dinger,
die in GCC SIGNAL heissen, können nicht unterbrochen werden.).
Allerdings hast du im Allgemeinen die Unsicherheit, dass ein
mehrtaktiger Befehl(wie zum Beispiel, aber nicht nur das Anspringen
einer ISR) erst zuende ausgeführt wird, bevor dein Interrupt dran ist.
Unerwünschtes "Gesichere" kannst du natürlich auch nach dem
Compilieren im Assembler wieder 'rauswerfen.

von Stefan Kleinwort (Gast)


Lesenswert?

Wenn Du im gcc-Interrupt keine Funktion anspringst, sondern Deinen Code
direkt (ohne Funktionsaufruf) reinschreibst, dann sichert gcc auch
keine "überflüssigen" Register.

Wenn Du dagegen eine externe Assembler-Funktion im IR aufrufst, dann
hat gcc keine Kontrolle mehr und muss alles sichern.

Stefan

von Gottfried Bremer (Gast)


Lesenswert?

Dann macht der das ja bis auf wenige Ausnahmen(z.B. wenn man ein
Register für einen Interrupt reservieren und anderswo garnicht benutzen
will) optimal. Ich nehme mal an, das mit den Funktionen bezieht sich auf
externe Libraries(und nicht auf Bitschieben mit BV oder so)?

von Jörg Wunsch (Gast)


Lesenswert?

_BV() ist keine Funktion, sondern ein simpler Makro.  Ja, die Aussage
bezieht sich in der Tat auf weitere Funktionsaufrufe, nicht notwendig
aber solche aus der Library.  Auch bei Funktionen, die in der gleichen
Quelldatei definiert werden, analysiert der Compiler nicht, welche
Register diese Funktion tatsächlich benötigen würde, sondern geht von
der pessimistischen Annahme aus, daß die gerufene Funktion alle
Register, die sie per ABI verwerfen darf (call-used registers), auch
ggf. benutzt.  Er behandelt also eine Funktion aus der eigenen
translation unit nicht anders als eine extern dazugelinkte.

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.