2025-03-19 4:25 AM
I have ported an application 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(®ion);
/* 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.