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