2024-08-06 09:25 AM
Hello everyone,
I'm working on an in-application firmware update for an STM32H7 series microcontroller. The process involves erasing and then writing to the flash memory. I can successfully erase bank 2, but I'm encountering an issue when writing to the flash.
Issue Description: After the first 256 bits (flash-word) are written without any error, the subsequent write operations result in an inconsistency error. Interestingly, even though the HAL_FLASH_Program function returns an error, when I compare the write buffer with the flash memory, all the data appears to have been written correctly.
Code Snippet:
HAL_StatusTypeDef flash_write(uint32_t address, uint8_t* data, size_t size) { HAL_StatusTypeDef status = HAL_OK; HAL_FLASH_Unlock(); for (size_t i = 0; i < size; i += 8) { if (address + i <= (FLASH_END_ADDRESS - 8)) { status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_FLASHWORD, address + i, (uint32_t )data + i); // if (status != HAL_OK) { // break; // Exit if there's an error // } // Verify the content of flash with RAM if (*(uint32_t*)(address + i) != *(uint32_t*)(data + i)) { status = HAL_ERROR; // Set an error status if verification fails break; } else { status = HAL_OK; } } else { status = HAL_ERROR; // Set an error status if out of bounds break; } } HAL_FLASH_Lock(); return status; }
Observations:
Questions:
Any insights or suggestions would be greatly appreciated!
Solved! Go to Solution.
2024-08-06 10:19 AM
I found the issue, and it turns out to be a simple mistake on my part. I mistakenly increased the iteration pointer by 8 instead of 8 * 4. That was causing the problem.
Based on the reference manual:
A wrap burst request issued by a master overlaps two or more 256-bit flash-word addresses, i.e. wrap bursts must be done within 256-bit flash-word address boundaries.
This misalignment was causing the inconsistency error I encountered. Correcting the iteration step resolved the issue.
Thank you all for your help and suggestions!
2024-08-06 09:31 AM
This is almost certainly a caching issue.
Make the pointer which reads from flash volatile (volatile uint32_t*) which forces the cpu to read it every time.
2024-08-06 09:53 AM
Thank you so much for your reply!
I appreciate your suggestion about making the pointer volatile. However, in my case, I'm passing a constant value as parameters like this:
if(flash_write(0x08100000, (uint8_t *)0x92000000, 205556) == HAL_OK)
Inside the HAL_FLASH_Program function, the addresses are already cast to volatile pointers:
__IO uint32_t *dest_addr = (__IO uint32_t *)FlashAddress; __IO uint32_t *src_addr = (__IO uint32_t*)DataAddress;
This should inherently make the pointers volatile. Additionally, I've tried disabling the cache and using zero compiler optimization, but the issue still persists.
Could there be any other reasons for this inconsistency error, or perhaps something specific to the STM32H7 flash memory behavior?
2024-08-06 10:19 AM
I found the issue, and it turns out to be a simple mistake on my part. I mistakenly increased the iteration pointer by 8 instead of 8 * 4. That was causing the problem.
Based on the reference manual:
A wrap burst request issued by a master overlaps two or more 256-bit flash-word addresses, i.e. wrap bursts must be done within 256-bit flash-word address boundaries.
This misalignment was causing the inconsistency error I encountered. Correcting the iteration step resolved the issue.
Thank you all for your help and suggestions!