mikrocontroller.net

Forum: Compiler & IDEs zeitkritische Interrupts


Autor: Dingens (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Jörg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Gottfried Bremer (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Stefan Kleinwort (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Gottfried Bremer (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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)?

Autor: Jörg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

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.