www.mikrocontroller.net

Forum: Compiler & IDEs Interrupt + Stack ???


Autor: AndreasH (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich habe einen merkwürdigen Fehler, den ich mir nicht erklären kann und
auch nicht weiss wie ich dahinter komme.

Mein Programm besteht aus einem C-Modul und einem Assembler-Modul.
Im Assembler-Modul gibt es eine Interrupt-Routine. Hier würde ich gerne
alle benutzten Register sichern. Dabei entsteht aber das Problem.
Es lassen sich nur eine bestimmte Anzahl Register sichern. Sobald ich
auch nur einen einzigen push/pop-Befehl ausführe funktioniert es nicht
mehr.
So sieht die noch funktionierende Interrupt-Routine aus:

SIG_OVERFLOW0:
    push    r2              ; Timer/Counter0 Overflow
                push    r30
;                push    r31
;    push    r17
;    push    r16
;    push    r5
    in      r2, SREG
    in      r16, TCNT0
          subi    r16, 0x50
    out     TCNT0, r16
          andi    r17, -0x11
                sbic    PIND, PIND2
                ori     r17, 0x10
                lds     r5, unk_200082
                or      r5, r16
                sts     unk_200082, r5
;               pop     r5
;               pop     r16
;               pop     r17
;               pop     r31
                pop     r30
                out     SREG, r2
                pop     r2
                reti

Wird jetzt ein push und der zugehörige pop-Befehl auskommentiert,
klappt es nicht mehr.
avr-nm gibt mir an, dass 8% des Datenspeichers belegt ist. Das kann gut
sein, ich habe kaum Variablen im Programm.
Als Controller wird der AT90S8515 verwendet.
Die Hex-Datei habe ich auch disassembliert. Die Ensprungadressen
stimmen.

Kann mir hier jemand mal einen Tip geben wie ich den Fehler eingrenzen
kann.

Danke

Andreas

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ein push/pop ist ja noch drin.
vielleicht solltest du dir im simulator mal den speicher angucken.
bin mir zwar nicht sicher, aber es kann doch sein das der compiler
seine variablen irgendwo ablegt und diese doch durch den stack platt
gemacht werden. eine andere möglichkeit wäre die zeit. reicht die zeit
bis zum nächsten interrupt aus um die befehle abzuarbeiten? (stack
overflow)

Autor: AndreasH (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Sebastian,

das ging ja superschnell. Danke.

Soweit ich weiss, ist doch der nächste interrupt gesperrt bis der erste
abgearbeitet ist.

Ich meine aber nicht, dass es dieses Problem ist. Ich habe mir den
Inhalt von SPL und SPH mal über die serielle Schnittstelle ausgeben
lassen. Das sieht immer ähnlich aus. Mal um +/- 2. Das kann aber
durchaus sein. Je nachdem in welcher Routine der Controller gerade
steckt.

Die Vermutung mit den Variablen hatte ich auch schon. Ich meine auch
irgendwo gelesen zu haben, wie ich an die Adressen komme.

Grüße
Andreas

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
lad die elf datei die der compiler ausgibt doch mal in avr studio.

und setz am anfang von der isr mal "cli" und am ende "sei"... nur
um sicher zu gehen. wenn der interupt zu früh erneut ausgelöst wird
dann springt er glaub ich erst ins hauptprogramm zurück und dann sofort
wieder in die isr... also ist dann nur noch mit der isr beschäftigt

Autor: AndreasH (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich denke ich habe es gefunen bzw. bin mir ziemlich sicher. Muss es aber
noch detailliert testen.

Bei der ganzen Sache handelt es sich um eine Can-Datenübertragung bei
der das Protokoll softwaremäßig erzeugt wird.
Deine Vermutung, dass der nächste Interrupt kam, bevor der erste
abgearbeitet wurde, ging in die richtige Richtung.

Hier war die Geschwindigkeit der Datenübertragung zu hoch. Die
Interruptroutine wurde zwar korrekt abgearbeitet. Aber insgesamt war
das Protokoll fehlerhaft. Ich hatte mir eine LED gesetzt, wenn alles in
Ordnung war. Diese leuchtete nicht mehr sobald ich Befehle in die
Interrupt-Routine eingefügt hatte. D.h. die Bitrate war zu hoch.
Dadurch die Datenübertragung fehlerhaft. Das ganze lief über einen
Timer. Der war zu schnell abgelaufen.
Habe die jetzt runtergesetzt und dann kann ich einige Befehle in die
Interrupt-Routine einfügen.

Meine Vermutung, dass irgendwas mit dem Stack wäre war also total
daneben.

Ich hoffe, ich habe das einigermassen klar ausgedrückt.

Danke nochmals für Deine Hilfe.

Grüße
Andreas

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.