Forum: Compiler & IDEs Kompilerfehler avr-g++ ?


von F. Weber (Gast)


Lesenswert?

Hallo,

Ich habe ein Problem mit einem c++ Projekt (Atmel-Studio 7) auf einem 
Atmega2560.
Das Programm steht vollständig auf github 
(https://github.com/FlorianWeber1018/ArduinoIO).

Dieses Programm soll Befehle über den UART empfangen und entsprechend 
antworten. Leider funktioniert dies nicht und das Programm verhält sich 
seltsam.
Genauer wird der this-Pointer des cmdParser Objekts (cmdParser.cpp) 
durch den Aufruf der  globalen Funktion 
"cmdHandler_get_config_io(uint8_t pin)" (cmdHandler.cpp), in der 
MemberFunction "void cmdParser::parseOne() volatile" (cmdParser.cpp) 
auf null gesetzt. Dies führt letztendlich zu dem seltsamen verhalten des 
Programms.

ich habe bereits längere Zeit damit verbracht den Fehler einzugrenzen 
und kann mir es nicht mehr anders erklären wie mit einem Compilerfehler.
in den Eingangsbuffer des UART lade ich zum Test ein Paar Pakete, sodass 
die Simulation des Projekts den Fehler reproduziert.
Die Optimierung habe bereits deaktiviert.

Nun bin ich ratlos und frage hier nach Hilfe.
Ist es wirklich ein Fehler im Compiler oder sehe ich den Wald vor lauter 
Bäumen nicht mehr?

von foobar (Gast)


Lesenswert?

> Ist es wirklich ein Fehler im Compiler oder sehe ich den Wald vor
> lauter Bäumen nicht mehr?

Eher letzteres. Wenn lokale Variablen auf einmal ihren Inhalt verlieren, 
würd ich als erstes mal nach Buffer-Overflows schauen ...

von F. Weber (Gast)


Lesenswert?

Vielen Dank für den Tipp. Ich habe gerade nochmal speziell danach 
gesucht, allerdings greife ich nur an einer Stelle im betreffenden 
Abschnitt schreibend auf ein Array zu, ein Auskommentieren dieser Zeile 
hat nichts geändert.

von Kaj (Gast)


Lesenswert?

foobar schrieb:
> Buffer-Overflows

Ich hab dein Problem mal auf das wesentliche reduziert:
1
void cmdHandler_get_config_io(uint8_t pin)
2
{
3
    if(pin < 40){
4
5
        uint8_t numberStr[2];
6
7
        plotNumber(3, numberStr);
8
9
    }
10
}
11
12
void plotNumber(int16_t number, unsigned char* result) {
13
    result[0] = (unsigned char)( number & 0x000F );
14
    result[1] = (unsigned char)( ( number >> 4 ) & 0x000F );
15
    result[2] = (unsigned char)( ( number >> 8 ) & 0x000F );
16
    result[3] = (unsigned char)( ( number >> 12 ) & 0x000F );
17
}

Wahrscheinlich rechnest du damit, dass die andere Funktion aufgerufen 
wird:
1
void plotNumber(uint8_t number, unsigned char* result){
2
    result[0] = ( number & 0x0F );
3
    result[1] = ( number >> 4 ) & 0x0F;
4
}
Das ist aber nicht der Fall, wie man im Simulator auch einfach 
feststellen kann.

von (prx) A. K. (prx)


Lesenswert?

NB: In eine ISR gehört normalerweise kein cli/sei.

von Florian W. (florian_weber)


Lesenswert?

Vielen Dank für die schnelle Hilfe.
Ich hatte schon in dem Assemblercode gesucht, dabei war es so was 
simples.

Super Forum, zwischen Eröffnung und Lösung weniger als eine Stunde.

Vielen Dank

von Florian W. (florian_weber)


Lesenswert?

A. K. schrieb:
> NB: In eine ISR gehört normalerweise kein cli/sei.

Dessen bin ich mir bewusst.... Ist dort auch nur zu Testzwecken 
vorhanden um den Fehler einzugrenzen. (bevor ich das mit dem this 
Pointer entdeckt habe war an dieser Stelle das erste Anzeichen das etwas 
nicht stimmt)

von (prx) A. K. (prx)


Lesenswert?

Florian W. schrieb:
>> NB: In eine ISR gehört normalerweise kein cli/sei.
>
> Dessen bin ich mir bewusst....

Wirklich? Es tut hier das Gegenteil dessen, nach dem es aussieht. Bei
 ISR(...) { cli(); ...; sei(); }
entsteht zwischen sei() und dem tatsächlichen Ende der ISR ein recht 
signifikantes Fenster aus Befehlen, die mit eingeschaltetem Interrupt 
ablaufen. Kann ggf zu Stack-Überlauf aufgrund verschachtelter ISRs 
führen. Ohne cli()...sei() hingegen wird die gesamte ISR mit 
abgeschalteten Interrupts ausgeführt.

von Florian W. (florian_weber)


Lesenswert?

A. K. schrieb:
> Wirklich? Es tut hier das Gegenteil dessen, nach dem es aussieht.

Da war ich wohl falsch informiert, ich dachte eine ISR könnte eine 
andere
standardmäßig unterbrechen.

Danke für die Aufklärung.

von Kaj (Gast)


Lesenswert?

Florian W. schrieb:
> Da war ich wohl falsch informiert, ich dachte eine ISR könnte eine
> andere standardmäßig unterbrechen.
Das haengt vom Controller ab. Bei AVR geht das nicht, bei ARM schon. Ein 
Blick ins Datenblatt hilft.
1
7.8 Reset and Interrupt Handling
2
3
[...]
4
When an interrupt occurs, the Global Interrupt Enable I-bit
5
is cleared and all interrupts are disabled.

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.