mikrocontroller.net

Forum: Compiler & IDEs Brauche Tipps zum Eingrenzen eines Fehlers


Autor: Bernhard (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Floh (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Mark Brandis (markbrandis)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Bernhard (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: sunburner (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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...

Autor: Michael Roek (mexman) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 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

Autor: Bernhard (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Mark Brandis (markbrandis)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Bernhard (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Michael Buesch (mb_)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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
...

Autor: Bernhard (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.