Skip to main content
EStei.3
Associate III
March 11, 2019
Question

STM32H7 Flash programming issue

  • March 11, 2019
  • 1 reply
  • 1599 views

​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

This topic has been closed for replies.

1 reply

chrisPyres66
Associate III
July 29, 2019

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,