Forum: Mikrocontroller und Digitale Elektronik STM32 - Temperaturproblem >> Absturz


von Markus M. (Firma: EleLa - www.elela.de) (mmvisual)


Lesenswert?

Hallo,

Ich habe einen STM32F103ZET6.
Da ist viel Code drin und neuerdings Stürzt der Prozessor bei "leichter" 
Erwärmung ab. (ca. 50..60°C)

Ich habe nun die Aufgabe bekommen, das näher zu analysieren und habe 
auch die Stelle gefunden:
1
return((UINT16)((tempCount32+2) >> 2));

Wenn das so programmiert wird, geht es ohne Absturz:
1
return((UINT16)((tempCount32+2) / 4));//>> 2));

Also mit der 2. Variante muss ich mit dem Fön wirklich lange drauf, 
halten und wenn der dann schon glüht stürzt der ab, aber die erste 
stürzt wirklich bei leichter Erwärmung ab.

Es war einiges an Arbeit die ganzen Datensicherungen durch zu ackern und 
dann jedes mal die vielen C/H Dateien zu vergleichen.

Hat jemand eine Idee wieso der abstürzt?

- Reproduzierbar an mindestens 5 Boards
- Mit Mehreren Rechner kompiliert und geladen
- An unterschiedlichen Tagen, also der Mond ist es nicht.

PS: Im Reset-Register "RCC->CSR" steht dann in den oberen 8 Bit 0x14, 
also SW-Reset, kein WDG oder IWDG.

Grüße Markus.

von Roland H. (batchman)


Lesenswert?

Welcher Compiler kommt zum Einsatz? Welche Optimierungsstufe?
Welcher Temperaturbereich ist für CPU spezifiziert?
Wie sieht das Assembler-Listing dieser Funktion aus?

Es gibt also einen Unterschied zwischen >> 2 und / 4. Da sollte die 
letzere Variante doch eigentlich "länger" sein (mehr Code, längere 
Ausführungszeit).

Vielleicht ist die längere Ausführungszeit "besser" für das restliche 
Programm, also vielleicht ein anderer Seiteneffekt als die Temperatur ?

Nachtrag: Wie kommt man eigentlich darauf >> 2 durch / 4 zu ersetzen? 
Ein / 4 sollte ja eigentlich eh der Compiler zu einem >> 2 optimieren?

von Roland H. (batchman)


Lesenswert?

Markus Müller schrieb:
> PS: Im Reset-Register "RCC->CSR" steht dann in den oberen 8 Bit 0x14,
> also SW-Reset, kein WDG oder IWDG.

Welcher "fault" tritt denn genau auf?

von Markus M. (Firma: EleLa - www.elela.de) (mmvisual)


Lesenswert?

Coudesourcery Arm-None-Eabi, -O1
Temperaturbereich T6

Nun das Listing:

Wenn ich den funktionierenden Code übersetzte, stürzt der nicht ab.

Wenn ich exakt den gleichen Code nehme und im Makefile:
1
-Wa,-ahlms=$(addprefix $(OBJDIR), $(<:.c=.lst))
hinzufüge, dann stürzt der ab bei Erwärmung.

Somit kann ich kein Listing ausgeben um einen Unterschied zu sehen 
geht/geht nicht :-(


>Welcher "fault" tritt denn genau auf?
Reset. Der Prozessor startet neu.

Es gibt zwar im Code solche Stellen:
SCB->AIRCR = 0x05FA0001;
Die werden aber garantiert nicht abgearbeitet und ich habe die auch 
schon alle auskommentiert. (Braucht es wegen implementierten Bootloader)

von Floh (Gast)


Lesenswert?

tempCount ist was für ein Datentyp?

von Markus M. (Firma: EleLa - www.elela.de) (mmvisual)


Lesenswert?

u32

von Markus M. (Firma: EleLa - www.elela.de) (mmvisual)


Lesenswert?

Jetzt wollte ich das Disassemby unter Eclipse an schauen.
Nun ja, die Routine wird gar nicht durchlaufen. !!?!?!
(Das Projekt hab ich nicht programmiert)

von Robert T. (robertteufel)


Lesenswert?

Markus Müller schrieb:
> Hallo,
>
> Ich habe einen STM32F103ZET6.
> Da ist viel Code drin und neuerdings Stürzt der Prozessor bei "leichter"
> Erwärmung ab. (ca. 50..60°C)
>
> Ich habe nun die Aufgabe bekommen, das näher zu analysieren und habe
> auch die Stelle gefunden:

schschsch....oene Aufgabe ;-)

