Kompilerfehler avr-g++ ?

Gast #5558384
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?
Gast #5558389
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 ...
Gast #5558409
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.
Gast #5558421
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.
#5558447
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.
Gast #5558470
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren