Forum: Mikrocontroller und Digitale Elektronik STM32F4xx - Backup Ram verliert Inhalte


von Christian J. (Gast)


Lesenswert?

Moin... gähn

Ich suche mich in meinem Projekt tot, warum "auf einmal" das Backup Ram 
seinen Inhalt verliert, wenn ich die Stromversorgung wegnehme. Klar, 3V 
Batterie ist dran an Vbat, Platine ist umgelötet. Alles auch 
nachgemessen, an Vbar liegen die 3V. Die RTC läuft auch einwandfrei 
weiter, wenn ich den USB Stecker abziehe. Es lief auch mal aber jetzt 
eben nicht mehr nachdem das Programm erweitert wurde.

Damit wird es aktiviert.

/* Enable SRAM Backup Register */
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);         // Power 
für RTC/Backup RAM
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_BKPSRAM, ENABLE);     // 
Backup RAM mit Clock versorgen
    PWR_BackupAccessCmd(ENABLE);

Und das bleibt auch so.

Im Debugger auch alles gecheckt, schaltet man bei einigen DISABLE ein, 
"verschwindet" das Backup RAM auch wieder, beim ersten Befehl bleibt 
auch die Uhr stehen.

Druck auf RESET Knopf lässt alles wie es ist, das RAM behält seine 
Inhalte, die Anwendung erkennt das auch, da ich eine ID im Ram abgelegt 
habe, die abgefragt wird.

Mir fällt nichts mehr ein.... wieso kann das RAM seinen Inhalt noch 
verlieren? Das lief doch vorher :-( Oder habe ich durch 1000 Mal flashen 
die CPU geschossen? Leider kein Ersatzboard derzeit. Bin drauf und dran 
ein E2PROM einzubauen oder einen Sektor des Flash als E2PROM zu 
missbrauchen, da weiss man wenigstens was man hat.

von Harald (Gast)


Lesenswert?

Idee dazu:
- Brown-Out Detection vom Prozessor benutzt, damit dieser im letzten 
Moment keinen Blödsinn macht?
- gibt es einen Write-Enable Pin, den man an einen Prozessorpin legen 
könnte. Beim Reset bzw. BrownOut würde dann sofort per internen Pull-Up 
an den IOs ein weiteres Schreiben verhindert.

von Harald (Gast)


Lesenswert?

Ah, OK - internes RAM. Also kein WriteEnable Signal. Die BrownOut Idee 
bleibt aber.

von Christian J. (Gast)


Lesenswert?

Harald schrieb:

> Idee dazu:
> - Brown-Out Detection vom Prozessor benutzt, damit dieser im letzten
> Moment keinen Blödsinn macht?
> - gibt es einen Write-Enable Pin, den man an einen Prozessorpin legen
> könnte. Beim Reset bzw. BrownOut würde dann sofort per internen Pull-Up
> an den IOs ein weiteres Schreiben verhindert.

Verstehe ich nicht ganz.

Habe zu dem Thema gegoogelt, es passierte einigen schon auch hier. Es 
kann ja nicht sein, dass die Uhr einwandfrei weiterläuft, auch deren 
Backup Register 00 bis 0x19 überleben einwandfrei die Wegnahme der CPU 
Spannung und nur das 4K Backup Ram ist gelöscht.

Ich warte mal auf das neue Board, evtl. ist ja die CPU auch beschädigt 
worden bei dem Rumbasteln.

von Georg (Gast)


Lesenswert?

Christian J. schrieb:
> nur das 4K Backup Ram ist gelöscht

Was verstehst du denn darunter? Nachher 4096 mal 00?

Georg

von Christian J. (Gast)


Lesenswert?

Georg schrieb:

> Was verstehst du denn darunter? Nachher 4096 mal 00?

Nein, Zufallszahlen, alles durcheinander. Nur die RTC Register sind wie 
vorher, also Strom hat der Hobel.

von eagle user (Gast)


Lesenswert?

Das Backup RAM hat einen eigenen Low Power Spannungsregler den man extra 
einschalten muss. Der wird nur bei Batteriebetrieb benutzt, im normalen 
Betrieb wird das RAM vom Core versorgt.

Wenn du verraten würdest, welchen F4xx du hast, könnte man im Reference 
Manual nach dem passenden Bit suchen...

von Christian J. (Gast)


Lesenswert?

eagle user schrieb:
> Wenn du verraten würdest, welchen F4xx du hast, könnte man im Reference
> Manual nach dem passenden Bit suchen...

STM32F407VG

von Christian J. (Gast)


Lesenswert?

Reicht das nicht?

/* Enable SRAM Backup Register */
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);         // Power
für RTC/Backup RAM
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_BKPSRAM, ENABLE);     //
Backup RAM mit Clock versorgen
    PWR_BackupAccessCmd(ENABLE);

