Ich habe das Problem, dass bei einer Übertragung die XOR Checksumme immer wieder falsch berechnet wird. (ca. 50 bis 70% der Checksummen werden falsch berechnet.) Ich verwende einen ATtiny24. Ich bin mir ziemlich sicher dass der Fehler bei der Berechnung passiert, da wenn ich die Datenquelle abhänge, wird immer die gleiche, falsche Checksumme überbittelt. Dass Merkwürdige ist, dass alle Arrays Global sind, wodurch eigentlich keine übermäßige Ram-Menge belegt werden sollte. Aktuell sind ca.87% des Flash, ca.53% des SRams und 0% des EE-Proms belegt. Das Merkwürdige ist, dass solange ich beim Starten geladene Standardwerte ohne Fehler verarbeitet werden. Der Fehler tritt erst auf, sobald das erste mal Daten eingelesen werden. (ADC-Werte und PWM-Signale) Vor dem Berechnen der Checksumme werden mit cli alle Interrupts abgedreht um mit die Daten nicht zu verändern. Dann werden alle Daten in ein eigenes Übertragungsarray geschrieben. Erst nach dem Kopieren der Daten werden die Interrupts wieder mit sei aktiviert. Kann mir bitte jemand ein paar generelle Tipps geben wie man solche Fehler eingrenzen kann? Wie kann man z.B. feststellen dass der Stack überläuft? Bitte kommt mir jetzt nicht dass der Fehler in Programmzeile 42 liegt. Ich brauche nur ein paar Tipps um das Problem selbst lösen zu können.
Bernhard schrieb: > Bitte kommt mir jetzt nicht dass der Fehler in Programmzeile 42 liegt. > Ich brauche nur ein paar Tipps um das Problem selbst lösen zu können. Was erwartest du dann hier? Mann könnte dir jetzt alles mögliche raten, was aber vielleicht in deinem Programm noch nicht mal verwendet wird. Und da du noch nicht mal deine Programmiersprache explizit erwähnst, ist das nicht mehr Stochern im Nebel, das ist einfach Zeitverschwendung. Aber bitte: einfache Eingabe -> checksumme berechnen lassen -> ausgeben -> von hand prüfen
Bernhard schrieb: > Ich bin mir ziemlich sicher dass der Fehler bei der Berechnung passiert, Darauf würde ich nicht wetten. Seltsame Fehler, die völlig unerklärlich sind, haben meistens ihren Ursprung in einem Fehler ganz wo anders. Arrayüberläufe, für Strings zu klein dimensionierte Arrays sind da die klassischen Kandidaten, allerdings sind das beileibe nicht alle Möglichkeiten. Eigentlich kann man erst hinterher, wenn man den Fehler gefunden hat, genau sagen wie sich dieser Fehler auswirkt, so dass man die Symptome sieht, die man sieht. Genau das ist das fiese an der Sache.
Folgendes kann man zum Beispiel machen: -Auf einem normalen PC kompilieren (vorausgesetzt, die Funktion ist in C oder so geschrieben) und dort mal mit entsprechenden Beispielwerten diverse Testläufe laufen lassen. Kommt auf der anderen Plattform immer das richtige Ergebnis raus, kann es also nicht an der Prüfsummen-Funktion an sich liegen, denn man hat dann ja gezeigt dass sie korrekt implementiert ist. -Debugger benutzen, Breakpoint setzen und die Funktion auf der Zielplattform Schritt für Schritt durchsteppen, notfalls hier mit Testarrays als Eingabe arbeiten weil man die Daten ja dann nicht in Echtzeit (über irgendeine Schnittstelle) bekommt -Laufzeit prüfen: Einen Digitalausgang des Mikrocontrollers auf 1 setzen wenn die zu prüfende Funktion startet, und auf 0 setzen wenn sie endet. So kann man mit einem Oszilloskop sehr schön sehen, wie groß die Bearbeitungszeit für die Funktion ist - eventuell liegt sie nicht mehr im passenden Rahmen, je nachdem welchen Zeitbedingungen die Anwendung unterliegt. -Generell prüfen, ob der Defekt nicht in der Hardware vorliegt: Mal den Mikrocontroller gegen einen anderen austauschen und die exakt gleiche Software aufspielen. -Generell prüfen, ob einem nicht der (falsch eingestellte) Watchdog dazwischenhaut - ein beliebter Fehler, wie ich aus eigener Erfahrung in meinem ersten Projekt nach dem Studium erleben durfte :-) Die Wahrscheinlichkeit, dass der Speicher an irgendeiner Stelle korrumpiert wird (z.B. wie von Karl heinz Buchegger beschrieben), halte ich für sehr viel größer als dass eine einfache Schleife über ein Array von Bytes und deren XOR-Verknüpfung Probleme macht.
Floh schrieb: > Aber bitte: > > einfache Eingabe -> checksumme berechnen lassen -> ausgeben -> von hand > > prüfen Dass war das 1. das ich gemacht habe um herauszufinden welche Seite der Komunikation da die falsche Checksumme liefert. Karl heinz Buchegger schrieb: > Bernhard schrieb: > >> Ich bin mir ziemlich sicher dass der Fehler bei der Berechnung passiert, > > Darauf würde ich nicht wetten. > Seltsame Fehler, die völlig unerklärlich sind, haben meistens ihren > Ursprung in einem Fehler ganz wo anders. > > Arrayüberläufe, für Strings zu klein dimensionierte Arrays sind da die > klassischen Kandidaten, allerdings sind das beileibe nicht alle > Möglichkeiten. Eigentlich kann man erst hinterher, wenn man den Fehler > gefunden hat, genau sagen wie sich dieser Fehler auswirkt, so dass man > die Symptome sieht, die man sieht. Genau das ist das fiese an der Sache. Dass ist mir leider schon zu oft passiert. Desswegen hatte ich gefragt welche Herangehensweise es gibt um den Fehler eingrenzen zu können. Denn jeder geht anders an die Fehlersuche heran. Und dadurch gibt es immer wieder nsätze an die man selbst nie im Leben gedacht hätte. Arrayüberläufe kann ich (fast) ausschließen. Denn ich habe die Felder inzwischen um 5 einträge größer germacht als nötug und habe auch einen Versuch mit hardcodet Zugriffen auf die Arrays gemacht. (Da schreit AVR Studio wenn man außerhalb des Arrays zugreift und man greift nicht so schnell daneben.) Es wird eigentlich ganz ohne Strings gearbeitet. Ich verwende nur 8 und 16 Bit Arrays. Was mir aufgefallen ist, ist dass AVR Studio hin und wieder ein 16 Bit Array dur ein 8 Bit Array ersetzt. Und dass obwohl ich ausdrücklich unsigned short geschrieben habe. Mir ist dass nur aufgefallen weil die Ram-Adressen der einzelnen Array-Werte beim Simulieren direkt aufeinander folgten. Mark Brandis schrieb: > Folgendes kann man zum Beispiel machen: > > -Auf einem normalen PC kompilieren (vorausgesetzt, die Funktion ist in C > oder so geschrieben) und dort mal mit entsprechenden Beispielwerten > diverse Testläufe laufen lassen. Kommt auf der anderen Plattform immer > das richtige Ergebnis raus, kann es also nicht an der > Prüfsummen-Funktion an sich liegen, denn man hat dann ja gezeigt dass > sie korrekt implementiert ist. > > -Debugger benutzen, Breakpoint setzen und die Funktion auf der > Zielplattform Schritt für Schritt durchsteppen, notfalls hier mit > Testarrays als Eingabe arbeiten weil man die Daten ja dann nicht in > Echtzeit (über irgendeine Schnittstelle) bekommt > > -Laufzeit prüfen: Einen Digitalausgang des Mikrocontrollers auf 1 setzen > wenn die zu prüfende Funktion startet, und auf 0 setzen wenn sie endet. > So kann man mit einem Oszilloskop sehr schön sehen, wie groß die > Bearbeitungszeit für die Funktion ist - eventuell liegt sie nicht mehr > im passenden Rahmen, je nachdem welchen Zeitbedingungen die Anwendung > unterliegt. > > -Generell prüfen, ob der Defekt nicht in der Hardware vorliegt: Mal den > Mikrocontroller gegen einen anderen austauschen und die exakt gleiche > Software aufspielen. > > -Generell prüfen, ob einem nicht der (falsch eingestellte) Watchdog > dazwischenhaut - ein beliebter Fehler, wie ich aus eigener Erfahrung in > meinem ersten Projekt nach dem Studium erleben durfte :-) > > Die Wahrscheinlichkeit, dass der Speicher an irgendeiner Stelle > korrumpiert wird (z.B. wie von Karl heinz Buchegger beschrieben), halte > ich für sehr viel größer als dass eine einfache Schleife über ein Array > von Bytes und deren XOR-Verknüpfung Probleme macht. Dass habe ich auch schon gemacht. Dass Problem ist, dass mit Daten-Tabellen und Startwerten alles richtig arbeitet. Sowol auf dem PC als auch auf dem uC. Nur sobald die richtigen Daten kommen, gibt's Fehler. Ich vermute, dass da irgentetwas bei der Berechnung und dem Ermitteln der Daten nicht ganz koscher ist. Aber da ich alle Interrupts global abdrehe, dürfte eigentlich nichts passieren. Ich glaube ich werde mich dass Wochenende ausgibig mit dem Quellcode beschäftigen müssen.
Bernhard schrieb: >> die Symptome sieht, die man sieht. Genau das ist das fiese an der Sache. > Dass ist mir leider schon zu oft passiert. > Desswegen hatte ich gefragt welche Herangehensweise es gibt um den > Fehler eingrenzen zu können. Den Fehler gar nicht erst entstehen lassen :-) Klingt jetzt neunmalklug, ist aber so. In kleinen Abschnitten entwickeln. Jeden Abschnitt für sich auf Herz und Nieren testen. > Denn jeder geht anders an die Fehlersuche > heran. Das ist gar nicht so sehr der springende Punkt. Der springende Punkt ist, dass es unglaublich schwer ist, in ein fünf-tausend Zeilen Code die eine zu finden, die für das momentan sichtbare Symptom verantwortlich ist, wenn man nicht nachweisen kann, dass es 4500 nicht sein können, weil man die ausreichend getestet hat. > Und dadurch gibt es immer wieder nsätze an die man selbst nie im > Leben gedacht hätte. Im Extremfall gehört auch ein Quentchen Glück mit dazu. Debugger, die man auf Speicherzellen ansetzen kann und die sich melden, wenn diese Zelle ihren Wert ändert (egal warum, also Überwachung indem nach jeder Anweisung gecheckt wird, ob sich die Zelle verändert hat) > Was mir aufgefallen ist, ist dass AVR Studio hin und wieder ein 16 Bit > Array dur ein 8 Bit Array ersetzt. Ganz sicher nicht. >> Die Wahrscheinlichkeit, dass der Speicher an irgendeiner Stelle >> korrumpiert wird (z.B. wie von Karl heinz Buchegger beschrieben), halte >> ich für sehr viel größer als dass eine einfache Schleife über ein Array >> von Bytes und deren XOR-Verknüpfung Probleme macht. > > Dass habe ich auch schon gemacht. > > Dass Problem ist, dass mit Daten-Tabellen und Startwerten alles richtig > arbeitet. > Sowol auf dem PC als auch auf dem uC. > Nur sobald die richtigen Daten kommen, gibt's Fehler. Dann bleibt dir nichts mehr anderes übrig als: Programm mit printf (bzw dem Äquivalent) spicken und alle auch nur irgendwie interessant scheinenden * Eingangswerte * Zwischenwerte * Ergebnisse ausgeben (UART ist da besser als LCD, weil ein Termialprogramm normalerweise eine längere Sitzung protokollieren kann) Dieses Protokoll mitlesen, Werte auf Plausibilität prüfen und hoffen das man dort den Bereich in etwa eingrenzen kann. Du musst die Black Box öffnen. Momentan weißt du nur, dass hinten was falsches raus kommt, wenn du vorne etwas reinsteckts (die Eingangswerte hast du hoffentlich schon geprüft. Es kommt gar nicht so selten vor, dass eine Funktion gar nicht die Werte vorgesetzt bekommt, die sich der Entwickler vorstellt und mit denen er Debugging betreibt). Also bleibt dir nichts anderes übrig als dir ein 'Fenster' in den µC zu schaffen, durch welches du deinem µC möglichst gut bei der Arbeit zusehen kannst.
Schau mal nach ob deine Arbeitsvariable zum berechnen der XOR Prüfsumme jedes mal zu Anfang der Berechnung richtig initialisiert wird (0 oder der Startwert deiner Wahl). Oder ist einer der verwendeten Variablen mit static deklariert? Verwendet der Compiler evtl. die Arbeitsvariable noch in einem anderen Zusammenhang -> volatile ? Ohne Quellcode kann ich auch nur raten...
> Ohne Quellcode kann ich auch nur raten...
Dito.
Was bei mir immer gerne passiert ;-) :
Bei einem Rotierbefehl RLC/RRC ist vorher das Carry nicht richtig
gesetzt....und je nach Aktivitaeten im Interrupt kann's auch mal falsch
sitzen ;-)
Generell stimuliert es die Motivation von Mitlesern mehr, eine sinnvolle
Antwort zu suchen, wenn der Fragesteller mehr Informationen gibt.
Angefangen vom tollen (?) Titel "Brauche Hilfe", "Tipps gesucht", "Was
ist der Fehler" bis zur Beschreibung der Randbedingungen:
Du schreibst nur, was nicht geht, und fragst was Du machen sollst,
schreibst aber nicht was Du ueberhaupt machen KANNST!
Keine Info ob ein SW-Simulator vorliegt, ob Du einen Emulator hast......
Im Simulator wuerde ich alle moeglichen Eingangswerte von 0 bis FFFF (?)
mal stimulieren und sehen, ob Werteabhaengig was passiert,
Wenn's das nicht ist, im Emulator mal die Uebertragungen freischalten,
aber als Werte immernoch die Defaultdaten benutzen um zu sehen, obdurch
die Kommunikation selber etwas passiert.....
vielleicht liegt der Fehler also wirklich in Zeile 42!
gruss
Michael
Ich weis dass ich den Titel etwas unglücklich gewählt habe. Ach etwas Quellcode schadet normalerweise nicht. Aber es ging mir um generelle Vorgehensweisen um den Fehler einzugrenzen. Karl heinz Buchegger schrieb: > Darauf würde ich nicht wetten. > Seltsame Fehler, die völlig unerklärlich sind, haben meistens ihren > Ursprung in einem Fehler ganz wo anders. Genau so wahr's. Ich bin alle Dateien Zeile für Zeile durchgegangen und habe genau überlegt ob die Vorgehensweise stimmt. Ich habbe alle möglichen Werte durchprobiert. (Alle Kombinationen habe ich nicht durchprobiert, da es einfach zu lange gedauert hätte. Ich habe aber eine Stunde lang den Zufallsgenerator Kombinationen ausspucken lassen.) Aber bis auf einige Optimierungsmöglichkeiten habe ich nichts gefunden. @Michael Bei diesem Fehler hätte es nichts gebracht den Quellcode des Projekts zu schicken. Der Fehler war übrigens in der Zeile 136. Der Fehler war übrigens fieserweise nicht im eigentlichen Projekt, sondern im Programm das die Ausgaben des Projekts auf Richtigkeit überprüft.
Bernhard schrieb: > Der Fehler war übrigens fieserweise nicht im eigentlichen Projekt, > sondern im Programm das die Ausgaben des Projekts auf Richtigkeit > überprüft. Wie gesagt - Mark Brandis schrieb: > -Debugger benutzen, Breakpoint setzen und die Funktion auf der > Zielplattform Schritt für Schritt durchsteppen, notfalls hier mit > Testarrays als Eingabe arbeiten weil man die Daten ja dann nicht in > Echtzeit (über irgendeine Schnittstelle) bekommt Für einen einzelnen Zyklus (oder wenige Zyklen) kann/soll man das durchaus mal von Hand prüfen. Und dann sieht man ja, dass auf dem Zielsystem das richtige Ergebnis herauskommt, und kann bei einer Diskrepanz zur Prüfsoftware diese sogleich in Gewahrsam nehmen.
Mark Brandis schrieb: > Für einen einzelnen Zyklus (oder wenige Zyklen) kann/soll man das > durchaus mal von Hand prüfen. Und dann sieht man ja, dass auf dem > Zielsystem das richtige Ergebnis herauskommt, und kann bei einer > Diskrepanz zur Prüfsoftware diese sogleich in Gewahrsam nehmen. Wie ich schon geschrieben habe, hat sich der Fehler bei manuellem Prüfen nicht gezeigt. Er ist nur beim normalen Programmablauf aufgetreten.
Bernhard schrieb: > Der Fehler war übrigens fieserweise nicht im eigentlichen Projekt, > sondern im Programm das die Ausgaben des Projekts auf Richtigkeit > überprüft. Dann ist dieses Programmnichts wert, wenn es dir im Fehlerfall nicht gestattet den (seiner Meinung) nach fehlerhaften Fall nachzuvollziehen. Soweit nachzuvollziehen, dass du aus diesem Prüfprogramm die notwendigen Input Daten erhältst, mit denen du die Berechnung kontrollieren kannst.
Michael Roek-ramirez schrieb: > Bei einem Rotierbefehl RLC/RRC ist vorher das Carry nicht richtig > gesetzt....und je nach Aktivitaeten im Interrupt kann's auch mal falsch > sitzen ;-) Dann ist aber der Interrupthandler auch noch defekt. Wenn der Handler das flag verändert, muss er dafür sorgen, dass es wieder zurückgesetzt wird. Oder was passiert hier: CLC <-- Interrupt RLC RRC ...
Karl heinz Buchegger schrieb: > Dann ist dieses Programmnichts wert, wenn es dir im Fehlerfall nicht > gestattet den (seiner Meinung) nach fehlerhaften Fall nachzuvollziehen. > Soweit nachzuvollziehen, dass du aus diesem Prüfprogramm die notwendigen > Input Daten erhältst, mit denen du die Berechnung kontrollieren kannst. Jepp Der Fehler war da nicht in der Fehleranalyse selbst, sondern in der Datenerfassung. Und wenn die erfassten Daten fehlerhaft sind, kann man die Daten noch so oft händisch nachrechnen und auf pausibilität überprüfen. Dass Ergebnis stimmt immer mit dem Analyseprogramm überein. (Außer man verrechnet sich.) Desswegen habe ich ja auch so lange an der falschen Stelle nach dem Fehler gesucht. Aber jetzt Schwamm drüber über die ganze Sache.
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.