2021-10-25 10:09 AM
I am trying to get an application to set a flag to non-volatile memory to communicate to the bootloader after reset to reprogram the application image. I am using the STM32L496 MCU.
EEPROM seems to be the weapon of choice, but our team has EEPROM on both the application and the bootloader configured to use "virtual eeprom" (which basically means it is actually using flash) and from what I can tell can only be used within their respective programs.
What would be beautiful is if the MCU had a spare non-volatile register (like the RCC_CSR register) that can be used to share a 1-bit flag between the applications to communicate when it is time to reprogram the image.
What is the simplest method for tackling this problem? Example?
Thanks,
Marshall
Solved! Go to Solution.
2021-10-25 12:03 PM
You could move the stack pointer down and shrink the RAM by 16 bytes or whatever.
*((uint32_t *)0x20004FFF0) = 0xABBAACDC;
Between you writing it and doing an NVIC_SystemReset() and entering Reset_Handler is a pretty short walk. The MCU does not clear memory, startup code potentially can but only that visible to the linker.
The RTC has 128 bytes of backup registers, perhaps look at related examples and RM. The linker has no awareness of this memory
void HAL_RTCEx_BKUPWrite(RTC_HandleTypeDef *hrtc, uint32_t BackupRegister, uint32_t Data);
uint32_t HAL_RTCEx_BKUPRead(RTC_HandleTypeDef *hrtc, uint32_t BackupRegister);
On parts like the L1 and L0 there is actual EEPROM if this needs to survive a power cycle, and you have not backup supply.
2021-10-25 10:21 AM
Assign 1 FLASH Page for configuration, page size is smallest independently erasable (often larger than smallest writable).
Some MCUs have bitwise and word-wise erasable sections for this, depends on the family you choose.
I wouldn't use a separate IC (EEPROM) unless this was going to be used often (>1000times in life of product), or you just can't reserve one page of FLASH because code uses every word.
Paul
2021-10-25 10:25 AM
Alternate:
Include a CRC in application code, bootloader check application code and CRC on bootup to verify valid.
To force bootload simply corrupt the App code's CRC by zeroing it. (Need to ensure CRC is alway non-zero.
To force a non-zero CRC simply reserve an extra byte/word and fill it with 0xFF, then BL can check for 0xFF and CRC on boot, if both zero then do Bootload.
Simpler: Reserve one word at beginning or end of App FLASH, zero it to trigger BL. BL must know its address which is why beginning or end of FLASH is best, or just after App Vector table, or an unused vector in App vector table.
2021-10-25 10:30 AM
If it's a simple reset you can just store magic values in RAM, could use registers in RTC also.
2021-10-25 11:32 AM
How would I store data to RAM and be able to recover it? Can you suggest a safe address for my application? This is the RAM allocation as defined in the linker file for both the bootloader and the application. Obviously the flash addresses are different. Do I allocate (aka "carve out") more memory?
2021-10-25 12:03 PM
You could move the stack pointer down and shrink the RAM by 16 bytes or whatever.
*((uint32_t *)0x20004FFF0) = 0xABBAACDC;
Between you writing it and doing an NVIC_SystemReset() and entering Reset_Handler is a pretty short walk. The MCU does not clear memory, startup code potentially can but only that visible to the linker.
The RTC has 128 bytes of backup registers, perhaps look at related examples and RM. The linker has no awareness of this memory
void HAL_RTCEx_BKUPWrite(RTC_HandleTypeDef *hrtc, uint32_t BackupRegister, uint32_t Data);
uint32_t HAL_RTCEx_BKUPRead(RTC_HandleTypeDef *hrtc, uint32_t BackupRegister);
On parts like the L1 and L0 there is actual EEPROM if this needs to survive a power cycle, and you have not backup supply.
2021-10-25 01:33 PM
Since the application is using the RTC peripheral, I am trying to get the RAM approach working first. However, it isn't saving the data.
Application Code:
uint8_t *ToReprogram = (uint8_t *)0x2004FFFF; // last byte of allocated RAM
PRINTF("ToReprogram: %d\n\r", *ToReprogram); // ToReprogram == 97
*ToReprogram = 1;
PRINTF("ToReprogram: %d\n\r", *ToReprogram); // ToReprogram == 1
NVIC_SystemReset(); // software reset -> Jump back to bootloader for reprogramming
Bootloader Code:
uint8_t *ToReprogram = (uint8_t *)0x2004FFFF; // last byte of allocated RAM
PRINTF("ToReprogram: %d\n\r", *ToReprogram); // ToReprogram == 97
What am I missing?
2021-10-25 02:54 PM
Never mind. I took your advice from the following post and it fixed the issue.
Specifically, I updated my linker file as such:
2021-10-25 03:04 PM
And does this work? The stack pointer must be aligned at least on 4 bytes.
2021-10-25 04:04 PM
It does work, but now that you say that I better do that so that I don't run the risk of overwriting whatever is in front of it. Thanks!