PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : PIC absturz



*Mario*
26.01.2006, 16:12
Hallo,

ich habe für den PIC ein ziemlich langes Programm entwickelt. Nun habe ich das Problem, dass das Programm sich einwandfrei in MPLAB simulieren läßt. In der Schaltung selbst, stürzt es nach eine zufälligen Zeit innerhalb von wenigen Sekunden ab.
Ich habe nun sämtliche mögliche Ursachen geprüft: PORT-pins, Interrupts (nur TIMER1 ist aktiv), Programmierfehler, Page-Fehler, RAM-Page Fehler.
Dabei habe ich festgestellt, das bei disable von interrupts (Timer1 interrupt) in einem bestimmten Teil des Programmes, keine Abstürze mehr auftreten. Der besagte Teil ist eine Schleife, die SPI-Daten ausgibt. Der Schleifenzähler wird aber nicht durch Code im Interrupt überschrieben.
Ersetze ich die SPI-Ausgabe durch Serielle Ausgabe, funktionierts wieder, auch mit überall erlaubten Interrupts und sonst keiner Programmänderung.
Hatte schon mal jemand selbiges Problem? Gibts da ein SPI/Interrupt Problem?
Der benutzte PIC ist ein 16LF876. Im Errata dazu konnte ich keinen PIC-Fehler finden.

Ich wäre euch für Tipps wo ich noch nach Fehlern suchen könnte sehr dankbar.

Danke!

stegr
27.01.2006, 01:34
Poste doch mal bitte deinen Quelltext - so zu raten ist immer etwas mühsam ;)

MfG
Stefan

Bernhard_
27.01.2006, 08:15
Hallo Mario,

ein solches Problem ist in einem Forum sicherlich schlecht lösbar. Dass du deinen Quelltext hier nicht posten möchtest kann ich verstehen. In diesem Fall hat jedoch stegr vollkommen recht, so kann dir niemand wirklich helfen.

Meine Glaskugel sagt mir aber, dass du ein Stack-Problem hast. Um das herauszubekommen musst du deinen Stackbedarf entweder berechnen, oder dir eine Funktion schreiben, die sich bei einem Stacküberlauf meldet.

Viele Grüße,
Bernhard

*Mario*
27.01.2006, 18:44
Hallo Stefan, Bernhard,

danke erst mal für Eure Antworten. Ich habe bewusst versucht erst mal nicht den Quelcode hier reinzustellen. Bei dem Umfang kann ich nicht erwarten, dass ich eine Antwort kriege (>3000 Zeilen, alles ASM, kaum Kommentare). Ich werde aber versuchen die relevanten Teile herauszunehmen und eine Kurzform bereitzustellen.

Bernhard: Ja das habe ich mir auch schon gedacht, die Stack-Tiefe sollte 8 Ebenen sein. Bei mir waren es fünf. Die interrupt Routine brauchte drei Ebenen, daher habe ich Sie auf zwei ebenen abgeflacht. Ich komm jetzt mit vier Ebenen aus.

Wie gesagt, das austauschen von SPI-senden durch Serial-Ausgabe reicht um das Problem zu lösen.

Ich vermute daher einen PIC-Fehler mit Interrupts in Verbindung mit SPI.
Um das allerdings zu verifizieren, müsste ich den Code zusammenstutzen, sodaß der Fehler nach wie vor auftritt.
Wenn ich daran vorbei komme, wäre das eine riesige Hilfe.

Beste Grüße,
Mario

stegr
28.01.2006, 00:10
Auch wenn es eigentlich eine Selbstverständlichkeit ist, erwähne ich es grade nochmal, weil es sich gerne mal als Fehler einschleicht:
Kehrst du aus allen CALLs auch mit RET zurück - oder hast du vielleicht irgendwo ein GOTO drinnen stehen?
Bernhards Idee mit dem Stack-Overflow klingt recht gut - eine der wenigen Möglichkeiten nen PIC abzuschießen - abgesehen von nem Zeigerüberlauf, so dass du bei 0000h landest.
Hast du ein ICD zum debuggen? Damit kannst du auch die Stacktiefe überwachen, wäre hier vielleicht ganz sinnvoll.

Funktioniert wärend der kurzen Zeit denn die SPI-Kommunikation?

MfG
Stefan

kalledom
29.01.2006, 16:20
Hallo Mario,
prüfst Du in der Interrupt-Service-Routine auf, wer den Interrupt ausgelöst hat ?
Rettest und restaurierst Du das W- und Status-Register (evtl. noch weitere) in der ISR ?
Beispiele dazu: http://www.domnick-elektronik.de/picasm.htm unter Interrupt-Service-Routine ISR.

*Mario*
08.03.2006, 22:47
Hallo,

