cancel
Showing results for 
Search instead for 
Did you mean: 

Store string into FLASH memory (STM32F407)

luke514
Senior

I want to insert the string my_data_SRAM in the base address of the FLASH. I wrote this code and tried 2 ways:

1) *((uint8_t *)BASE_ADDRESS_FLASH+i) = my_data_RAM[i];

2) HAL_FLASH_Program(TYPEPROGRAM_WORD, (uint32_t *)(BASE_ADDRESS_FLASH+i), my_data_RAM[i]);

Can you tell me where I am wrong? If it is a syntax error or if it is not possible to do what I want to do

#define BASE_ADDRESS_FLASH 0x08000000
 
int main(void)
{
  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
 
	uint8_t i = 0;
 
for (i = 0; i < sizeof(my_data_RAM); i++) {
	//1° method:
	*((uint8_t *)BASE_ADDRESS_FLASH+i) = my_data_RAM[i];
        //2° method:
	HAL_FLASH_Program(TYPEPROGRAM_WORD, (uint32_t *)(BASE_ADDRESS_FLASH+i), my_data_RAM[i]);
} 
 
  while (1)
  {
  }
 
}

3 REPLIES 3
KnarfB
Principal III

Embedded things rarely work by trial and error. Familiarize yourself with the flash (reference manual) and HAL Flash API functions.

  1. You cannot simply assign a new value to a flash location.
  2. Flash needs to be erased before programmed.
  3. BASE_ADDRESS_FLASH is an venturous choice, because that will overwrite the vector table and the MCU will no longer boot from flash. Check the MCU memory layout (data sheet, linker script, .map file)

hth

KnarfB

I don't think I'm causing problems by writing to that address because it is not the 'System memory' sector. Am I wrong?

But I also notice the One-Time-Programmable (OTP) for user data section... maybe that's where I should/can write? 

0693W00000Y8ZdtQAF.jpg

Isn't 0x08000000 where your code physically resides?

Put it deeper into the memory, say 0x080E0000, and make sure the memory is erased first, you can't rewrite it.

You need to unlock it first, and then write as aligned 32-bit values.

So for a string you're going to need to round up the length, including the NUL byte

 /* Unlock the Flash to enable the flash control register access *************/                                                             

HAL_FLASH_Unlock();   

Something along the lines of..

uint32_t WriteString(uint32_t Addr, char *string)
{
  int len = (strlen(string) + 1) + 3) / 4; // in words
  uint32_t *s = (uint32_t *)string;
 
  /* Unlock the Flash to enable the flash control register access *************/
  HAL_FLASH_Unlock();
 
  while(len--)
  {
    if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, Addr, *s++) != HAL_OK)
    {
      Addr = 0;
      break;
    }
 
    Addr += 4;
  }
 
  /* Lock the Flash to disable the flash control register access (recommended
     to protect the FLASH memory against possible unwanted operation) *********/
  HAL_FLASH_Lock();
 
  return(Addr);
}
/**
  * @brief  Gets the sector of a given address
  * @param  None
  * @retval The sector of a given address
  */
