2017-02-22 12:16 PM
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.2017-02-24 05:56 AM
Hi
Is it really impossible writing the flash of a L4 MCU at a erased location after a reset without having the complete page erased? On a F103 MCU this works.
Where are HAL_FLASH_ERROR_PGA and HAL_FLASH_ERROR_PGS documented?
What are the dependencies to allow writing to unprotected locations in flash memory on a L4 MCU?
Dieter
2017-02-28 02:24 PM
Hi
the device behaves different than a STM32F103x.
It seems to keep a record about which flash pages where written even beyond a reset.
Also it doesn't matter here whether all bits are set in this relevant location
In order to be able to set a flag for a bootloader this location has to be virgin not only all bytes 0xFF.
Dieter
2017-05-02 02:56 AM
The STM32L4 MCU uses 72bit Flash (64bit data + 8 bit Parity or somthing like this).
There is a difference, if you write a flash position to 0xFFFFFFFFFFFFFFFF or if it is unwritten!
I don't know, if you can see it in firmware. If you will find out a way, please give us a note ;)
2017-05-02 09:46 AM
For rebooting into DFU mode can't one use SRAM or BKPRAM based triggers.
2017-05-02 11:12 AM
I work arround the problem by not writing to this location (i.e. of the flag).
So there is only the erase needed within the bootloader.
After that erase I leave the location untouched (i.e write 127 of 128 locations only ) until the flag must be written.
// Dump and erase flash page. Clear flag in page buffer and write back to flash keeping the config vars
read_flash_vars((uint32_t *) flash_buf, 256, 0);
//flash_buf[127] = 0xFFFFFFFFFFFFFFFF;
erase_flash_page();
// leave last 64 bit wide location virgin after erase
// otherwise the application can not set the flag again
// even if all bits are set in this location
write_flash_vars((uint64_t*) flash_buf, 127, 0);
�?�?�?�?�?�?�?�?
2017-05-02 12:08 PM
I can not grasp what you mean in current context.
2017-05-02 01:24 PM
'
I need to write a flag (double word) to flash to tell a bootloader not to jump to the app but to start a DFU interface.
'When I want the bootloader to nuke the app, or jump to the system loader, I set a RAM variable and reset. If I wanted it more persistent I'd use NVRAM or Option Bytes.
You might want to clear all errors that are flagging. Instrument the code so you can review progress and entry outside a debugger.
2017-05-02 03:10 PM
There is a config tool. The user clicks on 'start bootloader'. The app sets a flag in a flash page where also the configuration of the app is located and resets the device. The bootloader deletes the flag and proceeds to start the DFU interface. The user downloads new app sotware (with or without new configuration) to the device, The DFU protocol resets the device (if so instructed by the config tool) and then the bootloader (now without the flag) starts the app by jumping to it.
What is wrong with that approach?
Would it be more elegant to make use of NVRAM or Option Bytes in this case?
2017-05-02 05:34 PM
You're free to solve it how ever you chose.
SRAM and NVRAM doesn't wear.