Ab dem 2.ten Befehl sieht man im Debugger das RAM sofort.

von eagle user (Gast)


Lesenswert?

Ich meinte das Bit BRE (Bit 9) im PWR_CSR Register. Nachdem man nicht 
weiß, was PWR_BackupAccessCmd(ENABLE) macht (oder ob irgendwer das Bit 
zurücksetzt) solltest du mal direkt das PWR_CSR kontrollieren. Genau 
genommen muss auch das Bit BRR "Backup Regulator Ready" (Bit 3) gesetzt 
sein.

Solange der Debugger verbunden ist, wird das Backup RAM direkt versorgt, 
nicht über diesen Backup Spannungsregler, deshalb geht's dann immer.

von Christian J. (Gast)


Angehängte Dateien:

Lesenswert?

eagle user schrieb:

> Ich meinte das Bit BRE (Bit 9) im PWR_CSR Register. Nachdem man nicht
> weiß, was PWR_BackupAccessCmd(ENABLE) macht (oder ob irgendwer das Bit
> zurücksetzt) solltest du mal direkt das PWR_CSR kontrollieren. Genau
> genommen muss auch das Bit BRR "Backup Regulator Ready" (Bit 3) gesetzt
> sein.
>
> Solange der Debugger verbunden ist, wird das Backup RAM direkt versorgt,
> nicht über diesen Backup Spannungsregler, deshalb geht's dann immer.

Dank dir für den Tip. Grad reingeschaut, das ist ja ein Krampf mit den 
ganzen Bits da drin. Hatten die nichts zu tun bei ST oder gibts pro 
Bit-Erfindung ne Prämie?

Heute abend mal reinschauen, ob die Bits alle so rumtoggeln wie sie 
sollen...

Sind die Register direkt zugänglich, ohne dass ich die StdperophLib 
verwenden muss, also zb

PWR_CS->BRE = ....

oder

PWR_CS | = (1 << BRE)

oder ähnlich?

von Christian J. (Gast)


Lesenswert?

Nett, wenn man per ftp von der Arbeit zu Hause was holen kann :-)

Da haben wir sie ja schon....

/*******************  Bit definition for PWR_CSR register 
********************/
#define  PWR_CSR_WUF                         ((uint32_t)0x00000001) 
/*!< Wakeup Flag                                      */
#define  PWR_CSR_SBF                         ((uint32_t)0x00000002) 
/*!< Standby Flag                                     */
#define  PWR_CSR_PVDO                        ((uint32_t)0x00000004) 
/*!< PVD Output                                       */
#define  PWR_CSR_BRR                         ((uint32_t)0x00000008) 
/*!< Backup regulator ready                           */
#define  PWR_CSR_WUPP                        ((uint32_t)0x00000080) 
/*!< WKUP pin Polarity                                */
#define  PWR_CSR_EWUP                        ((uint32_t)0x00000100) 
/*!< Enable WKUP pin                                  */
#define  PWR_CSR_BRE                         ((uint32_t)0x00000200) 
/*!< Backup regulator enable                          */
#define  PWR_CSR_VOSRDY                      ((uint32_t)0x00004000) 
/*!< Regulator voltage scaling output selection ready */
#define  PWR_CSR_ODRDY                       ((uint32_t)0x00010000) 
/*!< Over Drive generator ready                       */
#define  PWR_CSR_ODSWRDY                     ((uint32_t)0x00020000) 
/*!< Over Drive Switch ready                          */
#define  PWR_CSR_UDSWRDY                     ((uint32_t)0x000C0000) 
/*!< Under Drive ready                                */

