2023-06-27 11:32 PM - edited 2023-06-27 11:33 PM
hi there,
I have a stm32H743iit6 and I wish to write a uint32_t array in it flash. I use sector 6 to 7 of Bank1 to write my array to. first I fill my array with number of 0 to 69 like so
for (int i = 0; i < 70; i++)//10
{
flash_buffer_W[i]=i;
}
and then I use the code below to write it in my flash area.
/* Get the 1st sector to erase */
FirstSector = GetSector(FLASH_START_ADDR);
/* Get the number of sector to erase from 1st sector*/
NbOfSectors = GetSector(FLASH_END_ADDR) - FirstSector + 1;
__disable_irq();
vTaskSuspendAll();
HAL_FLASH_Unlock();
/* Fill EraseInit structure*/
EraseInitStruct.TypeErase = FLASH_TYPEERASE_SECTORS;
EraseInitStruct.VoltageRange = FLASH_VOLTAGE_RANGE_3;
EraseInitStruct.Banks = FLASH_BANK_1;
EraseInitStruct.Sector = FirstSector;
EraseInitStruct.NbSectors = NbOfSectors;
if (HAL_FLASHEx_Erase(&EraseInitStruct, &SECTORError) != HAL_OK)
{
return -1;
}
/*Program the user Flash area word by word
(area defined by FLASH_START_ADDR and FLASH_END_ADDR) ***********/
Addressf = FLASH_START_ADDR;
//while (Addressf < FLASH_END_ADDR)
// for(uint32_t i=0;i<size;i++)
//{
HAL_IWDG_Refresh(&hiwdg1); //Reload Watchdog inorder to prevent Micro Reset
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_FLASHWORD, Addressf, flash_buffer_W) == HAL_OK)
{
Addressf = Addressf + 32; /*32bits increment for the next Flash word*/
}
else
{
HAL_FLASH_Lock();
return -1;
}
// }
HAL_FLASH_Lock();
xTaskResumeAll();
__enable_irq();
my problem is
1. it just write first 8 elements of flash_buffer_W[] in the address and then rewrite it to the whole area address instead of writing rest of elements.
2.if I use flash_buffer_W[i] a hardfault happens and it doesnt work whereas in
HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t FlashAddress, uint32_t DataAddress)
I can see that I can use a uint32_t variable.
why is that?
2023-06-29 09:16 AM
> I use sector 6 to 7 of Bank1 to write my array to. first I fill my array with number of 0 to 69 like so
> FirstSector = GetSector(FLASH_START_ADDR);
Your code isn't consistent with what you're saying. You're erasing ALL pages in flash. Which you can do, but only if you are running your code out of RAM, which is not typical and takes some effort.
> HAL_FLASH_Program(FLASH_TYPEPROGRAM_FLASHWORD, Addressf, flash_buffer_W)
You're also passing a pointer as a parameter which requires a uint32_t. The compiler won't let you do this, you'll get error messages.
Note also that HAL_FLASH_Program writes the entire word of flash and has alignment requirements. (Hence why you're seeing 8 words being written in the one case). You can't write a single uint32_t at a time.
/**
* @brief Program a flash word at a specified address
* @PAram TypeProgram Indicate the way to program at a specified address.
* This parameter can be a value of @ref FLASH_Type_Program
* @PAram FlashAddress specifies the address to be programmed.
* This parameter shall be aligned to the Flash word:
* - 256 bits for STM32H74x/5X devices (8x 32bits words)
* - 128 bits for STM32H7Ax/BX devices (4x 32bits words)
* - 256 bits for STM32H72x/3X devices (8x 32bits words)
* @PAram DataAddress specifies the address of data to be programmed.
* This parameter shall be 32-bit aligned
*
* @retval HAL_StatusTypeDef HAL Status
*/
HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t FlashAddress, uint32_t DataAddress)
2023-06-29 11:14 AM - edited 2023-06-29 11:23 AM
The function prototype is confusing
HAL_FLASH_Program(uint32_t TypeProgram, uint32_t FlashAddress, uint32_t DataAddress)
The last parameter is actually a pointer, not uint32. At least it should be uintptr_t. But for a 32-bitter these are same type.
So when you specify flash_buffer_W - it is a pointer (correctly) - but you don't advance it in the loop.
If you specify a uint32_t of data instead (flash_buffer_W[i]) this is a bug and it causes a fault as it should.
Each time HAL_FLASH_Program() writes 32 bytes of data, from DataAddress to DataAddress + 31.