This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Unexpected MPU fault

Hello,
I'm facing an unexpected issue while configuring the MPU on a Cortex-M7 (STM32H7). Basically, after setting the MPU in privileged thread mode, the execution continues up to when I switch to unprivileged thread mode writing into the CONTROL register. At that point, the MemManage Fault exception is triggered, signaling a stacking and instruction violation access errors. I'm confused, did I do something conceptually wrong or it can be a bug? I'm posting the code below. I've deliberately set the regions larger than needed in an effort to debug the code.

void mpu_config_test(void)
{
    ARM_MPU_Disable();

    /*
     * Set region 0 : FLASH : code
     * Normal memory, non-sharable write through, no write allocate
     * C = 1, B = 0, TEX = 0, S = 0
     * SRD = 0, XN = 0
     * AP = Privileged : Read-only / Unprivileged : Read-only
    */
    MPU->RBAR = ARM_MPU_RBAR(0U, 0x00000000);
    MPU->RASR = ARM_MPU_RASR_EX(
		0U,								/* DisableExec:  1 = disable instruction fetches */
		ARM_MPU_AP_FULL,				/* AccessPermission */
		ARM_MPU_ACCESS_NORMAL(			/* Memory access attribution */
			ARM_MPU_CACHEP_WT_NWA,		/* Outer cache policy */
			ARM_MPU_CACHEP_WT_NWA,		/* Inner cache policy */
			0							/* Sharable */
		),
		0x00UL,							/* SubRegionDisable */
		ARM_MPU_REGION_SIZE_256MB		/* Size */
	);

    /*
     * Set region 1 : SRAM : stack + global
     * Normal memory, sharable, write through, no write allocate.
     * C = 1, B = 0, TEX = 0, S = 1
     * SRD = 0, XN = 1
     * AP = Privileged : full-access / Unprivileged : full-access
    */
    MPU->RBAR = ARM_MPU_RBAR(1U, 0x20000000);
    MPU->RASR = ARM_MPU_RASR_EX(
		0U,								/* DisableExec:  1 = disable instruction fetches */
		ARM_MPU_AP_FULL,				/* AccessPermission */
		ARM_MPU_ACCESS_NORMAL(			/* Memory access attribution */
			ARM_MPU_CACHEP_WT_NWA,		/* Outer cache policy */
			ARM_MPU_CACHEP_WT_NWA,		/* Inner cache policy */
			1							/* Sharable */
		),
		0x00UL,							/* SubRegionDisable */
		ARM_MPU_REGION_SIZE_256MB		/* Size */
	);

    /* Set region 2 : peripherals
     * Device memory, sharable
     * C = 1, B = 0, TEX = 0, S = 1
     * SRD = 0, XN = 1
     * AP = Privileged : full-access / Unprivileged : full-access
    */
    MPU->RBAR = ARM_MPU_RBAR(2U, 0x40000000);
    MPU->RASR = ARM_MPU_RASR_EX(
		0U,								/* DisableExec:  1 = disable instruction fetches */
		ARM_MPU_AP_FULL,				/* AccessPermission */
		ARM_MPU_ACCESS_DEVICE(			/* Memory access attribution */
			1							/* Sharable */
		),
		0x00UL,							/* SubRegionDisable */
		ARM_MPU_REGION_SIZE_256MB		/* Size */
	);

    /* Enable default memory map as a background region for privileged access */
    ARM_MPU_Enable(MPU_CTRL_PRIVDEFENA_Msk);
}


int main()
{
	/* Initialize the system */
	/* .... */

	/* Config the MPU */
	mpu_config_test();

	/* Some other code that runs correctly */

	/* Drop down to unprivileged thread mode */
	asm volatile (	"MRS	R0, CONTROL\n\t"
					"ORR	R0, R0, #0x1\n\t"
					"MSR	CONTROL, R0\n\t" /* <-- this instruction triggers the fault */
					"ISB	\n\t"
	);
}


Thank you.