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
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)
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
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
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.