Hi Guys,
meine Frage gilt der Fehlerbehandlung in C++.
Ich weiss das ich Fehler mit den try and catch Befehlen abfangen und
behandeln kann.
Jedoch wie geeignet ist dieses wenn das Programm auf einen µC laufen
soll?
Ich mich da mal durchgelesen(google & friends), in einigen Artikeln
wurde strikt davon abgeraten aber keine alternative geboten!
Habt ihr da schonmal was in diese Richtung gemacht oder gehört?
Ein Beispielcode ist hier aufgeführt, aber diese Lösung gefällt mir
nicht!!!
Eine Abwandlung von dem von Dir genannten Beispiel ist, dass
grundsätzlich jede Funktion einen Error-Code zurückgibt (typedef auf
int). Dieser wird lokal gespeichert. Initialisierung auf 'ok'.
Jede Funktion wird nur dann aufgerufen, wenn der lokale Fehlercode noch
'ok' entspricht.
Wenn eine Funktion mit einem von ihr aufgerufenen Fehlercode nichts
anfangen kann, reicht sie ihn halt einfach weiter hinauf. Ansonsten
unternimmt sie Massnahmen und setzt einen ensprechend neuen Fehlercode.
Nachteile:
-Jeder Funktionsaufruf muss in einem if-Block stattfinden, der prüft, ob
der (jeweils lokal gespeicherte) Fehlercode noch "ok" entspricht. ->
Zeilenzahl quasi verdreifacht.
-Werterückgabe nur noch durch out parameter.
Man kann aber recht weitführendes error handling damit machen.
Gruäss
Simon
Danke schonmal für die schnelle Antwort!
Ich will halt noch die Fehler codieren damit ich weiss wo genau was
schief gelaufen ist. Da genügt kein "nOK", da ich ja nicht weiss wer das
gesetzt hat?
Gruß
GoldenEyes
Erst musst du dich durchringen, was du unter uC verstehst.
Auf einem AVR bis zu einem kleinen ARM kannst du Ausnahmen leider
vergessen, ab da irgendwo lohnt es sich wieder darüber nachzudenken.
Alles, was mit dynamischer Speicherverwaltung arbeitet, wird auf einem
AVR o.ä. schnell knapp.
Im Zweifelsfall fährst du besser damit, zumindest in einer Debugvariante
Trace-Ausgaben z.B. über RS232 in die Welt zu schicken und auf dem uC
wieder zu vergessen.
Wo willst du denn sonst das alles sammeln? In den Lymphdrüsen?
goldeneyes1987 schrieb:> meine Frage gilt der Fehlerbehandlung in C++.> Ich weiss das ich Fehler mit den try and catch Befehlen abfangen und> behandeln kann.> Jedoch wie geeignet ist dieses wenn das Programm auf einen µC laufen> soll?
Die Fehlerbehandlung auf einem (kleinen =? ) µC hat andere Anforderungen
als auf einem PC und ich denke viele machen den Fehler die beim PC
gewünschte und erzielbare Flexibilität auf den µC bringen zu wollen.
Dein Beispiel (wenn ich den Kontext richtig rekonstuiere) ist ein
solcher Fall. Warum das Programm so schreiben, dass ich Kanäle zur
Laufzeit beliebig dazufügen kann? Die Resourcen des µC sind begrenzt,
deshalb überlege ich mir zuerst vieviele Kanäle maximal gebraucht werden
oder möglich sind, und dann lege ich sie alle statisch an.
Das Programm verwendet dann zwar nicht alle, und das muß ich verwalten,
aber ich habe keine Möglichkeit beim Anlegen Fehler zu machen. Nachteile
habe ich auch keine, weil der Speicher des µC ist sowieso da und mehr
als im statischen Fall bekomme ich sowieso nicht. Eher vielleicht
weniger, weil die Verwaltung der dynamische Objekte etwas brauchen wird.
goldeneyes1987 schrieb:> Ich will halt noch die Fehler codieren damit ich weiss wo genau was> schief gelaufen ist. Da genügt kein "nOK", da ich ja nicht weiss wer das> gesetzt hat?
Ich habe mich vielleicht unklar ausgedrückt: Fehlercodes gäbe es in
meinem Vorschlag natürlich viele. Und Du kannst dann auch reincodieren,
woher der Fehler gekommen ist. z.B. 8 Bit Package, 16 Bit Klasse, 8 Bit
Fehlercode.
Natürlich muss man das recht gründlich machen, aber so kann man, wenn
die "oberste" Routine einen Fehler ausspuckt, genau sagen, wo er
entstanden ist und warum.
Ausser natürlich, wie erwähnt, eine Routine weiter "oben" kennt den
Fehler und handled ihn.
Ansonsten wird der gesamte weitere Verlauf des Programms unterbrochen
(kein Aufruf mehr, weil eben der Fehlercode nicht mehr 'ok' ist, und
zuoberst kann dann ein BSoD gezeichnet werden mit dem Code. Dann ein
kleines VB-Skript, das ihn in Klartext übersezt: Package A, Klasse B,
Fehler C.
Ich denke kfalser hat mich falsch verstanden!
Die überprüfung findet nur in der Initialisierungsphase statt!!
Folgende Anmerkung:
Die Module sollen zwar zusammen wervendet werden, jedoch sollen diese
auch getrennt benutzt werden könne (natürlich. nur in bestimmten
konstelationen).
Die gesamt Software(alle Module) sollen es ermöglichen einen Drohnen zu
fliegen.
Aber es soll auch z.B. möglich sein nur die RC zu lesen und mit den
Signalen etwas anders zu machen.
Die Klasse Board verwaltet die Hardware und vergibt freie Pins je nach
µC.
Wenn jemand jetzt 10 Pins anfordert aber gerade der verwendete µC nur 8
hat-> Fehlermeldung!
Die Person die Pins muss sich nicht wissen wieviele Pins der µC hat!
Evtl. ist jetzt klarer geworden wass ich eigentlich vorhabe!
Gruß
GoldenEyes
Klaus Wachtler schrieb:> Wo willst du denn sonst das alles sammeln? In den Lymphdrüsen?
Hm, vielleicht (rotierende) Logfiles auf einer SD-Karte?
Haut vermutlich nicht mehr wirklich hin, wenn es viele Fehler gibt, weil
der µC dann wohl mehr Rechenzeit mit dem File-I/O verbringt als mit
allem anderen. Aber bei sporadischen Fehlern könnte ich mir das durchaus
noch vorstellen.
goldeneyes1987 schrieb:> Die überprüfung findet nur in der Initialisierungsphase statt!!
Das ist letzten Endes egal.
Der springende Punkt ist, dass das alles Speicher benötigt. Auf einem
größeren ARM ist das kein Problem, auf einem kleinen AVR aber schon.
> Die Module sollen zwar zusammen wervendet werden, jedoch sollen diese> auch getrennt benutzt werden könne (natürlich. nur in bestimmten> konstelationen).
Da würde ich mir überlegen, ob ich nicht einen Konfigurator machen kann,
der auf dem PC läuft.
D.h. auf dem PC stellt mir ein spezielles Programm aus Codebausteinen
die tatsächlich zu benutzende Konfigration in Form eines C++ Programmes
zusammen. Dieses wird dann compiliert und in den µC gebrannt.
Wie Klaus Falser weiter oben schon schrieb: Auf einem kleinen µC kann
man es mit der Flexibilität ganz schnell übertreiben. Und dann ist
Schicht im Schacht.
Wenn man SD-Karte o.ä. hat, ist es sicher sinnvoll, da Logs abzulegen.
Eine Überlegung wäre, das von der restlichen Funktion zu trennen:
1. Ein uC macht wie gehabt die Arbeit, schreibt Logs über RS232 oder was
man halt als Schnittstelle hat.
2. Ein zweiter nimmt die, und versucht alles auf SD o.ä. zu speichern.
Stattdessen kann man auch einen PC o.ä. anklemmen, und dort auswerten
oder speichern.
Das bringt mehr Flexibilität beim Entwickeln, in der Release-Version
lässt man dann den zweiten einfach weg.
Was zuviel ist, wird halt notfalls verworfen.
Karl Heinz Buchegger schrieb:> Das ist letzten Endes egal.> Der springende Punkt ist, dass das alles Speicher benötigt. Auf einem> größeren ARM ist das kein Problem, auf einem kleinen AVR aber schon.
Was ich vergessen hab:
Gerade auf einem kleinen µC hat man dann auch noch das Problem, dass man
mit zuviel Flexibilität den Compiler daran hindert, Optimierungen
einzusetzen.
Wir alle hätten zb auf einem AVR gerne ein LCD Modul, das man zur
Laufzeit auf eine bestimmte Pinkonfiguration konfigurieren kann. Nur hat
das extreme Nachteile, weil der Compiler dann nicht mehr in der Lage
ist, die speziellen Einzelbitzugriffs-Befehle an den Ports zu benutzen,
sondern tatsächlich bei jedem
PORTx |= ( 1 << Lcd.PinE );
die Bitverschiebung im Code machen zu müssen und durch einen kompletten
Read-Modify-Write Zyklus vom PORTx durchmuss. Gegenüber der Lösung, die
der Optimizer bei konstanter Konfiguration erzielen kann, und die in
einem einzigen Assembler Befehl mündet, ist das eine Verschlechterung,
die keiner akzeptieren will. (Ganz zu schwiegen von all den Problemen,
die dadurch entstehen werden, wenn diese Anweisung eben nicht zu einer
einzigen atomaren Anweisung optimiert wird)
Hi,
als ich denke meine Lösung soll eher dahingehend aussehen wie das Klaus
beschrieben hatt. Fehler werden registriert und "irgendwo"
hingeschrieben.
Wenn der Benutzer merkt etwas geht nicht dann kann er "irgendwo"
hinschauen und nachlesen wass evtl. die Ursache sein kann!
Oder habe ich immer noch nen denkfehler??
Gruß
Nico Sch. schrieb:> Ja, wo ist dieses "Irgendwo"?
"Irgendwo" kann auf sein auf einen Flash, SD-Karte oder driekt auf den
PC über ein Funkmodul(XBee/WLAN);
Natürlich soll dafür ein zweiter Controller verwendet werden!
Ich verstehe immernoch nicht ganz, warum Du es so kompliziert machen
willst.
Dein Prog, zumal es in einem uC hockt, hat ja bestimmt eine Main-Loop.
Und in der kannst Du jedesmal, wenn irgendwo im Code ein Fehler passiert
ist, in aller Ruhe diesen Fehler ablegen, wohin Du willst. Mit genauer
Beschreibung, was wo schiefgelaufen ist.
Durch geeignetes Platzieren von "Handlern", die einen Fehlercode, z.B.
im Sinne von: 'IP-Stack, UDP-Packet, Invalid Port' übersetzt in
'RTP-Stack, RTP-Stream-Handler, Sending UDP-Packet failed' übersetzt,
kannst Du einen für Dich geeigneten Tradeoff zwischen Granularität und
Lokalisierbarkeit erreichen. Und wenn Du im RTP-Stream-Handler schon den
Fehlercode übersetzt, kannst Du ja auch gleich einen Log-Eintrag machen:
Sending UDP-Packet failed, ErrorCode 0xf3746234, wobei 0xf3746234 in
Prosa übersetzt heisst: 'IP-Stack, UDP-Packet, Invalid Port'
Ich könnte mir auch vorstellen, dafür eine Art Stack zu machen. Immer,
wenn eine Routine einen Fehler zurückgibt, schiebt sie diesen zusätzlich
auf diesen Stack. Die übergeordnete Routine interpretiert diesen Fehler,
wenn sie kann, verändert ihn (s.o.) und legt diesen Fehler wiederum auf
den Stack.
Die Main-Loop sieht nun: Ah, Fehler, --> schreibt den gesamten
Fehlerstack raus, und man kann den Feheler vom Ursprung her bis nach
ganz oben tracen (und somit, bei geschickter Platzierung dieser Handler
darauf schliessen, was zum Fehler geführt hat).
Nur so eine Idee... hab's selber noch nie probiert
Gruäss
Simon
Ich denke ich werde vorerst dieses mit Hilfe einer Codiertabelle machen!
Am Ende der Init. wird ein String (zahlen???) in die LOG geschrieben.
Anhand der Tabelle kann dann auf den Fehler zurückgeschlossen werden.
So ähnlich wird das im Automobilbereich gelöst
->Fehlercods kennt bestimmt jeder :-(
Ich denke so sollte ich einfach zur einer "akzeptablen" Lösung kommen!??
Gruß
GoldenEyes