Forum: Mikrocontroller und Digitale Elektronik STM32F4: Frage zum Stop Mode


von Christian J. (Gast)


Lesenswert?

Hallo,

ich hätte mal ne Frage zu diesem Mode. Die Sequenz unten habe ich als 
funktionierend heraus gebastelt, um den Core anzuhalten, bis ein 1s 
Event ihn wieder aufweckt, damit er nicht sinnlos in der Schleife 
rumrennt. Brauche eh nur eine Zykluszeit von 1s. Die RTC ist auf 
Eventauslösung eingestellt, springt dann in einen Handler rein.

Seit dem ist die CPU auch eiskalt, während sie vorher leicht warm war 
und der Stromverbrauch um einiges geringer.

Frage:

1) Wieso muss ich den SysTick abschalten, damit mir dieser nicht direkt 
wieder die CPU aufweckt, denn genau das macht er, obwohl ich die CPU mit 
WFE schlafen schicke, was eigentlich nur für Events gilt.

2) Wieso muss ich SysInit erneut aufrufen, weil sonst zb die SPI 
plötzlich viel langsamer läuft, weil der SysClock auch viel langsamer 
ist. Habe nicht gemessen aber es sind keine 168Mhz mehr. Setzt dieser 
Mode da was zurück?

// Core anhalten bis 1s Wakeup von RTC oder external Interrupt
SysTick->CTRL  &= ~SysTick_CTRL_TICKINT_Msk;        // systick IRQ off
PWR_ClearFlag(PWR_FLAG_WU);
PWR_EnterSTOPMode(PWR_Regulator_ON, PWR_STOPEntry_WFE);
SysTick->CTRL  |= SysTick_CTRL_TICKINT_Msk;            // systick IRQ on
SystemInit();

von Jim M. (turboj)


Lesenswert?

Christian J. schrieb:
> 1) Wieso muss ich den SysTick abschalten, damit mir dieser nicht direkt
> wieder die CPU aufweckt, denn genau das macht er, obwohl ich die CPU mit
> WFE schlafen schicke, was eigentlich nur für Events gilt.

Alle Interrupts sind auch Events die WFE aufwecken. Solange Takt anliegt 
zählt der Systick weiter runter und löst auch den Interrupt aus.
Ob Deine Taktquelle im Stop Mode an ist musst Du selber nachlesen.

Christian J. schrieb:
> 2) Wieso muss ich SysInit erneut aufrufen, weil sonst zb die SPI

Bei niedriegeren Schlafmodi als "Idle" werden Taktgeneratoren zwecks 
Stromsparen angehalten. Das dürfte ganz sicher auch die PLL betreffen,
die man danach erst wieder hochfahren muss.

von Mampf F. (mampf) Benutzerseite


Lesenswert?

Christian J. schrieb:
> 1) Wieso muss ich den SysTick abschalten, damit mir dieser nicht direkt
> wieder die CPU aufweckt, denn genau das macht er, obwohl ich die CPU mit
> WFE schlafen schicke, was eigentlich nur für Events gilt.
>
> 2) Wieso muss ich SysInit erneut aufrufen, weil sonst zb die SPI
> plötzlich viel langsamer läuft, weil der SysClock auch viel langsamer
> ist. Habe nicht gemessen aber es sind keine 168Mhz mehr. Setzt dieser
> Mode da was zurück?

Ich hab keine Ahnung ... Hab nach einigen Stunden Debuggen, Googeln, 
Examples analysieren usw usf dann endlich herausgefunden, dass es am 
Systick liegt, dass der Stop-Mode ignoriert wird. Und dann bekam ich 
meinen STM32L162 in den Stop-Mode, nach dem Aufwachen über einen 
externen Taster hard-faultete der aber so richtig ... kA weshalb!

> // Core anhalten bis 1s Wakeup von RTC oder external Interrupt
> SysTick->CTRL  &= ~SysTick_CTRL_TICKINT_Msk;        // systick IRQ off
> PWR_ClearFlag(PWR_FLAG_WU);
> PWR_EnterSTOPMode(PWR_Regulator_ON, PWR_STOPEntry_WFE);
> SysTick->CTRL  |= SysTick_CTRL_TICKINT_Msk;            // systick IRQ on
> SystemInit();

Vielen Vielen Dank! Ich hab den Mist nicht zum Laufen gebracht! Das 
letzte Phänomen war ein Hard-Fault und dass der EXTI-Interrupt nicht 
ausgeführt wurde ... Weiß der Geier warum, aber mit deinem Code 
funktioniert alles sofort so wie es soll!

