Sida 1 av 2

Hur använder man "EEPROM" i STM32 F401RE

Postat: 31 maj 2020, 15:19:13
av DanielM
För det första så finns det inte EEPROM i STM32 F401RE. Men det finns ett sätt som man kan spara data i flashminnet.
Dessa filer som jag bifogar är gjorda för STM32 F401RE.

Här är ett arbetsexempel som är själva skapat av ST själva. Då är mina frågor:
  • Kan jag använda detta under körning? Eller är det bara vid uppstart?
  • Hur vet jag vilka adresser jag kan skriva till som är säkra?
  • Måste jag anropa HAL_FLASH_Lock(); För varje gång jag har skrivit klart?
Denna bild kommer från databaldet hos STM32 F401RE.
hhS2y.png

Kod: Markera allt

#include "main.h"
/** @addtogroup EEPROM_Emulation
  * @{
  */

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/

/* Virtual address defined by the user: 0xFFFF value is prohibited */
uint16_t VirtAddVarTab[NB_OF_VAR] = {0x5555, 0x6666, 0x7777};
uint16_t VarDataTab[NB_OF_VAR] = {0, 0, 0};
uint16_t VarValue,VarDataTmp = 0;
/* Private function prototypes -----------------------------------------------*/
static void SystemClock_Config(void);
static void Error_Handler(void);

/* Private functions ---------------------------------------------------------*/

/**
  * @brief  Main program.
  * @param  None
  * @retval None
  */
int main(void)
{
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();
  
  /* Configure the system clock to 84 MHz */
  SystemClock_Config();
  
   /* Unlock the Flash Program Erase controller */
  HAL_FLASH_Unlock();
  
  /* Configure LED2 */
  BSP_LED_Init(LED2);

  /* EEPROM Init */
  if( EE_Init() != EE_OK)
  {
    Error_Handler();
  }
  
  /* --- Store successively many values of the three variables in the EEPROM ---*/
  /* Store 0x1000 values of Variable1 in EEPROM */
  for (VarValue = 1; VarValue <= 0x1000; VarValue++)
  {
    /* Sequence 1 */
    if((EE_WriteVariable(VirtAddVarTab[0],  VarValue)) != HAL_OK)
    {
      Error_Handler();
    }
    if((EE_ReadVariable(VirtAddVarTab[0],  &VarDataTab[0])) != HAL_OK)
    {
      Error_Handler();
    }
    if (VarValue != VarDataTab[0])
    {
      Error_Handler();
    }
    
    /* Sequence 2 */
    if(EE_WriteVariable(VirtAddVarTab[1], ~VarValue) != HAL_OK)
    {
      Error_Handler();
    }  
    if(EE_ReadVariable(VirtAddVarTab[1], &VarDataTab[1]) != HAL_OK)
    {
      Error_Handler();
    } 
    if(((uint16_t)~VarValue) != VarDataTab[1])
    {
      Error_Handler();
    }

    /* Sequence 3 */
    if(EE_WriteVariable(VirtAddVarTab[2],  VarValue << 1) != HAL_OK)
    {
      Error_Handler();
    }
    if(EE_ReadVariable(VirtAddVarTab[2],  &VarDataTab[2]) != HAL_OK)
    {
      Error_Handler();
    } 
    if ((VarValue << 1) != VarDataTab[2])
    {
      Error_Handler();
    }
  }

  /* Store 0x2000 values of Variable2 in EEPROM */
  for (VarValue = 1; VarValue <= 0x2000; VarValue++)
  {
    if(EE_WriteVariable(VirtAddVarTab[1], VarValue) != HAL_OK)
    {
      Error_Handler();
    }      
    if(EE_ReadVariable(VirtAddVarTab[1], &VarDataTab[1]) != HAL_OK)
    {
      Error_Handler();
    }    
    if(VarValue != VarDataTab[1])
    {
      Error_Handler();
    }
  }

  /* read the last stored variables data*/
  if(EE_ReadVariable(VirtAddVarTab[0], &VarDataTmp) != HAL_OK)
  {
    Error_Handler();
  }   
  if (VarDataTmp != VarDataTab[0])
  {
    Error_Handler();
  }

  if(EE_ReadVariable(VirtAddVarTab[1], &VarDataTmp) != HAL_OK)
  {
    Error_Handler();
  }    
  if (VarDataTmp != VarDataTab[1])
  {
    Error_Handler();
  }

  if(EE_ReadVariable(VirtAddVarTab[2], &VarDataTmp) != HAL_OK)
  {
    Error_Handler();
  }    
  if (VarDataTmp != VarDataTab[2])
  {
    Error_Handler();
  }
  
  /* Store 0x3000 values of Variable3 in EEPROM */
  for (VarValue = 1; VarValue <= 0x3000; VarValue++)
  {
    if(EE_WriteVariable(VirtAddVarTab[2], VarValue) != HAL_OK)
    {
      Error_Handler();
    }      
    if(EE_ReadVariable(VirtAddVarTab[2], &VarDataTab[2]) != HAL_OK)
    {
      Error_Handler();
    }    
    if(VarValue != VarDataTab[2])
    {
      Error_Handler();
    }
  }

  /* read the last stored variables data*/
  if(EE_ReadVariable(VirtAddVarTab[0], &VarDataTmp) != HAL_OK)
  {
    Error_Handler();
  }    
  if (VarDataTmp != VarDataTab[0])
  {
    Error_Handler();
  }

  if(EE_ReadVariable(VirtAddVarTab[1], &VarDataTmp) != HAL_OK)
  {
    Error_Handler();
  }
  if (VarDataTmp != VarDataTab[1])
  {
    Error_Handler();
  }

  if(EE_ReadVariable(VirtAddVarTab[2], &VarDataTmp) != HAL_OK)
  {
    Error_Handler();
  }  
  if (VarDataTmp != VarDataTab[2])
  {
    Error_Handler();
  }
  
  /* Turn LED2 On */
  BSP_LED_On(LED2);

  while (1)
  {
  }
}

Re: Hur använder man "EEPROM" i STM32 F401RE

Postat: 31 maj 2020, 16:03:40
av hummel
STM32s dokumentation beskriver garanterat det, har du tittat där?

Re: Hur använder man "EEPROM" i STM32 F401RE

Postat: 31 maj 2020, 16:28:44
av DanielM
STM32's dokumentation är riktigt dålig. Det är ungefär som att leta en nål i en höstack.

Bilden jag bifogade kommer just från dokumentationen. Fick inte så klar information där.
Hur jag fick reda på dom där C-filerna har med att jag läste på ett STM32 forum.

Re: Hur använder man "EEPROM" i STM32 F401RE

Postat: 31 maj 2020, 18:20:32
av Icecap
Det BORDE vara så att funktionen för att spara ett minnesblock avslutar med att stänga efter sig.
Det är i alla fall vanligt på välskriven mjukvara.

Men om DU måste göra det i detta kan du klura ut själv.

Ett annat säkerhetstänkande kan också vara att man medvetet ska öppna för programmeringsmöjligheten, spara vad som ska sparas och efteråt stänger "manuellt". Jag anser dock att det är falsk säkerhet på det vis.

Re: Hur använder man "EEPROM" i STM32 F401RE

Postat: 31 maj 2020, 20:42:32
av Mr Andersson
Kan jag använda detta under körning? Eller är det bara vid uppstart?
Du kan skriva nästan närsomhelst. Enda kravet är att klockfrekvensen måste vara >=1MHz.

Hur vet jag vilka adresser jag kan skriva till som är säkra?
Du måste givetvis ha koll på vilket adressområde din programkod använder.

Måste jag anropa HAL_FLASH_Lock(); För varje gång jag har skrivit klart?
Nej det måste du inte. Det låsningen gör är att du får hardfault om du försöker skriva till flash medans det är låst.
Kan väl kanske vara ett litet skydd mot att buggig kod gör oavsiktliga skrivningar men det är inget krav att man låser det.

Allt står beskrivet i punkt 3.5 i RM0368.

