cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F746G-DISCO, FLASH

AD�?b
Senior

Why does flasch memory lose saved data after being read and written after power off?

Andrzej

19 REPLIES 19
KnarfB
Principal III

Keep in mind that flash wears out easily. Max. number of guaranteed cycles (10k) is in the data sheets. There is a EEPROM emulation library, see AN4894 "EEPROM emulation techniques and software for STM32 microcontrollers" and X-CUBE-EEPROM library doing some wear-leveling and other house keeping with a more user oriented API.

I will only write one uint32_t during power off. It is enough for 10 years.

I added HAL_FLASHEx_Erase (FLASH_SECTOR_3, 0);

It has not changed. ?

Why:

1. I write to FLASH by interrupting

2. when I reset Disco it's OK

3. when I turn off the power and turn on NO OK

Why do I have such comments?

in main.c

in expansion of macro 'FLASH_SECTOR_7'

and

at stm32f746xx_hal_flash.h

expected 'FLASH_EraseInitTypeDef * {aka struct <anonymous> *}' but argument is of type 'long unsigned int'

Something along the lines of this should work

/* Uncomment the following define to select the FLASH Dual Bank mode,
   or keep it commented to select the FLASH Single Bank mode */
 
#define DUAL_BANK
 
/* Base address of the Flash sectors */
#if defined(DUAL_BANK)
#define ADDR_FLASH_SECTOR_0     ((uint32_t)0x08000000) /* Base address of Sector 0, 16 Kbytes */
#define ADDR_FLASH_SECTOR_1     ((uint32_t)0x08004000) /* Base address of Sector 1, 16 Kbytes */
#define ADDR_FLASH_SECTOR_2     ((uint32_t)0x08008000) /* Base address of Sector 2, 16 Kbytes */
#define ADDR_FLASH_SECTOR_3     ((uint32_t)0x0800C000) /* Base address of Sector 3, 16 Kbytes */
#define ADDR_FLASH_SECTOR_4     ((uint32_t)0x08010000) /* Base address of Sector 4, 64 Kbytes */
#define ADDR_FLASH_SECTOR_5     ((uint32_t)0x08020000) /* Base address of Sector 5, 128 Kbytes */
#define ADDR_FLASH_SECTOR_6     ((uint32_t)0x08040000) /* Base address of Sector 6, 128 Kbytes */
#define ADDR_FLASH_SECTOR_7     ((uint32_t)0x08060000) /* Base address of Sector 7, 128 Kbytes */
#define ADDR_FLASH_SECTOR_8     ((uint32_t)0x08080000) /* Base address of Sector 8, 128 Kbytes */
#define ADDR_FLASH_SECTOR_9     ((uint32_t)0x080A0000) /* Base address of Sector 9, 128 Kbytes */
#define ADDR_FLASH_SECTOR_10    ((uint32_t)0x080C0000) /* Base address of Sector 10, 128 Kbytes */
#define ADDR_FLASH_SECTOR_11    ((uint32_t)0x080E0000) /* Base address of Sector 11, 128 Kbytes */
#define ADDR_FLASH_SECTOR_12    ((uint32_t)0x08100000) /* Base address of Sector 12, 16 Kbytes */
#define ADDR_FLASH_SECTOR_13    ((uint32_t)0x08104000) /* Base address of Sector 13, 16 Kbytes */
#define ADDR_FLASH_SECTOR_14    ((uint32_t)0x08108000) /* Base address of Sector 14, 16 Kbytes */
#define ADDR_FLASH_SECTOR_15    ((uint32_t)0x0810C000) /* Base address of Sector 15, 16 Kbytes */
#define ADDR_FLASH_SECTOR_16    ((uint32_t)0x08110000) /* Base address of Sector 16, 64 Kbytes */
#define ADDR_FLASH_SECTOR_17    ((uint32_t)0x08120000) /* Base address of Sector 17, 128 Kbytes */
#define ADDR_FLASH_SECTOR_18    ((uint32_t)0x08140000) /* Base address of Sector 18, 128 Kbytes */
#define ADDR_FLASH_SECTOR_19    ((uint32_t)0x08160000) /* Base address of Sector 19, 128 Kbytes */
#define ADDR_FLASH_SECTOR_20    ((uint32_t)0x08180000) /* Base address of Sector 20, 128 Kbytes */
#define ADDR_FLASH_SECTOR_21    ((uint32_t)0x081A0000) /* Base address of Sector 21, 128 Kbytes */
#define ADDR_FLASH_SECTOR_22    ((uint32_t)0x081C0000) /* Base address of Sector 22, 128 Kbytes */
#define ADDR_FLASH_SECTOR_23    ((uint32_t)0x081E0000) /* Base address of Sector 23, 128 Kbytes */
#else
#define ADDR_FLASH_SECTOR_0     ((uint32_t)0x08000000) /* Base address of Sector 0, 32 Kbytes */
#define ADDR_FLASH_SECTOR_1     ((uint32_t)0x08008000) /* Base address of Sector 1, 32 Kbytes */
#define ADDR_FLASH_SECTOR_2     ((uint32_t)0x08010000) /* Base address of Sector 2, 32 Kbytes */
#define ADDR_FLASH_SECTOR_3     ((uint32_t)0x08018000) /* Base address of Sector 3, 32 Kbytes */
#define ADDR_FLASH_SECTOR_4     ((uint32_t)0x08020000) /* Base address of Sector 4, 128 Kbytes */
#define ADDR_FLASH_SECTOR_5     ((uint32_t)0x08040000) /* Base address of Sector 5, 256 Kbytes */
#define ADDR_FLASH_SECTOR_6     ((uint32_t)0x08080000) /* Base address of Sector 6, 256 Kbytes */
#define ADDR_FLASH_SECTOR_7     ((uint32_t)0x080C0000) /* Base address of Sector 7, 256 Kbytes */
#define ADDR_FLASH_SECTOR_8     ((uint32_t)0x08100000) /* Base address of Sector 8, 256 Kbytes */
#define ADDR_FLASH_SECTOR_9     ((uint32_t)0x08140000) /* Base address of Sector 9, 256 Kbytes */
#define ADDR_FLASH_SECTOR_10    ((uint32_t)0x08180000) /* Base address of Sector 10, 256 Kbytes */
#define ADDR_FLASH_SECTOR_11    ((uint32_t)0x081C0000) /* Base address of Sector 11, 256 Kbytes */
#endif /* DUAL_BANK */
 
