2019-03-11 05:51 AM
Hi,
on a stm32h743 (with IAR embedded workbench IDE Version 8.30.1) i am experiencing the following Problem in the HAL_FLASH_Program function:
The Input Parameter DataAddress is reinterpreted as uint64_t* and copied to the Destination by the line
*dest_addr++ = *src_addr++;
In case of an unaligned src_addr this causes a hard fault. Having a look on the disassembly shows, that the line is translated using LDRD instruction.
According to the ARM Devices Generic User Guide the LDRD instruction is not capable of unaligned memory Access.
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0646b/BABFAIGG.html
In my usecase this problem can be fixed by changeing the reinterpretation to uint32_t* (and of course changeing the row_index to 8) which is translated using LDR instruction that is capable of unaligned Memory Access.
The disadvantage is that this is less efficient because copying is done word and not double word wise but the user is not implicitly forced to have word aligned addresses.
Furthermore this issue regards all Cortex-M3, M4 and M7 devices. But as the Flash implementation on ST's M3 and M4 devices is different, it probablywon't be an issue.
Cortex-M4: http://infocenter.arm.com/help/topic/com.arm.doc.dui0553b/DUI0553.pdf chapter 3.3.5
Cortex-M3: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0419e/index.htmlLDRD_instruction
2019-07-29 02:04 AM
Hello,
I have the same problem with the package 1.2 with STM32H743VIT and not with the 1.4 package depending of project history.
To solve this for package 1.2 :
#define FLASH_BUF_SIZE (64)
static volatile uint8_t flash_buf[FLASH_BUF_SIZE];
void flash_write(const uint32_t *src, uint32_t dst, uint32_t size)
{
// Unlock flash
HAL_FLASH_Unlock();
// Program the flash 32 bytes at a time.
for (int i=0; i<size/32; i++) {
if (HAL_FLASH_Program(TYPEPROGRAM_WORD, dst, (uint64_t)(uint32_t) src) != HAL_OK) {
// error occurred during flash write
HAL_FLASH_Lock(); // lock the flash
__fatal_error();
}
src += 8;
dst += 32;
}
// lock the flash
HAL_FLASH_Lock();
}
void callFuntion(void) {
.....
static volatile uint32_t flash_offset=0x08040000;
unsigned char DATA[64];
.....
for( ui_count=0;ui_count< FLASH_BUF_SIZE;ui_count++)
flash_buf[ui_count] = DATA[ui_count];
flash_write((uint32_t*)flash_buf, flash_offset, FLASH_BUF_SIZE);
flash_offset += FLASH_BUF_SIZE;
....
}
Good luck,