cancel
Showing results for 
Search instead for 
Did you mean: 

Strange data read protection(?) after failed write to internal flash

Arno1
Senior

I'm working on creating a sfu loader to load sfb files from an external flash on a port I made for the STM32H735 (based on NUCLEO-H753ZI)

I follow the same steps as used in the ymodem loader:

  • read and verify header (reusing SFU_LOADER_VerifyFwHeader)
  • erase active image in slot 1 (single slot config, starting at 0x08020000, ends at 0x080FFFFF) and set m_uDwlAreaAddress to m_uDwlAreaStart.
  • run SE_Decrypt_Init
  • write header to m_uDwlAreaAddress (== m_uDwlAreaStart) and increment it with SFU_IMG_IMAGE_OFFSET (1024)
  • for each chunk of data
    • SE_Decrypt_Append
    • pad extra bytes if needed
    • write to internal flash.

It's at the last step that it fails during write. Writing the header succeeds however and using STM32CubeProgrammer I can verify the written data is correct.

The first chunk is 1024B and is written to address 0x08020400.

Looking into SFU_LL_FLASH_INT_Write() it turns out it fails on verification of the written data (if memcmp:(

if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_FLASHWORD, destination, (source + i)) == HAL_OK)
{
  /* Check the written value */
  if (memcmp((void *)destination, (void *)(source + i), sizeof(SFU_LL_FLASH_write_t)) != 0)
  {

I added the following bit of code:

for (int ctr = 0; ctr < sizeof(SFU_LL_FLASH_write_t); ctr++) {
    TRACE ("\r\n%02X %02X", *(uint8_t*)(source + i + ctr), *(uint8_t*)(destination + ctr));
}

Which gives me

59 2800000
F4 2800000
33 2800000
C4 2800000
73 2800000
2A 2800000
75 2800000
...

Then, trying to read that part of flash memory (0x08020000, 0x400B) using STM32CubeProgrammer I get an error Error: Data read failed but the option bytes all seem to be fine. No read or write protection is active (all SBSFU protections are disabled: SECBOOT_DISABLE_SECURITY_IPS is defined).

Any idea on what I'm missing?

Thank you.

Arno.

1 ACCEPTED SOLUTION

Accepted Solutions
Jocelyn RICARD
ST Employee

Hello Arno,

yes this is strange indeed.

As you made the porting from a 2 bank to 1 bank, I would suggest having a look to the STM32CubeFW H7 example in STM32Cube_FW_H7_V1.9.0\Projects\STM32H735G-DK\Examples\FLASH\FLASH_EraseProgram\ if not already done;

Also, I would recommend double checking your clocking/flash WS/ Voltage level

Best regards

Jocelyn

View solution in original post

4 REPLIES 4
Arno1
Senior

turns out the HardFault_Handler in sfu_low_level_flash_int.c is being triggered as well.

in the hard fault, the ecc flag is tested and seems to be set:

  if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_DBECCE_BANK1RR)/* || __HAL_FLASH_GET_FLAG(FLASH_FLAG_DBECCE_BANK2RR)*/)
  {
 
      TRACE("\r\n double ecc error \r\n");
    __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_DBECCE_BANK1RR);
//    __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_DBECCE_BANK2RR);
 
    /* Memorize error to ignore the read value */
    DoubleECC_Error_Counter++;
 
...

which seems strange because this is an almost brand new board (STM32H735G-DK).

Jocelyn RICARD
ST Employee

Hello Arno,

yes this is strange indeed.

As you made the porting from a 2 bank to 1 bank, I would suggest having a look to the STM32CubeFW H7 example in STM32Cube_FW_H7_V1.9.0\Projects\STM32H735G-DK\Examples\FLASH\FLASH_EraseProgram\ if not already done;

Also, I would recommend double checking your clocking/flash WS/ Voltage level

Best regards

Jocelyn

Hi Jocelyn,

Thank you once more for your help!

Changing

p_erase_init.VoltageRange = FLASH_VOLTAGE_RANGE_3;

to

p_erase_init.VoltageRange = FLASH_VOLTAGE_RANGE_4;

did the trick. I also made sure to update SECoreBin- se_low_level.c with

p_erase_init.VoltageRange = FLASH_VOLTAGE_RANGE_4

Thank you again.

Best regards,

Arno