How can I read the UICR->OTP register of nrf9160?

I want to use the OTP register for production, but I don’t have permission to read the contents of the OTP register。

The following are my steps:

1.Allow the UICR area to be readable in the secure_services.c file.

__TZ_NONSECURE_ENTRY_FUNC
int spm_request_read_nse(void *destination, uint32_t addr, size_t len)
{
	static const struct read_range ranges[] = {
#ifdef PM_MCUBOOT_ADDRESS
		/* Allow reads of mcuboot metadata */
		{.start = PM_MCUBOOT_PAD_ADDRESS,
		 .size = PM_MCUBOOT_PAD_SIZE},
#endif
		{.start = FICR_PUBLIC_ADDR,
		 .size = FICR_PUBLIC_SIZE},
		{.start = FICR_RESTRICTED_ADDR,
		 .size = FICR_RESTRICTED_SIZE},
		 
		{.start = NRF_UICR_S_BASE,
		 .size = sizeof(NRF_UICR_Type)},

	};

	if (destination == NULL || len <= 0) {
		return -EINVAL;
	}

	if (ptr_in_secure_area((intptr_t)destination)) {
		return -EINVAL;
	}

	for (size_t i = 0; i < ARRAY_SIZE(ranges); i++) {
		uint32_t start = ranges[i].start;
		uint32_t size = ranges[i].size;

		if (addr >= start && addr + len <= start + size) {
			memcpy(destination, (const void *)addr, len);
			return 0;
		}
	}

	return -EPERM;
}

2.Read the value of OTP through the function spm_request_read().

static int read_uicr_word(uint32_t *result, const volatile uint32_t *addr)
{
	printk("Read UICR (address 0x%08x):\n", (uint32_t)addr);
	int ret = spm_request_read(result, (uint32_t)addr, sizeof(uint32_t));

	if (ret != 0) {
		printk("Could not read UICR (err: %d)\n", ret);
	}
	return ret;
}

void main(void){
    //omission
    uint32_t otp;
    if (read_uicr_word(&otp, &NRF_UICR_S->OTP[0]) == 0) {
                printk("NRF_UICR_S->OTP[0] = 0x%08X\n\n", otp);
	}
	
}

3.Through the log, I found that the value of OPT[0] is 0xDEADDEAD, which means I don’t have permission to get the value of the register.

Read UICR (address 0x00ff8108):
NRF_UICR_S->OTP[0] = 0xDEADDEAD

The following is a description of the KMU register.

https://infocenter.nordicsemi.com/topic/ps_nrf9160/uicr.html#register.KEYSLOT.CONFIG.PERM

infocenter.nordicsemi.com/.../kmu.html

The diagram here describes that OTP is always readable, and most of the content describes how to use key storage.

I accessed the KMU register in the application(ns) and found no effect. Do KMU registers need to be accessed in spm?

How can I obtain permission to read the OTP register. Are there any related demos?

Parents Reply Children
Related