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