static uint32_t GetSector(uint32_t Address)
{
  uint32_t sector = 0;
 
  if((Address < ADDR_FLASH_SECTOR_1) && (Address >= ADDR_FLASH_SECTOR_0))
  {
    sector = FLASH_SECTOR_0;
  }
  else if((Address < ADDR_FLASH_SECTOR_2) && (Address >= ADDR_FLASH_SECTOR_1))
  {
    sector = FLASH_SECTOR_1;
  }
  else if((Address < ADDR_FLASH_SECTOR_3) && (Address >= ADDR_FLASH_SECTOR_2))
  {
    sector = FLASH_SECTOR_2;
  }
  else if((Address < ADDR_FLASH_SECTOR_4) && (Address >= ADDR_FLASH_SECTOR_3))
  {
    sector = FLASH_SECTOR_3;
  }
  else if((Address < ADDR_FLASH_SECTOR_5) && (Address >= ADDR_FLASH_SECTOR_4))
  {
    sector = FLASH_SECTOR_4;
  }
  else if((Address < ADDR_FLASH_SECTOR_6) && (Address >= ADDR_FLASH_SECTOR_5))
  {
    sector = FLASH_SECTOR_5;
  }
  else if((Address < ADDR_FLASH_SECTOR_7) && (Address >= ADDR_FLASH_SECTOR_6))
  {
    sector = FLASH_SECTOR_6;
  }
  else if((Address < ADDR_FLASH_SECTOR_8) && (Address >= ADDR_FLASH_SECTOR_7))
  {
    sector = FLASH_SECTOR_7;
  }
  else if((Address < ADDR_FLASH_SECTOR_9) && (Address >= ADDR_FLASH_SECTOR_8))
  {
    sector = FLASH_SECTOR_8;
  }
  else if((Address < ADDR_FLASH_SECTOR_10) && (Address >= ADDR_FLASH_SECTOR_9))
  {
    sector = FLASH_SECTOR_9;
  }
  else if((Address < ADDR_FLASH_SECTOR_11) && (Address >= ADDR_FLASH_SECTOR_10))
  {
    sector = FLASH_SECTOR_10;
  }
  else if((Address < ADDR_FLASH_SECTOR_12) && (Address >= ADDR_FLASH_SECTOR_11))
  {
    sector = FLASH_SECTOR_11;
  }
  else if((Address < ADDR_FLASH_SECTOR_13) && (Address >= ADDR_FLASH_SECTOR_12))
  {
    sector = FLASH_SECTOR_12;
  }
  else if((Address < ADDR_FLASH_SECTOR_14) && (Address >= ADDR_FLASH_SECTOR_13))
  {
    sector = FLASH_SECTOR_13;
  }
  else if((Address < ADDR_FLASH_SECTOR_15) && (Address >= ADDR_FLASH_SECTOR_14))
  {
    sector = FLASH_SECTOR_14;
  }
  else if((Address < ADDR_FLASH_SECTOR_16) && (Address >= ADDR_FLASH_SECTOR_15))
  {
    sector = FLASH_SECTOR_15;
  }
  else if((Address < ADDR_FLASH_SECTOR_17) && (Address >= ADDR_FLASH_SECTOR_16))
  {
    sector = FLASH_SECTOR_16;
  }
  else if((Address < ADDR_FLASH_SECTOR_18) && (Address >= ADDR_FLASH_SECTOR_17))
  {
    sector = FLASH_SECTOR_17;
  }
  else if((Address < ADDR_FLASH_SECTOR_19) && (Address >= ADDR_FLASH_SECTOR_18))
  {
    sector = FLASH_SECTOR_18;
  }
  else if((Address < ADDR_FLASH_SECTOR_20) && (Address >= ADDR_FLASH_SECTOR_19))
  {
    sector = FLASH_SECTOR_19;
  }
  else if((Address < ADDR_FLASH_SECTOR_21) && (Address >= ADDR_FLASH_SECTOR_20))
  {
    sector = FLASH_SECTOR_20;
  }
  else if((Address < ADDR_FLASH_SECTOR_22) && (Address >= ADDR_FLASH_SECTOR_21))
  {
    sector = FLASH_SECTOR_21;
  }
  else if((Address < ADDR_FLASH_SECTOR_23) && (Address >= ADDR_FLASH_SECTOR_22))
  {
    sector = FLASH_SECTOR_22;
  }
  else/*(Address < FLASH_END_ADDR) && (Address >= ADDR_FLASH_SECTOR_23))*/
  {
    sector = FLASH_SECTOR_23;
  }
 
  return sector;
}
 
 
 
  FLASH_EraseInitTypeDef EraseInitStruct;
 
  /* Unlock the Flash to enable the flash control register access *************/
  HAL_FLASH_Unlock();
 
  /* Erase the user Flash area */
 
  /* Fill EraseInit structure*/
  EraseInitStruct.TypeErase = FLASH_TYPEERASE_SECTORS;
  EraseInitStruct.VoltageRange = FLASH_VOLTAGE_RANGE_3;
  EraseInitStruct.Sector = GetSector(0x0800E000);
  EraseInitStruct.NbSectors = 1;
  if (HAL_FLASHEx_Erase(&EraseInitStruct, &SectorError) != HAL_OK)
  {
    /*
      Error occurred while sector erase.
      User can add here some code to deal with this error.
      SectorError will contain the faulty sector and then to know the code error on this sector,
      user can call function 'HAL_FLASH_GetError()'
    */
    while (1)
    {
      ErrorHandler();
    }
  }
 
  /* Lock the Flash to disable the flash control register access (recommended
     to protect the FLASH memory against possible unwanted operation) *********/
  HAL_FLASH_Lock();

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