>
>
1
return((UINT16)((tempCount32+2) >> 2));
>
> Wenn das so programmiert wird, geht es ohne Absturz:
>
1
return((UINT16)((tempCount32+2) / 4));//>> 2));

Du wirst Dir sicher anschauen was die unterschiedlichen Uebersetzungen 
in ASM sind. Oft ist es nicht der Unterschied im Coding sonder wo das 
Programm dann zu liegen kommt. Falls also der DIV 4  anders uebersetzt 
wird vom Compiler als mit shift right, (dann ist es kein guter Compiler) 
aber andererseits kannste dann mal versuchen den shift mit NOPs zu 
ergaenzen, so dass die Laenge des Befehles in ASM gleich wird. Ich hoffe 
das ist klar was ich demit meine.
Falls dem so ist, dann verschiebt sich einfach ein Teil des Codes in 
"eine unguenstige Stelle". Ursache sind dann meist nicht initialisierte 
Pointer.
Die Temperaturabhaengigkeit ist allerdings merkwuerdig.
Wird ein interner Oszilator irgendwo beuetzt? Die sind manchmal stark 
temperaturabhaengig. Wird das Ergebnis einer ADC Wandlung fuer eine 
Verzweigung benutzt? ADC kann auch etwas schwanken mit Temp. Oder hat 
der Chip einen internen Temperatursensor, der als Bedingung fuer 
Verzweigungen verwendet wird?

Einfach mal so ein paar Gedanken, was temp abhaengig sein kann. Alles 
analoge, z.B. ein Comperator kann auch temp abhaengig sein.

Wie sieht's denn aus mit dem Frequenz? Ich nehme mal an im gruenen 
Bereich und kein Uebertakten?

Kannst Du mal im Linker eine Reihenfolge der Funktionen angeben, damit 
der Code woanders zu liegen kommt? Das aendert das Verhalten solcher 
Nadeln im Heuhaufen auch manchmal.

Jetzt faellt mir gerade nichts mehr ein. Sorry fuer die etwas konfuse 
Aneinanderreihung der Vorschlaege. Hab mich nur gemeldet weil Du oft 
gute Beitraege lieferst und Input verdient hast.

Gruss, Robert

von Arne (Gast)


Lesenswert?

Hast Du es mal mit einem anderen Exemplar eines STM32F103ZET6 probiert?
Gibt auch Produktionsfehler. Hatte mal von einem 68000 gelesen, der bei 
bestimmten ASM Befehlen abgeschmiert ist.
> Falls also der DIV 4  anders uebersetzt wird vom Compiler als mit shift
> right, (dann ist es kein guter Compiler)
Sehe ich genauso.

Ansonsten ist das wohl ein Fall für ST selbst.

von Ralf (Gast)


Lesenswert?

Hallo Markus,

Robert Teufel schrieb:
> Oder hat
>
> der Chip einen internen Temperatursensor, der als Bedingung fuer
>
> Verzweigungen verwendet wird?

Nutzt Du den internen Temperatursensor im ADC?

Hast Du in deinem Code die Flash Waitstates entsprechend der 
Taktfrequenz richtig eingestellt? Wenn die Waitstates fehlen könnte es 
sein, dass bestimmte Flashbereiche über den Temperaturbereich 
unterschiedlich reagieren.

Hast Du eine möglichkeit zu tracen?

Gruß,
Ralf

von Marko ⚠. (mos6502) Benutzerseite Flattr this


Lesenswert?

Roland H. schrieb:
> Seiteneffekt

Biddewas?

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

1
Letzteres wird "Nebenwirkung", häufig auch "Nebeneffekt" genannt. 
2
Auch die Bezeichnung "Seiteneffekt", eine falsche Rückübersetzung 
3
des englischen "side effect", ist weit verbreitet.
aus http://de.wikipedia.org/wiki/Wirkung_%28Informatik%29

von Markus M. (Firma: EleLa - www.elela.de) (mmvisual)


Lesenswert?

@Robert, vielen Dank, Antwort dazwischen

Robert Teufel schrieb:
> Du wirst Dir sicher anschauen was die unterschiedlichen Uebersetzungen
> in ASM sind. Oft ist es nicht der Unterschied im Coding sonder wo das
> Programm dann zu liegen kommt. Falls also der DIV 4  anders uebersetzt
> wird vom Compiler als mit shift right, (dann ist es kein guter Compiler)
> aber andererseits kannste dann mal versuchen den shift mit NOPs zu
> ergaenzen, so dass die Laenge des Befehles in ASM gleich wird. Ich hoffe
> das ist klar was ich demit meine.

Ja, ich habe das Listing an geschaut, der Compiller macht in beiden 
Fällen das gleiche, auch die HEX-Datei ist bei beiden Fällen exakt 
gleich.

> Falls dem so ist, dann verschiebt sich einfach ein Teil des Codes in
> "eine unguenstige Stelle". Ursache sind dann meist nicht initialisierte
> Pointer.

Bei einem nicht initialisierten Pointer springt der in den Hard-Fault 
Interrupt und bleibt darin stecken, der macht aber einen Reset.
Ich sehe grad, dort steht nicht mehr das while(1); sondern ein 
NVIC_SystemReset();
Jetzt weiß ich wenigstens woher noch ein SW-Reset kommt ;-)

> Die Temperaturabhaengigkeit ist allerdings merkwuerdig.
> Wird ein interner Oszilator irgendwo beuetzt? Die sind manchmal stark
> temperaturabhaengig.

Da ist ein Quarz drauf. Wenn ich auch mit der alten SW das Board laufen 
lasse, dann kann ich den zum glühen föhnen und die serielle Ausgabe ist 
ohne Fehlerzeichen, somit sollte die Frequenz einigermaßen Konstant 
sein.

> Wird das Ergebnis einer ADC Wandlung fuer eine
> Verzweigung benutzt? ADC kann auch etwas schwanken mit Temp. Oder hat
> der Chip einen internen Temperatursensor, der als Bedingung fuer
> Verzweigungen verwendet wird?
> Einfach mal so ein paar Gedanken, was temp abhaengig sein kann. Alles
> analoge, z.B. ein Comperator kann auch temp abhaengig sein.

Der interne Temp-Sensor ist inaktiv. Ansonsten sind ein paar Kanäle 
verwendet. Ich muss die Berechnungen mal alle durch gehen.

> Wie sieht's denn aus mit dem Frequenz? Ich nehme mal an im gruenen
> Bereich und kein Uebertakten?

Nein natürlich nicht übertaktet.

> Kannst Du mal im Linker eine Reihenfolge der Funktionen angeben, damit
> der Code woanders zu liegen kommt? Das aendert das Verhalten solcher
> Nadeln im Heuhaufen auch manchmal.

Dazu muss ich nur die Reihelfolge der C-Dateien im Makefile ändern, 
probiere ich mal.

> Jetzt faellt mir gerade nichts mehr ein. Sorry fuer die etwas konfuse
> Aneinanderreihung der Vorschlaege. Hab mich nur gemeldet weil Du oft
> gute Beitraege lieferst und Input verdient hast.
>
> Gruss, Robert


Arne schrieb:
> Hast Du es mal mit einem anderen Exemplar eines STM32F103ZET6 probiert?
> Gibt auch Produktionsfehler. Hatte mal von einem 68000 gelesen, der bei
> bestimmten ASM Befehlen abgeschmiert ist.
>> Falls also der DIV 4  anders uebersetzt wird vom Compiler als mit shift
>> right, (dann ist es kein guter Compiler)
> Sehe ich genauso.
>
> Ansonsten ist das wohl ein Fall für ST selbst.

Ich habe bei denen im Forum auch mal geschrieben.
Ich hatte schon mal ein Fehler wegen einem Chip der 384KB Flash haben 
sollte aber der nur 256 drin hatte. Aber dieser Chip hat garantiert mehr 
als 256KB, denn sonst würde das Programm nicht rein passen.

In jedem Fall gehe ich all eure Hinweise Stück für Stück durch. Ich 
bastle mir da jetzt auch eine Stack-Aufzeichnung rein mit der ich jeden 
Funktionsaufruf in eine Variable merke. Somit habe ich einen echten 
Trace, das hat mir schon manchmal geholfen.

von Markus M. (Firma: EleLa - www.elela.de) (mmvisual)


Lesenswert?

Ralf schrieb:
> Hast Du in deinem Code die Flash Waitstates entsprechend der
> Taktfrequenz richtig eingestellt? Wenn die Waitstates fehlen könnte es
> sein, dass bestimmte Flashbereiche über den Temperaturbereich
> unterschiedlich reagieren.
>
> Hast Du eine möglichkeit zu tracen?
>
> Gruß,
> Ralf

Schaue ich auch gleich an.

Einen Trace muss ich erst noch ein proggen, dauert ein wenig da ich das 
in jede Routine rein machen muss.

von Ralf (Gast)


Lesenswert?

Hallo Markus,

ich dachte eher an einen Debugger mit Trace Funktion wenn Du einen hast.

Ansonsten kannst Du ja jetzt in deinen HardFault Handler einen 
Breakpoint setzen und dann über den Stack Trace nachsehen aus welcher 
Funktion die Software zum HardFault gesprungen ist.

Was allerdings komisch ist, ist der identische Code. Wenn beide Code 
Zeilen zum identischen Ergebnis führen kann das eigentlich nicht die 
Ursache sein. Gibt es vielleicht Unterschiede in deinen Option Byte 
Settings? (bin mir gerade nicht sicher was da alles drin steht)

Gruß,
Ralf

von Peter D. (peda)


Lesenswert?

Temperaturabhängigkeit dürfte ein Flashtiming Problem sein.
Kann aber auch durch eine instabile PLL entstehen.

Die Codeabhängigkeit ist typisch für kritisches Timing, da der Code mal 
zufällig auf langsamen Flashzellen landet und mal nicht.

Abhilfe, das Flashtiming runter setzen (mehr Waits) und Code, der 
schnell sein muß, in den RAM kopieren.

Um Quarzprobleme auszuschließen, erstmal einen Quarzoszillator 
anschließen.
Und auch mal mit den VCCs rumspielen, obs davon abhängig ist.


Peter

von Markus M. (Firma: EleLa - www.elela.de) (mmvisual)


Lesenswert?

Einen Debugger mit Trace Funktion hab ich nicht.
Ich mache das etwas anders. In jedem Funktionsaufruf mache ich ein
SAVE_SP() mit rein, damit wird der aktuelle Adresszeiger in einem 
Ringbuffer gesichert (u32 Array[16]).
Um noch andere Infos zu sichern, mache ich dazwischen SAVE_U32(x).

Jetzt springt der in den Fault-Interrupt und darin gebe ich auf dem UART 
die gespeicherten Zahlen aus:
1
HardFault Exception! STOP.
2
Stack:
3
 0  0000CE90
4
 1  00000001
5
 2  00000003
6
 3  0000EC9C
7
 4  0001080C
8
 5  000108C4
9
 6  0000ED08
10
 7  000105C0
11
 8  00012934
12
 9  00006C16
13
10  0000C6AE
14
11  0000C36A
15
12  00000001
16
13  00009CF2
17
14  000087B2 <
18
15  00025B92

