cancel
Showing results for 
Search instead for 
Did you mean: 

Write data in custom flash section

K-C
Associate II

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 !

1 ACCEPTED SOLUTION

Accepted Solutions
K-C
Associate II

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.

View solution in original post

6 REPLIES 6
Pavel A.
Evangelist III

The flash size is defined accordingly to the stm32 model. Make sure that you define correct model in the project settings (preprocessor options).

KnarfB
Principal III

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

K-C
Associate II

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;))

K-C
Associate II

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.

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 ?

 

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