STM32L431 Grund für Reset herausfinden.

Gast #6015702
Lesenswert?

Hallo Forum,

ich bin STM32 Einsteiger und erstelle mein erstes Projekt.
Zuvor habe ich alle nötigen Module portiert und einige öffentliche 
Quellen genutzt die ich bereits in der AVR Welt eingesetzt habe 
(Scheduler, Tastenentprellung, IRMP, u8g2 Grafik Display Lib etc.).

Entwicklungsumgebung ist Visual GDB in aktueller Version.
HAL, kein RTOS.

Im Projektierungsverlauf führt der STM32 nun sporadisch einen Reset aus.

Ich habe auch bereits einen Code Block ausfindig gemacht. Wenn dieser 
auskommentiert wird, tritt der Fehler nicht auf.
Der Code Block für sich ist aber lauffähig und nicht allein ursächlich 
für den Reset. Der Fehler tritt dann irgendwann später (mal nach 10 
Sekunden, mal nach 3 Minuten) auf.
Letztendlich lösche ich nach abgelaufener Zeit einmalig das Display.
Diese Funktion wird ein dutzend mal an anderen Programmstellen 
aufgerufen.

Ich habe bereits eine Hard Fault Funktion hinzugefügt und einen break 
Point gesetzt. Der BP wird allerdings vorm Reset nicht angesprungen.

Nach google und Forumssuche ist mir nicht klar, wie man hier am besten 
systematisch vorgeht. Ich habe bereits viele Stunden damit verbracht 
auszuschließen und komme nicht weiter.

Ich wäre euch für Unterstütz sehr dankbar.

Gruß
Stefan
Gast #6015724
Lesenswert?

Aufbau der Hardware ist vernünftig?
Stromversorgung stabil?
Eventuell Watchdog aktiviert?

Ich finds geschickter bei der Fehlersuche im Hardfault-Handler oder auch 
bei fehlgeschlagenen asserts direkt einen "bkpt" Befehl auszuführen, das 
verschwendet keine Debug-Resourcen und schlägt immer an.
Gast #6015777
Lesenswert?

Hi,

danke für die Tipps!
Den Stack werde ich gleich mal vergrößern.

Der Hardfault Handler wird vor dem Reset lt. gesetztem Break Point nicht 
aufgerufen.

Die Stromversorgung ist stabil.
Der Controller geht nicht in den Reset wenn der entsprechende Codeblock 
auskommentiert ist.

Fas Problem ist, dass die St Link Schnittstelle auch abschmiert. So kann 
ich kein entsprechendes Register lesen.
Wenn ich dann eine neue Debug Session starte wird das Programm erneut 
übertragen und der Controller gezielt resettet.
Dann ist die die Reset Quelle Soft Reset.

Watchdog und Brown Out nutze ich nicht.


Stefan
Gast #6015783
Lesenswert?

Zum Codeteil der verantwortlich für den Reset ist:

Aufruf 1x pro Sekunde
1
void display_OffTimer(void)
2
{
3
  if (state.displayTime > 0)
4
  {
5
    state.displayTime--;
6

7
    if ((parameter.display.offTime != 0) && (state.displayTime == 0))
8
    {
9
      SET(state.flags, 4);      
10
    }
11
  }
12
  schedule_Remove(display_OffTimer);
13
  schedule_Add(display_OffTimer, SECONDS(1));
14
}

Das flag mit der (testweise) Magic Number wird in der Hauptschleife 
ausgewertet.

1
while(1)
2
{
3

4
if (READ(state.flags, 4))
5
    {
6
      CLR(state.flags, 4);
7
      display_Off(&display, READ(parameter.display.flags, DISP_FLAG_OFFSYMBOL));
8
      
9
    }
10

11
}

- state ist volatile
- parameter.display.offTime ist ein Parameter der nach Init aus einem 
EEPROM gelesen und in einem User Menu editiert und ins EEPROM 
geschrieben wird
- wenn parameter.display.offTime den Wert 0 hat bzw. wenn das Flag nicht 
geschreiben wird oder Display_Off nicht aufgerufen wird, kommt es nicht 
zum Reset.


Vereinfachte Funktion (normalerweise mit Auswertung value, allerdings 
besteht der Fehler auch so)
1
void display_Off(u8g2_t *display, uint8_t value)
2
{
3
  
4
  
5
  u8g2_ClearDisplay(display);
6
  
7
}
#6015988
Lesenswert?

technikus schrieb:
> Der Hardfault Handler wird vor dem Reset lt. gesetztem Break Point nicht
> aufgerufen.

Und der break Point war auf der allerersten Instruktion im Disassembly?

Ich frage das weil ein komplexer Handler gerne mal versucht was auf den 
Stack zu pushen. Was schief geht wenn SP ungültig ist -> Lockup. Lockup 
ist in vielen µC Designs mit Reset verkoppelt.

technikus schrieb:
> Wenn ich dann eine neue Debug Session starte wird das Programm erneut
> übertragen