das nächste mal so:
1
HardFault Exception! STOP.
2
Stack:
3
 0  00007086
4
 1  00007086
5
 2  00027B7C
6
 3  00027AD6 <
7
 4  00007086
8
 5  00007086
9
 6  00027B7C
10
 7  00027AD6
11
 8  00006E4E
12
 9  00008242
13
10  00007086
14
11  00007086
15
12  00027B7C
16
13  00027AD6
17
14  00006E4E
18
15  00008242

Der "<" zeigt die letzte Schreib-Position im Ringbuffer.
Nachteil: Wenn der Prozi ganz tot ist geht das natürlich nicht, aber in 
der Regel ist ja nicht das ganze Flash/Ram defekt und die seriellen 
Routinen sollten noch tun. Vorteil: geht auch beim Kunde und ohne 
Debugger.

Nun schaue ich nach der Routine bei 00027AD6 und mache da eine weitere 
Debug-Info rein, das nächste mal stürzt der bei einer ganz anderen 
Routine bei 00009DD6 ab, also in einer kleineren Flash-Adresse.

Der Flash war auf FLASH_Latency_1 eingestellt, ist lt. Doku für 48MHz 
auch gut so. Dennoch hab ich mal 2 eingestellt um diese Probleme auch zu 
umgehen, falls es eines geben sollte.

Aber der stürzt immer noch ab.

Mit einem alten Code war FLASH_Latency_1 eingestellt und der ist nicht 
abgestürzt.
Auch ohne Debugger stürzt der ab.

Langsam gehen mir die Ideen aus.

von Markus M. (Firma: EleLa - www.elela.de) (mmvisual)


Lesenswert?

Einen Stack-Überlauf gibt es auch nicht, der hat noch genügend Reserve.

Kompilieren mit -O0 / -O1 macht kein Unterschied.

von Lutz (Gast)


Lesenswert?

Markus Müller schrieb:
> return((UINT16)((tempCount32+2) / 4));//>> 2));

Probier mal die erste öffnenden Klammer wegzulassen. Vielleicht bringt's 
was.

von Lutz (Gast)


Lesenswert?

Markus Müller schrieb:
> Ja, ich habe das Listing an geschaut, der Compiller macht in beiden
> Fällen das gleiche, auch die HEX-Datei ist bei beiden Fällen exakt
> gleich.

Übersehen ...

von Roland H. (batchman)


Lesenswert?

Markus Müller schrieb:
> Bei einem nicht initialisierten Pointer springt der in den Hard-Fault
> Interrupt und bleibt darin stecken, der macht aber einen Reset.
> Ich sehe grad, dort steht nicht mehr das while(1); sondern ein
> NVIC_SystemReset();
> Jetzt weiß ich wenigstens woher noch ein SW-Reset kommt ;-)

Ein Rätsel gelöst.

Ralf schrieb:
> Ansonsten kannst Du ja jetzt in deinen HardFault Handler einen
> Breakpoint setzen und dann über den Stack Trace nachsehen aus welcher
> Funktion die Software zum HardFault gesprungen ist.

Hinter einem "hard fault" können sich ja andere "faults" verstecken, 
wenn man die Eskalation nicht ausschaltet.

Die Frage ist also: Welcher "fault" steckt wirklich dahinter?

Und wie schon Ralf geschrieben hat, lässt sich die Stelle herausfinden.

Dann ist die Frage, ob es immer die gleiche Stelle ist.

Ich hatte schon einmal mit einem ähnlichen Problem zu kämpfen. Ursache 
war dann, dass das Flash-Utility einen Fehler hatte und den Flash 
unvollständig beschrieben hat. Geringste Abweichungen im Code waren dann 
der Unterschied zwischen "geht" und "geht nicht".

Also auch mal das Flash an der Stelle auslesen.

von Markus M. (Firma: EleLa - www.elela.de) (mmvisual)


Lesenswert?

