Hallo zusammen, ich beschäftige mich im Moment mit AVR und STM32 mit AVR-GCC bzw ARM-GCC. Und schon wieder bin ich auf eine Anfängerfrage gestoßen: Wie werden auf einem Mikrocontroller eigentlich error()- und assert()-Funktionen implementiert. Momentan sieht es bei mir so aus, daß ich selbst eine Funktion void error(void) implmentiert habe, die alle Ausgänge hochohmig schaltet und dann in eine Dauer-while-Schleife übergeht. Irgendwann sieht man, daß das "heartbeat"-Signal ausbleibt und kann dann mit dem Debugger nachsehen. Aber wie wird soetwas "richtig" gemacht? Kennt ihr Quellen, die bewährte Verfahren beschreiben? Viele Grüße W.T.
http://nongnu.org/avr-libc/user-manual/group__avr__assert.html http://nongnu.org/avr-libc/user-manual/group__avr__stdlib.html#ga63e28bec3592384b44606f011634c5a8 Wobei ich das noch nie gemacht habe. Wenn der Controller gar nichts mehr macht, hat man nicht viel davon. Evtl. ist es sinnvoller, neu zu starten?
assert() hab ich auf einem uC noch nie verwendet. Ich versuch aber immer eine LED an irgendeinen freien port zu hängen, die sendet im Normalfall eine Art "Heartbeat" (alle paar Sekunden kurz blinken), und dann hab ich immer noch ein "panic(uint8_t code)" Funktion, die blinkt mir zuerst ein SOS zu, und dann den code (meist nur die unteren vier Bit) als eine Art Morsecode (0=kurz, 1=lang) zu.
Klaus Wachtler schrieb: > http://nongnu.org/avr-libc/user-manual/group__avr_... > http://nongnu.org/avr-libc/user-manual/group__avr_... > Die beiden kannte ich schon. Leider fehlt mir die Erfahrung, um aus dieser Beschreibung best practices abzuleiten. > Wobei ich das noch nie gemacht habe. Wenn der Controller gar nichts mehr > macht, hat man nicht viel davon. > Evtl. ist es sinnvoller, neu zu starten? Das hängt davon ab, in welchem Entwicklungstadium sich die Firmware befindet. Wenn sie ausentwickelt ist, ist es sicherlich sinnvoll, wenn sie irgendwie weiterläuft oder neustartet, wenn ein Fehler aufgetreten ist (graceful degradation). Im Stadium der Firmwareentwicklung will ich jedoch jeden Fehler so hart und deutlich wie möglich merken, um ihn möglichst einfach beheben zu können.
Na ja, so hart und deutlich wie möglich wäre 1 kg C4 mit Zünder an einem Ausgang, der im Fehlerfall gesetzt wird. Ansosonsten hiflt nur das übliche: Simuator, Emulator, Debug-Textausgabe. Da kannst du dann aich assert-Macros der avr-libc nutzen. Oliver
Ich verwende am Cortex-M in Anlehnung an das normale assert() und Visual Studio's "VERIFY" gerne sowas:
1 | inline void verify (bool cond) { |
2 | if (!cond) { |
3 | while (1) { |
4 | asm volatile ("cpsid i\nbkpt"); |
5 | }
|
6 | }
|
7 | }
|
8 | |
9 | #ifdef NDEBUG
|
10 | // because eventual evaluation of the argument
|
11 | #define assert(c) static_cast<void>(0)
|
12 | #else
|
13 | inline void assert (bool cond) { |
14 | verify (cond); |
15 | }
|
16 | #endif
|
Die verify() -Funktion prüft ihr Argument immer, und schaltet im Fehlerfall Interrupts ab und ruft "BKPT" auf, sodass ein evtl. angeschlossener Debugger das als Breakpoint sieht und man wunderschön im Backtrace etc. sehen kann was schief gelaufen ist. Das assert() ist nur im Debug-Modus aktiv (sonst macht es gar nichts) und prüft nur dann sein Argument. Man kann so in seinem Code auf Verdacht überall mit assert() alle möglichen Variablen prüfen, und im End-Programm nimmts keinen Platz/Rechenzeit weg. Hab so schon einige Bugs gefunden. Eventuell kann man ja noch Code einfügen um Pins auf Floating zu schalten etc. Wenn man kein C++ sondern C verwendet muss man das static_cast und das "bool" ändern.
Danke für die Antworten! Aber das kann doch nicht alles sein? Ich hätte gedacht, daß Fehlerbehandlung zu den Problemen für Fortgeschrittene gehört und es deshalb schön formulierte best practices gibt, damit wir Normalsterbliche nicht ziellos umherprogrammieren müssen. Oder gibt es soetwas erst ab Systemen mit Betriebssystemen? EDIT: Nanu, kursiv geht nicht, wenn ein Zeilenumbruch drin ist (?)
:
Bearbeitet durch User
Walter Tarpan schrieb: > Ich hätte gedacht, daß Fehlerbehandlung zu den Problemen für > Fortgeschrittene gehört und es deshalb schön formulierte best practices > gibt, damit wir Normalsterbliche nicht ziellos umherprogrammieren > müssen. Nun ja, ein "assert" kann man schwer als "Fehlerbehandlung" bezeichnen. Das ist sozusagen der Not-Aus, und in Produktivcode sollten sich meines Wissens nach auch keine Asserts mehr befinden. Das ist eher ein Testwerkzeug und muss auch nur anzeigen, wo etwas wie fehlgeschlagen ist. Je nach Vorliebe und Möglichkeiten eben mit LEDs o.a. Was du mit "error()" meinst musst du vielleicht noch etwas genauer ausführen. Meinst du das als Synonym zu assert()? Oder im Sinne von Exception-Handling usw., also echter Fehlerbehandlung?
OK, "assert" und "error" sind sicherlich keine Fehlerbehandlung für Fortgeschrittene. Also hätte ich den Thread eher "bewährte Methoden der Fehlerbehandlung auf ARM und AVR" nennen sollen.
Walter Tarpan schrieb: > Also hätte ich den Thread eher "bewährte Methoden der Fehlerbehandlung > auf ARM und AVR" nennen sollen. Viele Programmiersprachen bieten mit Exceptions einen vereinheitlichten mächtigen Mechanismus zur Fehlerbehandlung; auf ARM's mit genug Speicher kann man die in C++ verwenden. Ansonsten muss man sich halt wie immer mit return codes behelfen. Da aber das typischer µC-Programm keine 100 Aufruf-Ebenen hat, ist das da noch verkraftbar...
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.