Re: Hur använder man "EEPROM" i STM32 F401RE

Postat: 31 maj 2020, 21:14:06
av TomasL
Dessutom är det väl ruskigt dumt att skriva till programminnet (gissar att det är det som avses) med tanke på den begränsade livslängden på just programminnet.

Re: Hur använder man "EEPROM" i STM32 F401RE

Postat: 31 maj 2020, 21:28:23
av DanielM
Fast man kan väll skriva flera miljoner gånger här?

Re: Hur använder man "EEPROM" i STM32 F401RE

Postat: 31 maj 2020, 21:29:21
av DanielM
Mr Andersson skrev:Kan jag använda detta under körning? Eller är det bara vid uppstart?
Du kan skriva nästan närsomhelst. Enda kravet är att klockfrekvensen måste vara >=1MHz.

Hur vet jag vilka adresser jag kan skriva till som är säkra?
Du måste givetvis ha koll på vilket adressområde din programkod använder.

Måste jag anropa HAL_FLASH_Lock(); För varje gång jag har skrivit klart?
Nej det måste du inte. Det låsningen gör är att du får hardfault om du försöker skriva till flash medans det är låst.
Kan väl kanske vara ett litet skydd mot att buggig kod gör oavsiktliga skrivningar men det är inget krav att man låser det.

Allt står beskrivet i punkt 3.5 i RM0368.
Tackar! Vet inte hur du lyckades hitta denna information. Antar du har gjort detta förut.
Min klockfrekvens HCLK är 84 MHz så då bör detta fungera.

Edit:
Nu förstår jag varför jag inte hittade samma information som du. Jag kollade i andra dokumentet om just samma processor.
https://www.st.com/resource/en/datashee ... f401re.pdf

Jag tror jag sparar dom här i sektor 7.

Re: Hur använder man "EEPROM" i STM32 F401RE

Postat: 31 maj 2020, 21:54:04
av TomasL
DanielM skrev:Fast man kan väll skriva flera miljoner gånger här?
Du får kontrollera databladet angående detta.
Generellt sett så har programminnet låg redundans. typ 10k eller så, till skillnad från EE-flash (typ separata Flashminnen) som kan ligga ett antal tio-potenser högre.

Re: Hur använder man "EEPROM" i STM32 F401RE

Postat: 31 maj 2020, 21:56:24
av AndLi
Varför slösa en av de större sektorerna på inställningar? Är det så mycket du ska spara?

Re: Hur använder man "EEPROM" i STM32 F401RE

Postat: 31 maj 2020, 22:00:26
av DanielM
Jag kollar i kapitel 3 som Neo, ovan, hänvisade till. Men hittar inget.
Jag förväntar mig någon "utmattningstabell". Nej, inte wöhlerkurva :roll:

Re: Hur använder man "EEPROM" i STM32 F401RE

Postat: 31 maj 2020, 22:15:34
av TomasL
I de tekniska data, ingen tabell, av naturliga skäl, utan enbart en siffra. för processorn i fråga hittar du redundansen för minnet.

Re: Hur använder man "EEPROM" i STM32 F401RE

Postat: 1 juni 2020, 11:16:56
av DanielM
Vill bara säga att orsaken varför jag tänker spara i minnet har med att jag har en LCD som jag har kört en x,y kalibrering på.

Då tänkte jag spara detta i minnet.
Jag har även en funktion där jag kan återkalibrera under körning.

Så vad tror ni är bäst?
1. Skriva in permanent kalibreringkoordinater
2. Ha en funktion där man kan kalibrera under körning och spara detta i minnet.

Det är en Kina - lcd - ili9341

Re: Hur använder man "EEPROM" i STM32 F401RE

Postat: 1 juni 2020, 15:57:04
av Rick81
Beror på hur många enheter du har/tänker använda. Är det bara en kan du lika väl lägga det direkt i koden då det blir enklare.

Re: Hur använder man "EEPROM" i STM32 F401RE

Postat: 1 juni 2020, 16:34:05
av Findecanor
Helt omöjligt att använda extern EEPROM?