Erstaunlich, dass anscheinend sonst niemand diese Probleme hatte ... Bei 
Google findet man NICHTS darüber!

: Bearbeitet durch User
von Christian J. (Gast)


Lesenswert?

Mampf F. schrieb:
> Vielen Vielen Dank! Ich hab den Mist nicht zum Laufen gebracht! Das
> letzte Phänomen war ein Hard-Fault und dass der EXTI-Interrupt nicht
> ausgeführt wurde ... Weiß der Geier warum, aber mit deinem Code
> funktioniert alles sofort so wie es soll!
>
> Erstaunlich, dass anscheinend sonst niemand diese Probleme hatte ... Bei
> Google findet man NICHTS darüber!

Ich habe damals auch Stunden gfrickelt, bevor ich das heraus gefunden 
habe, dass man danach alles neu einstellen muss, und natürlich vorher 
den Systick deaktivieren.

von Mampf F. (mampf) Benutzerseite


Lesenswert?

Christian J. schrieb:
> Ich habe damals auch Stunden gfrickelt, bevor ich das heraus gefunden
> habe, dass man danach alles neu einstellen muss, und natürlich vorher
> den Systick deaktivieren.

Ja echt zum Kotzen ... Der Clock wurde bei mir auch umgestellt ... In 
keinem einzigen Beispiel oder Tutorial wird auf die beiden Sachen 
eingegangen ... Und weshalb es bei mir hard-faultete - keine Ahnung!

Aber Danke nochmal :)

von Christian J. (Gast)


Lesenswert?

Mampf F. schrieb:
> Christian J. schrieb:
>> Ich habe damals auch Stunden gfrickelt, bevor ich das heraus gefunden
>> habe, dass man danach alles neu einstellen muss, und natürlich vorher
>> den Systick deaktivieren.
>
> Ja echt zum Kotzen ... Der Clock wurde bei mir auch umgestellt ... In
> keinem einzigen Beispiel oder Tutorial wird auf die beiden Sachen
> eingegangen ... Und weshalb es bei mir hard-faultete - keine Ahnung!
>
> Aber Danke nochmal :)

Das mit dem Hard Fault hatte ich schon mehrfach. Bevor ich mir aber 
einen abbreche da eine Analyse Routine zu schreiben habe ich u.a. die 
Optimierungsstufe als Problem erkannt. Es gibt Programme, die laufen nur 
bei O0 und bei höherem O versagen sie dann. Das haben auch schon andere 
gemerkt. Häufig liegt es daran, dass das Volatile irgendwo vergessen 
wurde bei einer Variable, die im Int verwendet wird und global definiert 
wurde.

Diese Routine bei mir, die die Software SPI füttert läuft nur, wenn ich 
eigens für sie O0 einstelle. Ich habe bis heute nicht herasugefunden 
warum. Mit O2 oder O3 landet sie im HardFault. Das __DMB habe ich 
sicherheitshalber eingefügt, damit auch garantiert der Buszugriff 
abgeschlossen wurde.
1
/* ----------------------------------------------------------------
2
   Schreibt ein 40 Bit Wort in den 74HCT595
3
---------------------------------------------------------------   */
4
static void Set74HCT595(uint64_t data)
5
{
6
    for (int_fast8_t i = 0; i < NSHIFT; i++) {
7
        // Datenbit setzen
8
        GPIO_WriteBit(HC595_CTRL,HC595_DS, (data & 0x1)); __DMB();            
9
        GPIO_SetBits(HC595_CTRL,HC595_SHCP);  __DMB();
10
        GPIO_ResetBits(HC595_CTRL,HC595_SHCP); __DMB();
11
        data = data >> 1;
12
    }
13
14
    // 16 Bit an die Ausgaenge clocken
15
    GPIO_SetBits(HC595_CTRL,HC595_STCP); __DMB()    // STCP -> HIGH
16
    GPIO_ResetBits(HC595_CTRL,HC595_STCP);         // STCP -> LOW
17
}

von Mampf F. (mampf) Benutzerseite


Lesenswert?

Christian J. schrieb:
> Diese Routine bei mir, die die Software SPI füttert läuft nur, wenn ich
> eigens für sie O0 einstelle.

Das hatte ich bei der SDRAM-Inititalisierung eines STM32F429 + 32MB ext 
SDRAM ...

Netterweise kann man O0 für einzelne Funktionen aktivieren:
1
void __attribute__((optimize("-O0"))) SystemInit_ExtMemCtl(void) {
2
...
3
}

:)

: 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.