Dieses Verhalten sollte man abstellen können. Ist bei Eclipse ein Haken 
in der Debug Konfiguration.

technikus schrieb:
> Display_Off nicht aufgerufen wird

Mach da mal einen Haltepunkt rein und schau Dir den display Pointer 
genau an.

Wenn der auf den flaschen Speicherbereich zeigt, kann der durchaus den 
Stack durcheinander bringen. Was zu o.g. Problem mit Fault und kaputten 
Stack Pointer führt...
Gast #6016357
Lesenswert?

Folgendes probiert. Dabugging Option umgestellt damit das Programm nicht 
erneut übertragen wird und folgende Funktion aufgerufen:
1
uint8_t get_system_reset_cause(void)
2
{
3
  uint8_t reset_cause = 0;
4
  if (__HAL_RCC_GET_FLAG(RCC_FLAG_LPWRRST))
5
  {
6
    reset_cause = 1;//"LOW_POWER_RESET";
7
  }
8
  else if (__HAL_RCC_GET_FLAG(RCC_FLAG_WWDGRST))
9
  {
10
    reset_cause = 2;//"WINDOW_WATCHDOG_RESET";
11
  }
12
  else if (__HAL_RCC_GET_FLAG(RCC_FLAG_IWDGRST))
13
  {
14
    reset_cause = 3;//"INDEPENDENT_WATCHDOG_RESET";
15
  }
16
  else if (__HAL_RCC_GET_FLAG(RCC_FLAG_SFTRST))
17
  {
18
    reset_cause = 4;//"SOFTWARE_RESET";    // This reset is induced by calling the ARM CMSIS `NVIC_SystemReset()` function!
19
  }
20
  //  else if (__HAL_RCC_GET_FLAG(RCC_FLAG_PORTRST))
21
  //  {
22
  //    RCC_FLAG_
23
  //    reset_cause = "POWER-ON_RESET (POR) / POWER-DOWN_RESET (PDR)";
24
  //  }
25
    else if(__HAL_RCC_GET_FLAG(RCC_FLAG_PINRST))
26
  {
27
    reset_cause = 5;//"EXTERNAL_RESET_PIN_RESET";
28
  }
29
  // Needs to come *after* checking the `RCC_FLAG_PORRST` flag in order to ensure first that the reset cause is 
30
  // NOT a POR/PDR reset. See note below. 
31
  else if(__HAL_RCC_GET_FLAG(RCC_FLAG_BORRST))
32
  {
33
    reset_cause = 6;//"BROWNOUT_RESET (BOR)";
34
  }
35
  else
36
  {
37
    reset_cause = 7;// "UNKNOWN";
38
  }
39
  // Clear all the reset flags or else they will remain set during future resets until system power is fully removed.
40
      __HAL_RCC_CLEAR_RESET_FLAGS();
41
  
42
  return reset_cause; 
43
}


Nach einem Reset den Debugger angeworfen und die Funktion hat eine 5 
zurück gegeben (RCC_FLAG_PINRST).

Das verwirrt mich jetzt total. Daraufhin habe ich Datenblatt und Layout 
überprüft. Ich habe am NRST lediglich einen 100nF gegen Masse. Keine 
Lötbrücke, kein Layoutfehler.

Kann jemand etwas mit der Erkenntnis anfangen?
#6016535
Lesenswert?

technikus schrieb:
1
else if(__HAL_RCC_GET_FLAG(RCC_FLAG_PINRST))
2
   {
3
     reset_cause = 5;//"EXTERNAL_RESET_PIN_RESET";
4
   }
5
   // Needs to come *after* checking the `RCC_FLAG_PORRST` flag in order 
6
 to ensure first that the reset cause is
7
   // NOT a POR/PDR reset. See note below.
8
   else if(__HAL_RCC_GET_FLAG(RCC_FLAG_BORRST))
9
   {
10
     reset_cause = 6;//"BROWNOUT_RESET (BOR)";
Demnach könnte es doch auch ein BOR gewesen sein?
Oder sogar ein POR? Weil das Flag nicht getestet wird?
Von wem stammt eigentlich der Kommentar "Needs..."?

Am einfachsten fände ich es, das komplette Register als 32 Bit Wort 
auszugeben.
Gast #6016817
Lesenswert?

Tatsächlich hatte die Brwon Out Detection zugeschlagen.

Ich habe eine Power Bank verwendet um den Probeaufbau zu programmieren.
Bei Abschalten des Displays, hat die Gesamtschaltung so wenig Strom 
gebraucht, das die Power Bank abgeschaltet hat. Nach einem Controller 
Reset ist wieder genug Strom geflossen damit die Power Bank wieder 
versorgt hat.

Jetzt, am Netzteil, läuft alles wie gewünscht.

Danke für die Unterstützung, erst recht für den Hinweis alle Flags bei 
der Fehlersuche zu berücksichtigen.


Gruß
Stefan

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren