Forum: Mikrocontroller und Digitale Elektronik STM32F10x EEPROM Emulation


von Stefan (Gast)


Lesenswert?

Hallo ans Forum,

zum Thema "EEPROM Emulation" beim STM32F10x habe ich bereits die AN2594 
gelesen, aber eine Antwort habe ich dort nicht gefunden, daher versuche 
ich es mal hier im Forum:

Von kleineren Controllern her kenne ich es so, dass man Teile der EEPROM 
Emulation aus dem RAM heraus ausführen lassen muss (z.B. die Befehle für 
Löschen und das Warten auf "Löschen fertig", da Lesezugriff durch die 
CPU während Löschvorgang nicht möglich ist).

Das Thema Löschvorgang/Lesezugriff ist zwar beschrieben, aber in einem 
existierenden Beispielcode von ST ist bezüglich Ausführung aus dem RAM 
nichts zu sehen.

Kann mir jemand sagen, wie genau es sich beim STM32F10x verhält? Muss 
ich Funktionen aus dem RAM ausführen oder nicht?

Gruss und danke im vorraus!

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Ich habe die EEPROM Emulation auf meinem VL-Discovery (STM32F100RB) ohne 
jegliche Klimmzüge machen  können, der Code sitzt ganz normal im Flash. 
Ich kämpfe zwar zur Zeit mit einem Checksummen Problem, der Monitor 
zeigt aber, das die Werte richtig im reservierten 'EEPROM' Bereich 
stehen.

von Stefan (Gast)


Lesenswert?

Danke für die Info. Mir bleibt zwar ein flaues Gefühl im Magen da die 
Aussagen in den Dokus und die SW von ST mir an der Stelle nicht 
übereinstimmend erscheinen, aber da hilft wohl nur ausprobieren...

von Boris S. (rosch7777)


Lesenswert?

Hallo Zusammen

Ich bin nun auch in der misslichen Lage und muss aus platzgründen das 
interne Flash vom STM32 als EEprom missbrauchen.

Nun für genau diesen Zweck gibt es ja von ST diese EEprom emulation.

Nur trotz durchlesen der application note habe ich das ganze noch nicht 
richtig begriffen !!

Ich will am liebsten einfach nur ein struct mit verschiedenen 
Kalibrationsdaten abspeichern.

Im Beispiel von ST werden einfach values von 0-1000 in die virtuelle 
Speicheradresse von 0x5555 und
values von 0-500 in 0x6666 und
values von 0-800 in 0x7777 gespeichert.

Ich verstehen den Nutzen dieses Bsp. nicht !
Wie kann ich nun die abgespeicherten Werte vom Flash zurücklesen ??

00047 int main(void)
00048 {
00049   /* Setup STM32 system (clock, PLL and Flash configuration) */
00050   SystemInit();
00051
00052   /* Unlock the Flash Program Erase controller */
00053   FLASH_Unlock();
00054
00055   /* EEPROM Init */
00056   EE_Init();
00057
00058 /* --- Store successively many values of the three variables in 
the EEPROM ---*/
00059   /* Store 1000 values of Variable1 in EEPROM */
00060   for (VarValue = 0; VarValue < 1000; VarValue++)
00061   {
00062     EE_WriteVariable(VirtAddVarTab[0], VarValue);
00063   }
00064
00065   /* Store 500 values of Variable2 in EEPROM */
00066   for (VarValue = 0; VarValue < 500; VarValue++)
00067   {
00068     EE_WriteVariable(VirtAddVarTab[1], VarValue);
00069   }
00070
00071   /* Store 800 values of Variable3 in EEPROM */
00072   for (VarValue = 0; VarValue < 800; VarValue++)
00073   {
00074     EE_WriteVariable(VirtAddVarTab[2], VarValue);
00075   }
00076
00077   while (1);
00078 }

Ich verstehe einfach nicht wie ich mit hilfe dieser Application notes
mein problem umsetzten muss.

Kann mir da jemand auf die Sprünge helfen?

PS: ich habe einfach mal diese AppNote umgesetzt kann aber an 
Speicheradresse 0x08010000 im debugger keine Aenderung der Daten 
feststellen !?!?

Gruss

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Roger S. schrieb:
> 00061   {
> 00062     EE_WriteVariable(VirtAddVarTab[0], VarValue);
> 00063   }

Du schreibst VarValue auch immer an die gleiche Adresse 
'VirtAddVarTab[0]' was auch immer das sein soll. Du musst die Adresse 
mit richtigem Wert besetzen. Hier mal ein Beispiel aus einem meiner 
Motorcontroller:
1
// addresses in eeprom
2
#define ee_DEAD_TIME_HALF 0
3
#define ee_motor_fwd_commutation 1
4
#define ee_motor_rev_commutation 2
5
6
#define ee_checksum 31
7
8
// write values to EEPROM
9
void EEPROMWrite(void)
10
{
11
  /* Unlock the Flash Program Erase controller */
12
  FLASH_Unlock();
13
  /* EEPROM Init */
14
  ErrValue = EE_Init();
15
// now write our bytes
16
  ErrValue = EE_WriteVariable(ee_DEAD_TIME_HALF,DEAD_TIME_HALF);
17
  ErrValue = EE_WriteVariable(ee_motor_fwd_commutation,motor_fwd_commutation);
18
  ErrValue = EE_WriteVariable(ee_motor_rev_commutation,motor_rev_commutation);
19
// finally write our checksum
20
  ErrValue = EE_WriteVariable(ee_checksum,CalcChecksum());
21
  // Clear the EEPROM Error
22
  error &= ~(ERR_EEPROM);
23
}
24
// Reading
25
// now lets initialize the EEPROM Emulation and read in our variables
26
void EEPROMInit(void)
27
{
28
uint16_t chksum = 0;
29
  ErrValue = EE_ReadVariable(ee_DEAD_TIME_HALF,(uint16_t*)&DEAD_TIME_HALF);
30
  ErrValue = EE_ReadVariable(ee_motor_fwd_commutation,(uint16_t*)&motor_fwd_commutation);
31
  ErrValue = EE_ReadVariable(ee_motor_rev_commutation,(uint16_t*)&motor_rev_commutation);
32
33
  ErrValue = EE_ReadVariable(ee_checksum,&chksum);
34
35
  if ((chksum != CalcChecksum()) || ErrValue ) error |= ERR_EEPROM;
36
}
Das alles für den STM32 VLDiscovery.

von Boris S. (rosch7777)


Lesenswert?

Hallo Zusammen

Also ich habe es jetzt folgendermassen hinbekommen:

struct myData
{
uint32_t test1;
float test2;
};

struct myData sampleData;
struct myData readBackData;
uint16_t* dataPtr = (uint16_t*)&sampleData;
uint16_t* readBackPtr = (uint16_t*)&readBackData;
int i;
int length;
uint16_t vaddr;

int main(void)
{
  /* Setup STM32 system (clock, PLL and Flash configuration) */
  SystemInit();

  sampleData.test1 = 0xFFFF;
  sampleData.test2 = -3.5;

  /* Unlock the Flash Program Erase controller */
  FLASH_Unlock();

  /* EEPROM Init */
  EE_Init();

  //schreibt das sampleData struct ins Flash
  length = (sizeof(sampleData) + 1) / 2;
  vaddr = 0;
  for (i=0; i<length; i++)
  {
      EE_WriteVariable(vaddr, *dataPtr);
      vaddr ++;
      dataPtr++;
  }
  // zur kontrolle struct wieder auslesen vom Flash
  length = (sizeof(readBackData) + 1) / 2;
  vaddr = 0;
  for (i=0; i<length; i++)
  {
      EE_ReadVariable(vaddr, readBackPtr);
      vaddr++;
      readBackPtr++;
  }

Im readBackData struct müssen nun die gleichen Daten wie im sampleData 
struct liegen.

Das hat nun wunderbar funktioniert.
Ich finde das Beispiel von ST unbrauchbar und verwirrend !

Danke Matthias für Deinen input
Ich hoffe unsere Beispiele werden anderen user helfen!

Gruss

von Boris S. (rosch7777)


Lesenswert?

Roger S. schrieb:
> //schreibt das sampleData struct ins Flash
>
>   length = (sizeof(sampleData) + 1) / 2;
>
>   vaddr = 0;
>
>   for (i=0; i<length; i++)
>
>   {
>
>       EE_WriteVariable(vaddr, *dataPtr);
>
>       vaddr ++;
>
>       dataPtr++;
>
>   }

Ach ja und nicht vergessen die irq's zu deaktivieren und danach wieder 
aktivieren wie folgt

__disable_irq();
__enable_irq();

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.