2021-07-30 07:43 AM
Hi! Jest a curiosity topic.
Currently Im writing a double word to flash with HAL_FLASH_Program function.
RM notes that You should write a word32 and than to the same adress another word32.
How can You write a 2x_word_32 or 1x_doubleword_64 without HAL funciin or making struct etc.
?
Chip Im using is stm32L432KC, that has a page flash aligment and You can write only double word to it at once.
Thanks !
Writing to desired location like to FLASH->KEYR or with +0x04UL distancing with another word fails with data aligment error flag.
Solved! Go to Solution.
2021-07-30 08:57 AM
They don't write the data to the same address
/**
* @brief Program double-word (64-bit) at a specified address.
* @param Address: specifies the address to be programmed.
* @param Data: specifies the data to be programmed.
* @retval None
*/
static void FLASH_Program_DoubleWord(uint32_t Address, uint64_t Data)
{
/* Check the parameters */
assert_param(IS_FLASH_PROGRAM_ADDRESS(Address));
/* Set PG bit */
SET_BIT(FLASH->CR, FLASH_CR_PG);
/* Program first word */
*(__IO uint32_t*)Address = (uint32_t)Data;
/* Barrier to ensure programming is performed in 2 steps, in right order
(independently of compiler optimization behavior) */
__ISB();
/* Program second word */
*(__IO uint32_t*)(Address+4U) = (uint32_t)(Data >> 32);
}
If I were using assembler I'd probably use the STRD in this context. It does expect 32-bit (4-byte) alignment of the address. The flash array expects a 64-bit (8-byte) alignment of the address.
2021-07-30 08:57 AM
They don't write the data to the same address
/**
* @brief Program double-word (64-bit) at a specified address.
* @param Address: specifies the address to be programmed.
* @param Data: specifies the data to be programmed.
* @retval None
*/
static void FLASH_Program_DoubleWord(uint32_t Address, uint64_t Data)
{
/* Check the parameters */
assert_param(IS_FLASH_PROGRAM_ADDRESS(Address));
/* Set PG bit */
SET_BIT(FLASH->CR, FLASH_CR_PG);
/* Program first word */
*(__IO uint32_t*)Address = (uint32_t)Data;
/* Barrier to ensure programming is performed in 2 steps, in right order
(independently of compiler optimization behavior) */
__ISB();
/* Program second word */
*(__IO uint32_t*)(Address+4U) = (uint32_t)(Data >> 32);
}
If I were using assembler I'd probably use the STRD in this context. It does expect 32-bit (4-byte) alignment of the address. The flash array expects a 64-bit (8-byte) alignment of the address.
2021-07-30 10:00 AM
Thank You, now I start to understand it.
2021-08-08 02:47 PM
Typical for ST's code. The comments show how actually incompetent the developers are. First, they talk about avoiding an instruction reorder by compiler optimization... for volatile types, which are not reordered anyway! Second, if the types where not volatile, a compiler barrier would be enough, not a pipeline flush instruction (ISB). Third, ISB doesn't even guarantee the order of memory accesses - for that there is DMB. Forth, only Cortex-M7 can reorder the memory accesses, therefore none of those instructions are actually required for Cortex-M4 in L4 series.
2021-08-15 07:07 AM
Doesnt RM mention about flushing pipeline in flash section?
2021-08-21 08:16 AM
No, it talks about flushing caches, which is a different issue and is not addressed at driver level. User code must flush caches if an executable code memory is modified.