gut ding braucht weile. Nun hab ich es endlich geschafft, den Quelltext auf ein einigermassen überschauberes Schnipsel zusammenzustutzen.

Leider, oder vielleicht auch interessant für euch, ist der Code für die Ansteuerung des S65-Displays aus dem S65 Mobiltelefon, d.h. für den Test nicht ganz so optimal :(.

Nachdem mir die Variante "mal eben schnell einen ICD aufzubauen" doch zu kompliziert war, blieb mir nur das langwierige zusammenschneiden. Also, wenn Ihr die

#define __NO_CRASH

auskommentiert, so kommt Ihr zu einem Code der Abstürzt. Wenn Ihr die
#define drinnen lasst, dann stürzt der Code nicht ab.

Nun mit meinen Versuchen habe ich herausgefunden, dass der Grund für den Absturz ein Interrupt ist, der eigentlich nicht auftauchen dürfte. Der Code verzweigt dann in die Ausgaberoutine for INTCON/PIR1/PIR2/PIE1/PIE2 und endet in der Endlosschleife.

Die Ausgabe auf dem Display ergibt (ohne Muster) folgende
Kombinationen:
PIE1=00000001, PIE2=00000000

INTCON | PIR1 | PIR2
01000100|00001011|00000000
01000101|00001001|00000000
01000000|00001001|00000000
01000001|00001001|00000000 => kommt fast immer bei dem angehängten Code.

Hat von Euch jemand eine Ahnung?
Ober habe ich tatsächlich das glückliche Los gezogen auf einen internen Fehler im PIC gestoßen zu sein :(

Gruß
Mario

*Mario*
08.03.2006, 22:50
Komisch, wo ist das Attachment?

OK, ich habs jetzt nochmals aufgenommen.

gunzelg
10.03.2006, 11:43
Hallo Mario

falls du noch nicht weitergekommen bist: Das muss nicht unbedingt ein Softwarefehler sein. Auch Störungen, wie sie z.B. von Elektromotoren produziert werden, können einen Prozessor oder einen uC zum Absturz bringen. Was hast du denn an dem Dingens angeschlossen ?

Gerhard :-k

*Mario*
10.03.2006, 14:49
Hallo Gerhard,

danke für Deine Antwort. Ja das kann ich mir gut vorstellen. Also, details zur HW:
Ich hab einen 16LF876A an einer Li-Knopfzelle angehängt, mit dabei sind dann noch ein paar Sensoren die Daten liefern. Die kann man allerdings vernachlässigen, d.h. ich habe sämtlichen Code zum auslesen und auswerten und steuern der Sensoren rausgeschmissen, die tun dann eigentlich nichts mehr in der Schaltung - kann ich auch abhängen.

D.h. es verbeibt das S65-Display und der PIC an einer Li-Knopfzelle. Vor jedem der beiden habe ich Abblockkondensatoren gegeben, auch das Reset habe ich entsprechend gesichert. Laufen tut die ganze Schaltung mit 2MHz, also weit im erlaubten Bereich für diese Versorgungsspannung.

Was nun passiert ist, dass ein Interrupt ausgelöst wird, der eigentlich nicht auftreten sollte - genau für diesen Fall habe ich die Ausgabe auf das Display mit einem abschließenden goto $ gemacht. Wenn ich allerdings in einem gewissen Programmteil im Hauptprogramm die Interrupts temporär global verbiete, klappt alles wunderbar.

Für zusätzliches Debugging habe ich noch Port B herangezogen.

Das Attachment ist als zip etwas groß, das liegt daran, dass auch die Projekt Definitionen von MPLAB drinnen sind - sollte also nicht abschrecken :). Das ASM-File selber ist antürlich viel kleiner. Und wen es interessiert, beinhalten die Ansteuerung für das S65 Display, welches in er "elektronischen Bucht" günstig zu haben ist.

Gruß
Mario

gunzelg
10.03.2006, 15:37
Was mir noch einfällt:
- ist der Watchdog abgestellt ?
- und wie ist der Reset beschaltet ?
- sind keine Wackelkontakte vorhanden (mal mit dem Oszi die Stromversorgung kontrolliert ?)

Ich hab ja schon einige Schaltungen mit PICs gemacht, aber noch nie Software-bedingte Abstürze gehabt. Braucht vielleicht das Display zeitweise zu viel Strom, wodurch die Versorgung mit der Batt zusammenbricht ? Schon mal statt der batterie ein Netzteil verwendet ?

Gerhard

andie2302
28.03.2006, 22:49
Hallo!

Könnte es vieleicht sein, dass LOW-Voltage Programmieren eingeschaltet ist
und der PIC nicht wirklich abstürzt, sondern in den Programmiermodus geht, weil eine ausreichend hohe Programmierspannung angelegt wurde?