Hi,
ich bräuchte dringend Hilfe. Derzeit arbeite ich an einem Programm für
meinen AtMega8, dass mein Fahrzeug steuert, also zwei Motoren. Das
Programm wäre soweit fertig, es müssen nur noch die Fehler raus ;).
Allerdings komme ich nun nicht mehr weiter. Ich habe das Problem, dass
sich mein Programm aus unbekannten Gründen immer wieder neu startet. Das
kann ich über mein Serial Terminal Programm sehen, ich debugge über die
UART. Vorhin gings noch ohne Problem, bevor ich einen Bug aus meiner
Timer Komponente entfernte. Wenn ich den Simulator vom AVR Studio 4
drüber laufen lasse, bekomme ich immer wieder die Nachricht "AVR
Simulator: Invalid opcode 0xffff at address 0x000f00", was das bedeutet
habe ich bereits heraus gefunden, mein Programm springt komischerweise
immer wieder zur Addresse 0x000f00, wo aber nichts ist, nur warum
springt es ins leere?? Ich verwende in meiner Timer Komponente nur
einmal ein Array von Funktionszeigern, ansonsten werden keine eigenen
Funktionssprünge von mir vorgenommen, außer von C. Das Programm ist
recht groß geworden, weshalb ich vorerst nur die Timer Komponente zeigen
werde.
Timer.h
Ich habe leider überhaupt keine Ahnung, warum das passiert. Er startet
solange neu bis das Array überläuft und es zum Fehler kommt, was
ebenfalls schon merkwürdig ist, da bei Neustart timerHandlerCount immer
wieder zurück gesetzt wird. Wenn das zuwenig werde ich den ganzen Code
zeigen, aber die Initialisierung müsste Fehler frei sein.
Vielen Dank für die Hilfe
mfg
Christopher C. schrieb:> Wenn ich den Simulator vom AVR Studio 4> drüber laufen lasse, bekomme ich immer wieder die Nachricht "AVR> Simulator: Invalid opcode 0xffff at address 0x000f00"
Bist du sicher, dass du den richtigen Controller im Simulator ausgewählt
hast?
Der Controller ist richtig eingestellt. Ich lasse mir jetzt jedes mal,
wenn die timerInit() Funktion aufgerufen wird, eine Nachricht schicken.
Nun läuft das Array nicht mehr über, allerdings startet er immer noch
wieder neu. Habe den Simulator wieder drüber laufen lassen. Jetzt
bekomme ich die Nachricht "Stack pointer below start of RAM", das
bedeutet doch das RAM voll ist O.o vom Stack, oder? Das wäre eine
Erklärung für das Phänomen oder?
> Irgendwelche undefinierten Interrupts aktiviert ohne passende ISR?
Eigentlich nicht, nur die Timer und UART Komponente rühren andere
Register als die Input/Output an.
Das erste Problem ist, ersteinmal darüber klar zu sein, was denn den
Jump/Gosub an diese Stelle versursachen kann.
Das kann mindestens zwei Ursachen habe:
1. Es werden mehr RETs ausgeführt als zuvor Gosubs ausgeführt wurden.
Bei einem C Programm unwahrscheinlicher als bei einem Assemblerprogramm.
2. Eine Variable respektive ein Array wird jenseits seiner Grösse
geschrieben.
Das scheint mir hier wahrscheinlicher zu sein.
Deine timerAddHandler ist vermutlich so ein Kandidat, denn sie schreibt
in das Array auch wenn der maximale Index längst erreicht ist.
Ich schreibe "vermutlich", da es möglich ist, das Deine error-Funktion
den Return-Stack manipuliert um eben dieses Problem zu vermeiden.
Schreib mal was dazu bzw. zeige uns die error-Funktion.
Ein anderer Angriffspunkt ist mal im Memory-Map File zu gucken was denn
unmittelbar vor dem Stack als Variable deklieriert ist. Die Funktionen
welche dieses Variable manipulieren solltest Du Dir mal anschauen.
Christopher C. schrieb:> Jetzt> bekomme ich die Nachricht "Stack pointer below start of RAM", das> bedeutet doch das RAM voll ist O.o vom Stack, oder?
Oder dass du doch den falschen Controller eingestellt hast, entweder im
Simulator oder beim Compilieren (das sind zwei separate Einstellungen).
Danke schon mal für die ganzen Antworten.
Ich hab noch mal geschaut, der Controller ist in den
Projekteigenschaften sowie in "Select Platform and Device" richtig
eingestellt. Ich verwende den ATMega8515 hab nur fälschlicherweise den
ATMega8 angegeben, ist aber in den Einstellungen richtig.
Das ist die Error Funktion
1
voiderror(constuint8_terrorCode)
2
{
3
chartmpStr[5];
4
utoa(errorCode,tmpStr,10);
5
uartSendSyncMessage("ERROR: ");
6
uartSendSyncMessage(tmpStr);
7
while(1){}/* Endlosschleife */
8
}
Eigentlich nichts verdächtiges, oder?
Wo kann ich die Memory-Map File finden?
>Wo kann ich die Memory-Map File finden?
Da wo es die Dokumentation sagt. ;-)
Jedenfalls wird nicht weiter in dieses Array geschrieben. OK.
Ein anderer Aspekt, der sich möglicherweise aber nicht auf Dein Problem
bezieht, ist, was denn die uartSendSyncMessage-Funktion macht.
Verwendest Du den UASRT per Interrupt oder per Polling? Zeig mal die
Funktion bitte.
Christopher C. schrieb:> Ich hab noch mal geschaut, der Controller ist in den> Projekteigenschaften sowie in "Select Platform and Device" richtig> eingestellt.
Dann sehe ich 3 Möglichkeiten (Reihenfolge nach Wahrscheinlichkeit):
1) Du legst selber irgendwo reichlich Daten auf den Stack (zeige
zumindest mal main()).
2) Du hast irgendwo selbst geschriebenen fehlerhaften ASM-Code.
3) Bug im Compiler.
Also ein paar Daten lege ich schon auf den Stack, aber ganze 512 Bytes?
Da es sehr umfachreich ist poste ich mal den ganzen Code.
ASM Code benutze ich nicht, reines C.
Christopher C. schrieb:> uint8_t timerHandlerCount = 0;
Muss da nicht "volatile" hin wegen:
> ISR(TIMER0_COMP_vect)> {> int i;> for (i=0;i<timerHandlerCount;i++)
Gruß Dietrich
> TCCR0 |= (1 << WGM01);> OCR0 = ctcValue;> TIMSK |= (1 << OCIE0);
ATmega8 hat weder OCRO, TIMSK.OCIE0 noch TCCR0.WGMxx
Zudem ist das Setzen von timerHandlerArray nicht atomar.
> ATmega8 hat weder OCRO, TIMSK.OCIE0 noch TCCR0.WGMxx
Das mag sein, aber ein ATMega8515 :).
> Zudem ist das Setzen von timerHandlerArray nicht atomar.
Stimmt das könnte unter Umständen gefährlich werden, ein cli() und ein
sei() in timerAddHandler() dürfte helfen, oder?
Christopher C. schrieb:>> Zudem ist das Setzen von timerHandlerArray nicht atomar.> Stimmt das könnte unter Umständen gefährlich werden, ein cli() und ein> sei() in timerAddHandler() dürfte helfen, oder?
Nicht wirklich nötig. Der Interrupt erfährt ja erst durch das Erhöhen
von timerHandlerCount von dem neuen Eintrag, da muss das Eintragen
selber nicht atomar sein.
Ich glaube, dass ich eine interessante Entdeckung gemacht habe. Ich habe
noch mal den Simulator laufen lassen, er meldet wieder "Stack pointer
below start of RAM" und hält bei
. Ich weiß, dass ich damals diesen Befehl fälschlicherweise in der If
Abfrage hatte. Nun habe ich mal die Parameter überprüft, der Parameter:
bool ctcMode ist false, obwohl er eigentlich true sein müsste. Beim
ersten Aufruf ist er auch true, d.h. irgentwas stimmt da gewalltig
nicht. Läuft der Mikrocontroller amok? Aber warum sind die ganzen
Nachrichten über die UART in der richtigen Reihenfolge? Füllt der Stack
den ganzen Speicher aus. Was meint ihr?
An dem ersten Bild kann man sehen, dass du die libm.a nicht mitlinkst
(was den RAM-Verbrauch drastisch erhöht). Unter "Libraries" hinzufügen
und nochmal probieren.
@ Stefan Ernst
>An dem ersten Bild kann man sehen, dass du die libm.a nicht mitlinkst
Magst Du bitte etwas mehr im Detail erklären, woran man das sieht? Würde
mich interessieren.
Wow tatsächlich, das drückt den Speicherverbrauch drastisch und nun
funktionierts sogar. Endlich. Also lags am vollen Speicher. Was genau
macht den diese libm.a?
Vielen Dank ;)
Christopher C. schrieb:>> ATmega8 hat weder OCRO, TIMSK.OCIE0 noch TCCR0.WGMxx> Das mag sein, aber ein ATmega8515 :).
Ober schreibst du explizit ATmega8.
Noname schrieb:> @ Stefan Ernst>>An dem ersten Bild kann man sehen, dass du die libm.a nicht mitlinkst>> Magst Du bitte etwas mehr im Detail erklären, woran man das sieht? Würde> mich interessieren.
An dem auffälligen Muster:
01 02 02 03 03 03 03 04 04 04 04 04 04 04 04 ...
Das ist eine Lookup-Tabelle, die vom generischen Math-Code benutzt wird.
Stefan Ernst schrieb:> 01 02 02 03 03 03 03 04 04 04 04 04 04 04 04 ...> Das ist eine Lookup-Tabelle, die vom generischen Math-Code benutzt wird.
Was aber auch mit libm passieren kann, siehe
http://gcc.gnu.org/PR29524 (behoben in 4.7.0)
Johann L. schrieb:
>>> ATmega8 hat weder OCRO, TIMSK.OCIE0 noch TCCR0.WGMxx>> Das mag sein, aber ein ATmega8515 :).> Ober schreibst du explizit ATmega8.
Ja war ein kleiner Denkfehler.
> Ich verwende den ATMega8515 hab nur fälschlicherweise den ATMega8 angegeben,
ist aber in den Einstellungen richtig.
Also vielen Dank noch mal ;)