2023-04-17 12:18 AM
Hi there,
I have a STM32L431RCT6 microcontroller. I wish to write some data on it. let's say I want to write 2 at 0x08009000 Address.
here is my code
#define FLASH_USER_START_ADDR ((uint32_t)0x08009000)
#define FLASH_USER_END_ADDR ((uint32_t)0x08009000) + FLASH_PAGE_SIZE
#define DATA_SIZE 2
and here is the code where I call flash wirte
flash_buffer_w[1]=2;
write_data_to_flash(flash_buffer_w,DATA_SIZE);
and here is the definition of write_data_to_flash()
uint8_t write_data_to_flash(int32_t *data,uint16_t size)
{
uint32_t NbOfPages = 0;
/* Unlock the Flash to enable the flash control register access *************/
HAL_FLASH_Unlock();
/* Clear OPTVERR bit set on virgin samples */
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR);
/* Unlock the Options Bytes *************************************************/
HAL_FLASH_OB_Unlock();
/* Get the number of the start and end pages */
StartPage = GetPage(FLASH_USER_START_ADDR);
EndPage = GetPage(FLASH_USER_END_ADDR);
/* Get the number of pages to erase from 1st page */
NbOfPages = GetPage(FLASH_USER_END_ADDR) - StartPage + 1;
/* Erase the user Flash area
(area defined by FLASH_USER_START_ADDR and FLASH_USER_END_ADDR) ***********/
/* Fill EraseInit structure*/
EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;
EraseInitStruct.Banks = FLASH_BANK_1;
EraseInitStruct.Page = FLASH_USER_START_ADDR;
EraseInitStruct.NbPages = NbOfPages;
/* Note: If an erase operation in Flash memory also concerns data in the data or instruction cache,
you have to make sure that these data are rewritten before they are accessed during code
execution. If this cannot be done safely, it is recommended to flush the caches by setting the
DCRST and ICRST bits in the FLASH_CR register. */
if (HAL_FLASHEx_Erase(&EraseInitStruct, &PAGEError) != HAL_OK)
{
/*
Error occurred while page erase.
User can add here some code to deal with this error.
PAGEError will contain the faulty page and then to know the code error on this page,
user can call function 'HAL_FLASH_GetError()'
*/
a1=-1;
}
/* Program the user Flash area word by word
(area defined by FLASH_USER_START_ADDR and FLASH_USER_END_ADDR) ***********/
Address = FLASH_USER_START_ADDR;
for(uint32_t i=0;i<size;i++)
{
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, Address, flash_buffer_w[i]) == HAL_OK)
{
Address = Address + 8;
}
else
{
/* Error occurred while writing data in Flash memory.
User can add here some code to deal with this error */
a1=-2;
}
}
/* Lock the Flash to disable the flash control register access (recommended
to protect the FLASH memory against possible unwanted operation) *********/
HAL_FLASH_Lock();
}
but what happens is that the erasing process happens in a way that it even erases some pages form the very beginning Address of the whole program i.e. Address 0x8000000!!!
why this happens?
any solution?
2023-04-20 07:47 AM
Hi @Ala,
About your erasing problem, it may be caused by the definition of the EraseInit structure.
EraseInitStruct.Page should be given a page index, not an address.
You can either specify the index, or you use a macro that will return the index of the page you need :
#define PAGE(__ADDRESS__) (uint32_t)((((__ADDRESS__) - FLASH_BASE) % FLASH_BANK_SIZE) / FLASH_PAGE_SIZE)
Then, PAGE(FLASH_USER_START_ADDR) will return the index that you need.
Let me know if this solves your problem or if we should continue to investigate.
Regards,
Florian LR
2023-04-20 08:42 AM
I could swear I posted an L4 example in recent weeks, but the search on SalesForce/OfficeSpace is so godawful..
You don't need to unlock the option bytes.
Make sure the page and number of page computation are correct.
If it's erasing the WRONG pages, assume it is NOT
Instrument the code so it can report what it's doing, as it does it, with the error/status codes. Don't try to single step this.
The function is passed a pointer, why introduce another pointer/buffer