Extending number of MPU regions

hdtx wrote on Tuesday, February 21, 2017:

I’m using GCC on a Cortex-M4F (LPC43xx family).

I need more than the 3 configurable MPU regions for this port. I decided to do away with the privileged flash area because I don’t need it (privileged background map is enabled and my unprivileged flash area does not reach there, so privileged accesses are enabled by default and unprivleged accesses are blocked).

What I did:

  • added the fourth area to all my task parameters (all tasks are created using xTaskCreateRestricted);
  • took out the lines setting portMPU_REGION_BASE_ADDRESS_REG and portMPU_REGION_ATTRIBUTE_REG for the privileged flash area in prvSetupMPU (mpu/port.c);
  • changed a few lines at the start of mpu/portmacro.h from
#define portUNPRIVILEGED_FLASH_REGION		( 0UL )
#define portPRIVILEGED_FLASH_REGION			( 1UL )
#define portPRIVILEGED_RAM_REGION			( 2UL )
#define portGENERAL_PERIPHERALS_REGION		( 3UL )
#define portSTACK_REGION					( 4UL )
#define portFIRST_CONFIGURABLE_REGION	    ( 5UL )
#define portLAST_CONFIGURABLE_REGION		( 7UL )

to

#define portUNPRIVILEGED_FLASH_REGION		( 0UL )
#define portPRIVILEGED_RAM_REGION			( 1UL )
#define portGENERAL_PERIPHERALS_REGION		( 2UL )
#define portSTACK_REGION					( 3UL )
#define portFIRST_CONFIGURABLE_REGION	    ( 4UL )
#define portLAST_CONFIGURABLE_REGION		( 7UL )

What did not work: the fourth area is never set (whatever region I put there does not get activated).

I checked portNUM_CONFIGURABLE_REGIONS, it’s obviously 4 instead of 3 now. I looked at the FreeRTOS code and the fourth region should be working, I have no idea why it’s not. I appreciate any help.

hdtx wrote on Tuesday, February 21, 2017:

Never mind, I found it… xPortPendSVHandler in mpu/port.c only swaps in 4 regions at most (including the stack region), so I added a few lines that fixed it. If anyone has the same problem, delete line 495 and add this in its place (assuming you defined the appropriate symbol):

#if !defined(FREERTOS_EXTRA_MPU_REGION)
		"	stmia r2!, {r4-r11}					\n" // original line
#else
		"	stmia r2, {r4-r11}					\n" // don't update r2
		"	ldmia r1!, {r4-r5}					\n" // load 1 set of MPU regs
		"	stmia r2, {r4-r5}					\n" // write 1 set of MPU regs
#endif