Ich habe im Bootloader noch einen Zahlendreher gefunden:
1
// Flash-Zugriff vor Takterhoehung festlegen
2
FLASH->ACR &= 0x31; // Flash Latency 1 (bis 48 MHz)
3
FLASH->ACR |= 0x10; // Flash Prefetch Buffer EIN

Morgen testen wir noch weiter ob es wirklich nur daran lag.

In der Applikation würde zwar Latency 1 gesetzt werden, aber da der 
Bootloader die USB Verbindung initialisiert darf die Applikation die 
Taktfrequenz nicht mehr ändern. Sonst klappt das nicht mehr mit dem 
"übernehmen" der USB Verbindung Bootloader <> Applikation.

Somit: Problem erst mal gelöst, wenn nicht schreibe ich morgen nochmals.

Vielen Dank für die Tipps.

von Arne (Gast)


Lesenswert?

> Ich habe im Bootloader noch einen Zahlendreher gefunden
Genau deswegen nimmt man auch benamte Konstanten und bastelt sich den 
Zielwert zusammen. So muss man immer das Datenblatt parat haben.

von Markus M. (Firma: EleLa - www.elela.de) (mmvisual)


Lesenswert?

Normalerweise wird auch alles mit der STM Library gemacht. Dann hat man 
diese Probleme automatisch nicht.
Aber der Bootloader darf diesen Code  leider nicht nutzen, da bei einem 
Update der Applikation der Flash gelöscht wird.
Bootloader und App sind in den gleichen Sourcen.

von Arne (Gast)


Lesenswert?

Schlechte Ausrede ;)
Ich nehm nie die STM Lib - trotzdem habe ich überall benamte Konstanten.

von Lutz (Gast)


Lesenswert?

Markus Müller schrieb:
> Ja, ich habe das Listing an geschaut, der Compiller macht in beiden
> Fällen das gleiche, auch die HEX-Datei ist bei beiden Fällen exakt
> gleich.

Markus Müller schrieb:
> Ich habe im Bootloader noch einen Zahlendreher gefunden:

Das kann der Bootloader nichts mit zu tun haben. Wenn alles inkl. 
HEX-Datei gleich ist (btw: Wie festgestellt? MD5 o.ä.?), kann es ja nur 
noch etwas Externes sein, wie z.B. Versorgungsspannung oder EMV.

von Markus M. (Firma: EleLa - www.elela.de) (mmvisual)


Lesenswert?

Doch das war es. Problem ist gelöst und es wurden mehrere Bords jetzt im 
Dauer-Stresstest richtig geprüft.

von Lutz (Gast)


Lesenswert?

???
Das verstehe ich nicht. Wenn wirklich alles inkl. der HEX-Datei gleich 
ist, wie kann dann

Markus Müller schrieb:
> return((UINT16)((tempCount32+2) >> 2));
> Wenn das so programmiert wird, geht es ohne Absturz:
> return((UINT16) ((tempCount32+2) / 4));//>> 2));

die Ursache dafür sein, daß der Chip abschmiert? Bei gleicher HEX-Datei 
besteht doch gar keine Möglichkeit für den Chip "herauszufinden", welche 
der beiden Codeformen zur gleichen HEX-Datei geführt hat. Entweder hat 
das esoterische Züge oder ich habe bisher einen großen Verständnisfehler 
gehabt (was ich nicht unbedingt ausschließen will).

von Markus M. (Firma: EleLa - www.elela.de) (mmvisual)


Lesenswert?

Wenn man den Flash Latency falsch einstellt und man bewegt sich im 
Grenzbereich, dann macht das Flash je nach Temperatur was falsches oder 
auch doch nicht.

"esoterische Züge" hatte ich nach 2 Tagen auch vermutet.

Wenn also jemand auf Nummer Sicher gehen will/muss, dass besser eine 
Flash Latency Stufe höher bzw. kleinere Frequenz einstellen.

Beim STM32F4xx hat man da noch mehr Möglichkeiten. Da ist auch die Flash 
Latency Zahl abhängig von Taktfrequenz UND Betriebsspannung.

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
Noch kein Account? Hier anmelden.