Forum: Mikrocontroller und Digitale Elektronik Problemlösungs-Tipp: STM32 friert nach Flashen ein bei Nutzung des Stop/Standby-Modus


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Falls noch jemand anders bei so einem Problem graue Haare bekommt:

System: Ein neuerer UltraLowPower-STM32, also L-Reihe, U-Reihe oder 
WL-Reihe.

Auslöser: Ein Stop- oder Standby-Modus wird genutzt.

Symptom: Nach dem Debuggen/Flashen mittels Debugger friert das Programm 
ein. Auch ein Reset per NRST-Eingang/Button löst das nicht, das Programm 
bleibt stehen. Nur die Spannungsversorgung zu trennen lässt das Programm 
korrekt durchlaufen.

Bei Verwendung eines RTOS, welches in der Initialisierung vor der 
main()-Funktion schon temporär den Stop/Standby-Modus nutzt, wird die 
main() eventuell gar nicht erst aufgerufen.

Wichtiges Detail: Beim Betreten des Stop/Standby-Modus verliert der 
Debugger die Verbindung, aber das Programm scheint zumindest ein Stück 
weit weiter zu laufen. Ohne Debugger kann man aber nicht herausfinden wo 
es stehen bleibt...

Der Grund ist so blöde wie unerwartet:
Der Debugger setzt beim Starten (nach dem Flashen) einen Breakpoint in 
der main() und/oder woanders. Wenn der STM32 in den Stop/Standby geht 
und die Verbindung zum Debugger getrennt wird, bleibt der Breakpoint 
erhalten, und das Programm bleibt genau dort stehen, aber kann nicht 
mehr fortgesetzt werden. Dieser Breakpoint bleibt auch nach einem Reset 
per NRST-Pin erhalten, nur ein Power-Cycle löscht ihn.

Die Lösung:
Man kann den Debugger in Sleep/Stop/Standby am Leben erhalten indem man 
beim Start einmal
1
// Prüfe ob Debugger aktiv ist (dieses Bit überlebt den Reset per NRST):
2
if (CoreDebug->DHCSR & CoreDebug_DHCSR_C_DEBUGEN_Msk) {
3
  // Debugger auch im Sleep/Stop/Standby aktiv lassen
4
  DBGMCU->CR = DBGMCU_CR_DBG_STANDBY | DBGMCU_CR_DBG_STOP | DBGMCU_CR_DBG_SLEEP;
5
}
macht. Bei Verwendung eines RTOS muss man aufpassen, dass dies früh in 
der Initialisierung vor dem ersten Stop/Standby gemacht wird, weil bei 
der Initialisierung von Treibern bereits der Stop/Standby betreten 
werden könnte wenn dort ein Delay-Aufruf gemacht wird.

Dann tritt das Problem nicht mehr auf - allerdings muss man erstmal 
drauf kommen, dass das unsaubere Trennen des Debuggers wirklich die 
Problemursache ist. Das hatte ich zuerst als unwichtigen Seiteneffekt 
abgetan. Ich hatte diese Bits im DBGMCU_CR-Register schon früh bei der 
Suche gesetzt und festgestellt dass es dann funktioniert, dachte aber, 
dass durch das Setzen dieser Bits vielleicht noch irgendwelche anderen 
Teile des Prozessors (Takt, Power domains) erhalten bleiben welche das 
Verhalten im Standby/Stop-Modus irgendwie beeinflussen und nur ein 
Symptom beheben, aber tatsächlich noch irgendwo ein Software-Fehler 
besteht. Insbesondere auch, weil ich vorher schon über diverse andere 
Bugs im Zusammenhang mit dem Stop-Mode im RTOS gestolpert bin, die sich 
sehr ähnlich äußerten.

Und weil man ja im Produktivbetrieb diese Bits nicht setzen möchte um 
möglichst viel Strom zu sparen, soll es ja auch ohne diese funktionieren 
- aber woher will man wissen, dass es dann auch garantiert funktioniert 
(und die Bits nicht nur ein Symptom eines tieferlegenden Problems 
maskieren) - man kann es ja so nicht debuggen. Man muss aber erstmal 
drauf kommen dass es ohne diese Bits im Produktivbetrieb natürlich gar 
kein Problem gibt, weil ja nie ein Debugger dran ist, und somit o.g. 
Code auch immer drin bleiben kann.

Also ein lustiges Verwirrspiel: Die vermeintliche Symptombekämpfung 
behebt tatsächlich das eigentliche Problem, und es gibt kein 
tieferlegendes Problem. Sonst ist es immer anders rum! Drauf gekommen 
bin ich erst als ich (mehr aus Verzweiflung als aus Methode) vor der 
main() - und somit vor dem ersten Breakpoint - noch weitere Breakpoints 
gesetzt hatte, und sich das Verhalten des Programms änderte obwohl der 
Debugger ja getrennt wurde, was erst durch Power-Cycle "repariert" 
wurde...

: Bearbeitet durch User
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.