uint32_t ReadValue(void)
{
  return(*(uint32_t *)ADDR_FLASH_SECTOR_3);
}
 
void WriteValue(uint32_t Value)
{
  FLASH_EraseInitTypeDef EraseInitStruct = {0};
  uint32_t SECTORError = 0;
 
  if (ReadValue() == Value) return; // Already at current value
 
  /* Unlock the Flash to enable the flash control register access *************/
  HAL_FLASH_Unlock();
 
  /* Fill EraseInit structure*/
  EraseInitStruct.TypeErase     = FLASH_TYPEERASE_SECTORS;
  EraseInitStruct.VoltageRange  = FLASH_VOLTAGE_RANGE_3;
  EraseInitStruct.Sector        = FLASH_SECTOR_3;
  EraseInitStruct.NbSectors     = 1;
 
  /* Note: If an erase operation in Flash memory also concerns data in the data or instruction cache,
     you have to make sure that these data are rewritten before they are accessed during code
     execution. If this cannot be done safely, it is recommended to flush the caches by setting the
     DCRST and ICRST bits in the FLASH_CR register. */
  if (HAL_FLASHEx_Erase(&EraseInitStruct, &SECTORError) != HAL_OK)
  {
    ErrorHandler();
  }
 
  if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, ADDR_FLASH_SECTOR_3, Value) != HAL_OK)
  {
    ErrorHandler();
  }
 
  /* Lock the Flash to disable the flash control register access (recommended
     to protect the FLASH memory against possible unwanted operation) *********/
  HAL_FLASH_Lock();
} // sourcer32@gmail.com

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

What is the difference between working with one bank or two banks.

I have uint32_t to write. Does it have any purpose?

It affects the addressing, the banks can be placed end-to-end or side-to-side, the latter being wider, improving the fetching/caching efficiency.

Try the Reference Manual for insight into the flash geometry and functionality.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

Hi

Thank you! It works.

Is it not the other way around in attention? "Uncomment the following define to select the FLASH Dual Bank mode, or keep it commented to select the FLASH Single Bank mode "

I saw // #define DUAL_BANK In my opinion, I work in Single Bank mode.

I changed instead of sector 3 to sector 7 because there was a collision. I had 180 kB FLASH seized.

There was one more mistake: was ErrorHandler (); a should be Error_Handler ();

greetings

Andrzej

I also have this problem: 1. I want to save one uint32_t when disconnecting the power supply 2. the relay is switched on with the same power supply as the power supply 3. NC contacts are connected to the interrupt 4. in the absence of power, they are to initiate saving to FLASH 5.void HAL_GPIO_EXTI_Callback (uint16_t GPIO_Pin) // interrupt for writing to FLASH { if (GPIO_Pin == STOP_Pin) { WriteValue (total_time); } } 6. After turning the power off and turning it back on, uint32_t = 0?