von Christian J. (Gast)


Angehängte Dateien:

Lesenswert?

Sooo.......

Dann kommt hier mal die Auflösung, an der wahrscheinlich schon mancher 
graue Haare bekommen hat...tatatataaaa.

Um das Backup Ram zu benutzen muss folgende Sequenz herhalten bei 
Verwendung der StdPeripLib 1.6.1
1
/* Enable SRAM Backup Register */
2
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); 
3
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_BKPSRAM, ENABLE);
4
    PWR_MainRegulatorModeConfig(PWR_Regulator_Voltage_Scale1);
5
    PWR_WakeUpPinCmd(ENABLE);
6
    PWR_BackupRegulatorCmd(ENABLE);
7
    while(PWR_GetFlagStatus(PWR_FLAG_BRR) == RESET);
8
    PWR_BackupAccessCmd(ENABLE);


BRE laesst sich erst setzen, wenn das EWUP Bit gesetzt wurde. Zufall 
dass ich das rausgefunden habe.

Und dann ist der BKRAM Inhalt beim Power Off/on auch wieder da :-))))

Danke Dir !

von Tassilo H. (tassilo_h)


Lesenswert?

Christian J. schrieb:
> BRE laesst sich erst setzen, wenn das EWUP Bit gesetzt wurde. Zufall
> dass ich das rausgefunden habe.

Warum sollte das so sein? Steht das irgendwo im Datenblatt?. Waere ja 
unpraktisch, wenn man den WKUP-Pin nicht braucht (oder PA0 fuer was 
anderes braucht).

von Christian J. (Gast)


Lesenswert?

Tassilo H. schrieb:
> Warum sollte das so sein? Steht das irgendwo im Datenblatt?. Waere ja
> unpraktisch, wenn man den WKUP-Pin nicht braucht (oder PA0 fuer was
> anderes braucht).

k.A. Ist jedenfalls so, BRE lässt sich bei mir nur setzen, wenn vorher 
EWUP gesetzt worden ist. Tja...

Sag mal, gibt es da ein Standardverfahren diese Bits zu setzen, außer 
den PeriphLib Funktionen?

von Tassilo H. (tassilo_h)


Lesenswert?

