STM32 Flashing or entering the debug mode performs a mass chip ERASE?
I am working on a H755zi-Q Nucleo board , I am using the flash memory to store some parameters and i have implemented flash wearing as well, All this works fine , my data persists across resets and is correctly loaded upon reset, and i have even verified this in the memory , in debug mode i see each page being written perfectly on every write command, when i upload a new code or sometimes when i terminate and relaunch the debug session and open memory , i see that data is erased. How do i prevent this?i want to retain that sector's data over flashes and debug sessions, the memory sector i am using is far away from my code's sector, (i am using bank 2 last sector).

This is my initial data in the memory, i have entered debug mode, and after performing a new write operation,

here we are again,
but from now if i keep performing write operations they are preserved correctly.
/*
* @brief Find the page of the memory sector to write the
* data of the params struct
*/
uint32_t FindLatestPage(void)
{
FlashPage *pages = (FlashPage *)FLASH_STORAGE_ADDR;
uint32_t latestSeq = 0;
uint32_t latestIdx = 0;
for (uint32_t i = 0; i < NUM_PAGES; i++)
{
if (pages[i].magic == 0xFFFFFFFF)
{
return (i == 0) ? 0 : i - 1; // Return last valid page
}
if (pages[i].magic == MAGIC_NUMBER && pages[i].sequence > latestSeq)
{
latestSeq = pages[i].sequence;
latestIdx = i;
}
}
return latestIdx; // Sector full, return last page
}
/*
* @brief Load data from the flash memory
* to populate the can param struct.
*/
void LoadFromFlash(void)
{
uint32_t idx = FindLatestPage();
FlashPage *page = (FlashPage *)(FLASH_STORAGE_ADDR + idx * PAGE_SIZE);
if (page->magic == MAGIC_NUMBER)
{
memcpy(&canparam, &page->data, sizeof(BMS_COMMAND_RECEPTION));
}
else
{
// Initialize with defaults if no valid data
memset(&canparam, 0, sizeof(BMS_COMMAND_RECEPTION));
SaveToFlash(0); // Start with page 0
}
}
/*
* @brief Save data to next page on the flash.
*/
HAL_StatusTypeDef SaveToFlash(uint32_t currentIdx)
{
HAL_StatusTypeDef status;
FLASH_EraseInitTypeDef eraseInit = {0};
uint32_t sectorError = 0;
static uint32_t sequence = 0;
uint32_t nextIdx = (currentIdx + 1) % NUM_PAGES;
// Check if sector is full (next page is used or wrapping to 0)
FlashPage *nextPage = (FlashPage *)(FLASH_STORAGE_ADDR + nextIdx * PAGE_SIZE);
if (nextIdx == 0 || nextPage->magic != 0xFFFFFFFF)
{
// Erase Sector 7 of Bank 2 when full
status = HAL_FLASH_Unlock();
if (status != HAL_OK) return status;
eraseInit.TypeErase = FLASH_TYPEERASE_SECTORS;
eraseInit.Banks = FLASH_BANK_2;
eraseInit.Sector = FLASH_SECTOR_7; // Sector 7 in Bank 2
eraseInit.NbSectors = 1;
status = HAL_FLASHEx_Erase(&eraseInit, §orError); // Fixed: Use sectorError
if (status != HAL_OK)
{
HAL_FLASH_Lock();
return status;
}
sequence = 0; // Reset sequence after erase
nextIdx = 0; // Start from page 0
HAL_FLASH_Lock();
}
// Write to the next page
status = HAL_FLASH_Unlock();
if (status != HAL_OK) return status;
FlashPage newPage;
newPage.magic = MAGIC_NUMBER;
newPage.sequence = ++sequence; // Increment sequence for each write
newPage.data = canparam;
uint8_t *data = (uint8_t *)&newPage;
uint32_t addr = FLASH_STORAGE_ADDR + nextIdx * PAGE_SIZE;
for (uint32_t i = 0; i < sizeof(FlashPage); i += 32)
{
status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_FLASHWORD, addr + i, (uint32_t)(data + i));
if (status != HAL_OK)
{
HAL_FLASH_Lock();
return status;
}
}
HAL_FLASH_Lock();
return HAL_OK;
}
/*
* @brief Update the parameter if changed and then save it
* to the next page on the flash memory.
*/
void UpdateParameter(uint16_t index, uint16_t value)
{
// Adjust index: Convert 1-based index to 0-based
if (index >= 1 && index <= 28)
{
uint8_t internalIndex = index - 1;
BMS_COMMAND_RECEPTION old = canparam;
canparam.audCommandDataArray[internalIndex] = value;
if (memcmp(&old, &canparam, sizeof(BMS_COMMAND_RECEPTION)) != 0)
{
uint32_t currentIdx = FindLatestPage();
if (SaveToFlash(currentIdx) != HAL_OK)
{
TRACE("ERROR UPDATING THE FLASH MEMORY (UPDATE PARAM FAILED)\r\n");
}
}
}
else
{
TRACE("Invalid index in UpdateParameter(): %d\r\n", index);
}Here are my functions , if you think there is something wrong with this , do let me know.
Also any suggestions to make the code make more cleaner , i try to keep it clean add comments and briefs for functions as well , what else could be more helpful i am open to constructive criticism.
Thankyou.
