cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H7 Flash programming issue

EStei.3
Associate III

​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 😎 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

1 REPLY 1
chrisPyres66
Associate III

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,