cancel
Showing results for 
Search instead for 
Did you mean: 

Memory management fault on OTP reading

Donnie
Associate

I have ported an application to STM32H563ZI which uses the OTP area to store a key. MPU is configured. Reading the UID is possible.

void Mpu::Config(void)
{
  MPU_Attributes_InitTypeDef   attr{};
  MPU_Region_InitTypeDef       region{};

  /* Disable MPU before perloading and config update */
  HAL_MPU_Disable();

  /* Define cacheable memory via MPU */
  attr.Number             = MPU_ATTRIBUTES_NUMBER0;
  attr.Attributes         = INNER_OUTER(MPU_NOT_CACHEABLE);
  HAL_MPU_ConfigMemoryAttributes(&attr);

  /* BaseAddress-LimitAddress configuration */
  region.Enable           = MPU_REGION_ENABLE;
  region.Number           = MPU_REGION_NUMBER0;
  region.AttributesIndex  = MPU_ATTRIBUTES_NUMBER0;
  region.BaseAddress      = 0x08FFF000;
  region.LimitAddress     = 0x08FFFFFF;
  region.AccessPermission = MPU_REGION_ALL_RW;
  region.DisableExec      = MPU_INSTRUCTION_ACCESS_DISABLE;
  region.IsShareable      = MPU_ACCESS_NOT_SHAREABLE;
  HAL_MPU_ConfigRegion(&region);

  /* Enable the MPU */
  HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
}

Reading the OTP area results in a memory management fault.

static void CopyKey(uint32_t* out)
{
  const volatile uint32_t * otp = reinterpret_cast<const volatile uint32_t *>(FLASH_OTP_BASE);
  for(uint16_t c = 0; c < MeterKey::LENGTH; c++) {
    out[c] = otp[c];
  }
}

See error registers:

HFSR  = 00000000
CFSR  = 00000082
ICSR  = 0440F804
AIRCR = FA052300
SCR   = 00000000
CCR   = 00000201
SHCSR = 00010001
DFSR  = 0000000B
MMFAR = 08FFF000
BFAR  = 08FFF000
AFSR  = 00000000
CPACR = 00F00000
FLASH->ECCDETR = 00000000

I have no idea why I could not read the OTP area. As you can see I get no ECC error. The first 16 bytes of block 0 are written.

Updated 24.03.2025: Added controller STM32H563ZI

3 REPLIES 3
CMYL
ST Employee

Hello @Donnie 

Which STM32 family you are using ?

 

Best regards

Sorry.

STM32H563ZI

CMYL
ST Employee

Hello @Donnie,

I did a simple check with a very simple code as you can see below:

For your Test issue:

- May be you kept the code used for programming the OTP. Because, writing twice an OTP 16-bit word will generate ECC error (NMI).

- Another hypothesis, the debugger is reading OTP regions. Debugger will read non-programmed OTP or programmed regions twice and will cause NMI as well. In this case, avoid memory view of OTPs.

In my test:

Initially, I programmed the addresses from 0x08fff000 to 0x08fff020. 

Then, I read the programmed OTP with a simple for loop:

 

  for(flash_address= 0x08fff000; flash_address < 0x08fff020; flash_address = flash_address +4)
  {
    uint32_t c_ad;
    c_ad = *((uint32_t*) flash_address);
    printf("\n\r OTP = 0x%08x ", c_ad); 
  }

 

I'm able to read the OTP addresses as depicted below: 

CMYL_1-1742831517908.png

best regards,

Younes