Also bei mir sieht das für die RTC so aus wie unten gezeigt, Backup-RAM 
ist noch nicht verwendet, soll aber noch, deshalb bin ich auf diesen 
Thread aufmerksam geworden.
Ich verwende direkten Registerzugriff (abgesehen vom clock enable, 
anfangs hab' ich noch die Lib verwendet, bis mir aufgefallen ist, daß 
das für viele Dinge unübersichtlicher ist als direkter Registerzugriff 
und auch nicht portabler). So kann ich den Code wenigstens mit dem 
Datenblatt abgleichen. Ob es Probleme mit dem Backup RAM gibt, weiß ich 
nicht, das wird (noch) nicht verwendet (daher auch das etwas sinnlose 
DBUP an/aus und der Backup Regulator wird noch nicht eingeschaltet).
1
void clockSetRTCWriteProtection(bool enable)
2
{
3
  if (enable) {
4
    RTC->WPR = 0xFF;
5
    PWR->CR &= ~PWR_CR_DBP;
6
  } else {
7
    PWR->CR |= PWR_CR_DBP;
8
    RTC->WPR = 0xCA;
9
    RTC->WPR = 0x53;
10
  }
11
}
12
13
void clockSetInitializationMode(bool enable)
14
{
15
  if (enable) {
16
    RTC->ISR |= RTC_ISR_INIT;
17
    systickSetIOTimeout(3);
18
    while ( ((RTC->ISR & RTC_ISR_INITF) == 0) && (!systickIOTimeoutExpired()) );
19
  } else {
20
    // clear init flag and also the RSF flag
21
    RTC->ISR &= ~(RTC_ISR_INIT | RTC_ISR_RSF);
22
  }
23
}
24
25
void clockInit()
26
{
27
  uint32_t v;
28
29
  if ( (RCC->BDCR & (RCC_BDCR_RTCEN | RCC_BDCR_RTCSEL_1 | RCC_BDCR_RTCSEL_0 | RCC_BDCR_LSEBYP | RCC_BDCR_LSEON))
30
     !=  (RCC_BDCR_RTCEN | RCC_BDCR_RTCSEL_0 | RCC_BDCR_LSEON) ) {
31
    // initialization needed
32
    // reset Backup domain
33
    RCC->BDCR |= RCC_BDCR_BDRST;
34
    RCC->BDCR &= ~RCC_BDCR_BDRST;
35
    // enable write access to BDCR
36
    PWR->CR |= PWR_CR_DBP;
37
    // clear all the RTC relevant bits
38
    v = RCC->BDCR & (~(RCC_BDCR_RTCEN | RCC_BDCR_RTCSEL_1 | RCC_BDCR_RTCSEL_0 | RCC_BDCR_LSEBYP | RCC_BDCR_LSEON));
39
    v |= (RCC_BDCR_RTCEN | RCC_BDCR_RTCSEL_0 | RCC_BDCR_LSEON);
40
    RCC->BDCR = v;
41
    // ok, RTC clock selected and enabled, set it up
42
    clockSetRTCWriteProtection(false);
43
    RTC->CR &= 0xFF000000; // clear all non-reserved bits
44
    RTC->ISR &= 0xFFFE8000; // clear all non-reserved bits
45
    clockSetInitializationMode(true);
46
    RTC->PRER = 255; // sync divider by 256
47
    RTC->PRER |= 127<<16; // async divider by 128
48
    clockSetInitializationMode(false);
49
    clockSetRTCWriteProtection(true);
50
    clockTimeAvailable = false;
51
  } else {
52
    clockTimeAvailable = true;
53
    // enable write access to Backup Domain
54
    PWR->CR |= PWR_CR_DBP;
55
  }
56
  // enable backup sram
57
   RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_BKPSRAM, ENABLE);
58
  PWR->CR &= ~PWR_CR_DBP;
59
60
... etc.

von Christian J. (Gast)


Lesenswert?

Tassilo H. schrieb:
> Ich verwende direkten Registerzugriff (abgesehen vom clock enable,
> anfangs hab' ich noch die Lib verwendet, bis mir aufgefallen ist, daß
> das für viele Dinge unübersichtlicher ist als direkter Registerzugriff
> und auch nicht portabler).

Naja, das erinnert mich an meine schlimmsten LPC2368 Zeiten, wo ich die 
PLL etc auch so gesetzt habe. Ich könnte keine Zeile intuitiv lesen so 
wie das da steht. Ich habe grad nochmal rumprobiert, jetzt lässt sich 
BRE auch so setzen. Vorher aber defintiv nicht. Warum weiss ich nicht, 
das Bit blieb 0. Ich schalte EWUPO jetzt wieder ab nachdem alles gesetzt 
ist und belasse es dabei. Nachher geht das wieder nicht.

Ok, auf jeden Fall sind wir etwas weiter. Ich finde es nur echt blöd, 
dass die StdPeriphLib kein pdf als Manual hat, diese chm Datei finde ich 
voll daneben.

PS: Wo steht das denn alles drin? Automatische Ergänzung funzt nicht.

PWR->CR |= PWR_CR_DBP;

CMSIS?

PS: Mit dem BRE Bit hat es irgendwas auf sich, jetzt lässt es sich nicht 
mehr zurücksetzen im Debugger. Seltsam....

von Tassilo H. (tassilo_h)


Lesenswert?

Christian J. schrieb:
> PS: Wo steht das denn alles drin? Automatische Ergänzung funzt nicht.
>
> PWR->CR |= PWR_CR_DBP;

stm32f4xx.h

Da ist alles drin nach dem Schema
[Peripheriename aus dem Datenblatt]->[Registername aus dem Datenblatt]

Diese Headerdatei kam mit der CooCox IDE, aber nach den Kommentaren ist 
sie von ST und gehört zu CMSIS.

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.