cancel
Showing results for 
Search instead for 
Did you mean: 

STM32L4 HAL_FLASH_Program without erase

nichtgedacht
Senior
Posted on February 22, 2017 at 21:16

Hi

I need to write a flag (double word) to flash to tell a botloader not to jump to the app but to start a DFU interface.

The bootloader dumps the flash page which contains settings for the app and writes the buffer back to flash with the flag erased.

Within the app the flag can only be written if the flash page gets erased first although its location is guaranteed to be erased.

Here are the relevant parts:

uint32_t write_flash_vars(uint64_t* data, uint16_t length, uint16_t offset) {  uint32_t Address = FLASH_USER_START_ADDR;  __IO uint64_t data64 = 0;   Address += offset;   HAL_FLASH_Unlock();   while (length > 0)  {  data64 = *(__IO uint64_t *) data;   if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, Address, data64) == HAL_OK)  {  Address += 8;  data++;  length--;  }  else  {  HAL_FLASH_Lock();  return HAL_FLASH_GetError();  }  }  HAL_FLASH_Lock();  return HAL_OK; }  uint32_t erase_flash_page(void) {  //Erase flash page(s)  //Fill EraseInit structure  EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;  EraseInitStruct.Page = FLASH_PAGE;  EraseInitStruct.Banks = 0;  EraseInitStruct.NbPages = (FLASH_USER_END_ADDR - FLASH_USER_START_ADDR) / FLASH_PAGE_SIZE;   HAL_FLASH_Unlock();    /* Clear OPTVERR bit set on virgin samples */  __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR);   if (HAL_FLASHEx_Erase(&EraseInitStruct, &PAGEError) != HAL_OK)  {  // PAGEError will contain the faulty page  // error code from 'HAL_FLASH_GetError()'  HAL_FLASH_Lock();  return HAL_FLASH_GetError();  }  else  {  HAL_FLASH_Lock();  return HAL_OK;  } }  void start_bootloader(void) {  HAL_NVIC_SystemReset(); }  void config_state_switch(const char *cmd) {  char buf[20];  char label[8] = 'DFU';   if (strcmp(cmd, 'reboot') == 0)  {  start_bootloader();  }  else if (strcmp(cmd, 'bootloader') == 0)  {   // erase_flash_page();   write_flash_vars((uint64_t*) label, 1, 1016);   start_bootloader(); .... }�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

If the 'erase_flash_page()' is commented out I get the error 0x2a within the program call which is

HAL_FLASH_ERROR_PROG | HAL_FLASH_ERROR_PGA | HAL_FLASH_ERROR_PGS

With the 'erase_flash_page()' call the thing works as expected.

I'm trying to avoid wearing.

How can I achieve the same state as after the erase without actually erasing the page?

Dieter

Note: this post was migrated and contained many threaded conversations, some content may be missing.
12 REPLIES 12
Posted on May 03, 2017 at 12:13

Ok, thanks for the idea.

Can you give me a pointer to working example preserving a variable in SRAM for the bootloader.

I'm using CubeMX generated code for openstm32 system workbench (AC6).

How are startup files and linker scripts to be modified?

Posted on May 03, 2017 at 17:36

The method here is based on examples I've provided for assorted STM32 parts over the years.

https://community.st.com/0D50X00009XkemvSAB

 

*((unsigned long *)0x20017FF0) = 0xDEADBEEF; // Set magic value, and then reset

NVIC_SystemReset(); // or equivalent

If you want to protect the RAM location you can shrink the linkers allocation by 4 bytes, the memory is likely already out of the realm of what will be touched between you setting it, and resetting the part.

The app obviously would need a higher base address in the linker script or scatter file so the flash image doesn't overlap that of your loader, but I suspect you are already dealing with that.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on May 04, 2017 at 19:57

The solution from this blog is only almost working:

https://andrehessling.de/2015/02/16/howto-remanent-data-after-microcontroller-software-reset/

The usage of _estack as an extern declared variable does not work.

On has to use the address directly as you have shown above.

For the application only the shift of _estack within the linker script is needed.

No other mod or mod of startup file here.

The mods of linker script and startup file of the bootloader and their usage are working as in the blog.