2023-06-27 06:45 AM
Hi,
I'm working on stm32l496 and I try to write data to a custom flash section, in the .ld file I put new sector :
/* Memories definition */
MEMORY
{
[...]
FLASH (rx) : ORIGIN = 0x08003800, LENGTH = 0x07B800
config(rx) : ORIGIN = 0x0807F000, LENGTH = 2K
common(rxw) : ORIGIN = 0x0807F800, LENGTH = 2K
}
[...]
PROVIDE(_config_page_start = ORIGIN(config));
PROVIDE(_common_page_start = ORIGIN(common));
I set it like this to flash config or common page without touch my program section.
I have no difficulty to read data from this pages. But when I use `HAL_FLASH_Program()` function to write data in 'common' section, I have an error.
After reseach the error may be due to ASSERT checking if the address is whitin the flash range.
This is my code :
error_e mcu_flash_program_data(uint32_t start_addr, const void *data, size_t size) {
HAL_StatusTypeDef hal_ret = HAL_OK;
const uint64_t *ptr = data;
for (size_t i = 0; i < size; i += sizeof(uint64_t)) {
hal_ret = HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, start_addr + i, *ptr);
if (hal_ret != HAL_OK) {
return (ERR_HAL);
}
}
return (ERR_OK);
}
error_e mcu_flash_write_page(my_own_struct_s data) {
void* ptr = &data;// the data to store
uin32_t addr_val = 0x0807F800;
size_t size = sizeof(data);
if (HAL_FLASH_Unlock() == HAL_OK) {
err = mcu_flash_program_data(addr_val, data_ptr, size);
HAL_FLASH_Lock(); // it always returns HAL_OK
}
If I replace `addr_val` by 0x0807e000 (by example) there is no problem.
Is there a way to write correctly in this part of the memory ?
Thanks !
Solved! Go to Solution.
2023-06-28 02:20 AM
I found the solution !
I forgot to erase the page before write it, it seems it is not mandatory to erase it for FLASH sector, but for my custom sector I have to erase it before.
Thanks for your help.
2023-06-27 09:31 AM
The flash size is defined accordingly to the stm32 model. Make sure that you define correct model in the project settings (preprocessor options).
2023-06-27 11:55 AM
Debug step your code into HAL_FLASH_Program and try to understand exactly what's happening. IMO the assertion depends on FLASH_SIZE_DATA_REGISTER and not on linker script settings.
Your code snippet does not compile: data_ptr is undefined. Passing a struct by value (data parameter) is inefficient and not needed if you only need a pointer to it.
hth
KnarfB
2023-06-27 11:45 PM - edited 2023-06-28 12:15 AM
You're right, the error happens in `FLASH_WaitForLastOperation()` function. I get the error flag with this 3 errors :
FLASH_SR_PROGERR /*!< FLASH Programming error flag */
FLASH_SR_PGAERR /*!< FLASH Programming alignment error flag */
FLASH_SR_PGSERR /*!< FLASH Programming sequence error flag */
So in debug I verify the address given : 0x807f808 -> is aligned. My sector area [0x807f800-08080000].
I have 1MBytes of flash memory and I only use half of it.
I'm not really comfortable with linker script, maybe there is an issue with the declaration of my section.
.common : {
. = ALIGN(4);
KEEP (*(.common.sec))
. = ALIGN(4);
} >common
In STMcubeIDE I see the differents region allocated.
(I modify the code I provide to you from mine to give the main idea but i made a mistake during the copy/paste;))
2023-06-28 02:20 AM
I found the solution !
I forgot to erase the page before write it, it seems it is not mandatory to erase it for FLASH sector, but for my custom sector I have to erase it before.
Thanks for your help.
2024-01-15 08:53 PM
i think for flash to it is necessary to erase before flashing.
i want to know that weather i can erase single word in the flash as i am able to erase the whole sector not single 32bits.do you have any idea ?
2024-03-01 01:09 AM
No. Although it is possible to write a single word in Flash memory, it is not possible to erase a single word. Erasing can only be done sector by sector, or mass erase (= erase the complete Flash).
You will find more information about the write/erase granularity in the Reference Manual (RM) of your specific STM32 device. For example, the RM of the STM32F446xx microcontrollers can be found here: https://www.st.com/resource/en/reference_manual/dm00135183-stm32f446xx-advanced-arm-based-32-bit-mcus-stmicroelectronics.pdf