Skip to main content
Visitor II
March 21, 2019
Question

STM32H7 Internal Flash Error

  • March 21, 2019
  • 13 replies
  • 8213 views

I'm having trouble reading/writing to internal flash on an STM32H743XI. For a while I've been erasing/programming sectors of internal flash from a custom bootloader without issue but I somehow got the chip into a state now where 4 sectors can no longer be read from and instead trigger a hardfault. I think it has to do with ECC but I'm having trouble verifying that or clearing the error. The issue persists through power cycle. The HAL functions for erasing/programming flash still execute on these bad sectors and return HAL_OK but if I try to read data anywhere in these sectors the MCU hardfaults.

Anyone have an idea of what the issue is and how to resolve it?

Debugger is also unable to access this memory as shown below:

0690X0000088V9vQAE.png

    This topic has been closed for replies.

    13 replies

    Visitor II
    March 10, 2021

    I have written the bootloader for STM32H743. Normally I avoid using HAL but for this it was easier. First take care that HAL_GetTick is working correctly since it is used inside the HAL programming routines. For the reset it is quite simple code. I have had some corruption in the beginning but this was due to unfinished erase on a sector which could only be repaired with my debugger and a chip erase.

    I post my programming code.

    Erase:

    /*---------------------------------------------------------------------------*/
    /** @brief Erase a Sector of FLASH
     
    This performs all operations necessary to erase a sector in FLASH memory.
    The page should be checked to ensure that it was properly erased. A sector must
    first be fully erased before attempting to program it.
     
    See the reference manual or the FLASH programming manual for details.
     
    @param[in] sector (0 - 11 for some parts, 0-23 on others)
    */
     
    void target_flash_erase(DWORD sector_, DWORD address_)
    {
     HAL_StatusTypeDef result;
     FLASH_EraseInitTypeDef eraseType;
     uint32_t error;
     
     eraseType.TypeErase = FLASH_TYPEERASE_SECTORS;
     if(sector_ > 7u)
     {
     eraseType.Banks = FLASH_BANK_2;
     eraseType.Sector = sector_ - 8u;
     }
     else
     {
     eraseType.Banks = FLASH_BANK_1;
     eraseType.Sector = sector_; /* 0 to 7 */
     }
     eraseType.NbSectors = 1u;
     eraseType.VoltageRange = FLASH_VOLTAGE_RANGE_4;
     
     result = HAL_FLASHEx_Erase(&eraseType, &error); 
    }

    Program:

    /*---------------------------------------------------------------------------*/
    /** @brief Write a 256 bit word to FLASH
    */
    void target_flash_program_256(DWORD address_, uint64_t DataAddress_)
    {
     FLASH->CR1 |= FLASH_VOLTAGE_RANGE_4;
     FLASH->CR2 |= FLASH_VOLTAGE_RANGE_4;
     HAL_FLASH_Program(FLASH_TYPEPROGRAM_FLASHWORD, address_, DataAddress_);
    }

    Super User
    January 30, 2024

    is this trick valid for all addresses or just for FLASH?

    This should work for any non-cached address that allows byte access.

    I should deactivate interrupts during address test. What if Idon't it?

    Then an interrupt can occur in any point of the probe test, and the fault can occur because of something that the handler did.

     

     

    Graduate II
    January 31, 2024

    >This should work for any non-cached address that allows byte access.

    OK. I'm using it to check the FLASH addresses that should be cached (after sector reset I have to invalidate the cache of their addresses...), so I couldn't apply this trick?

    Graduate II
    April 12, 2024

    @Pavel A.  triple kudos for this address check!
    I'm working on a bootloader now, and this will surely prevent some hard faults.

    Still not deep enough into ARM, spent too much time with AVRs and FPGAs... ;)