cancel
Showing results for 
Search instead for 
Did you mean: 

How do I create a non cacheable memory area that requires 512Kb + 256Kb

Claydonkey
Senior

Using STM32 HAL and a STM32H7 (I know some dissuade the usage of this). I have created 2 MPU Regions of non cacheable memory .

void MPU_Config(void) {
 
	MPU_Region_InitTypeDef MPU_InitStruct = { 0 };
	/* Disables the MPU */
	HAL_MPU_Disable();
	/** Initializes and configures the Region and the memory to be protected
	 */
	MPU_InitStruct.Enable = MPU_REGION_ENABLE;
	MPU_InitStruct.Number = MPU_REGION_NUMBER0;
	MPU_InitStruct.BaseAddress = 0x24060000;
	MPU_InitStruct.Size = MPU_REGION_SIZE_512KB;
	MPU_InitStruct.SubRegionDisable = 0;
	MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
	MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
	MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
	MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
	MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
 
	MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE
	HAL_MPU_ConfigRegion(&MPU_InitStruct);
 
	/** Initializes and configures the Region and the memory to be protected
	 */
	MPU_InitStruct.Number = MPU_REGION_NUMBER1;
	MPU_InitStruct.BaseAddress = 0x240E0000;
	MPU_InitStruct.Size = MPU_REGION_SIZE_128KB;
	MPU_InitStruct.SubRegionDisable = 0x0;
	HAL_MPU_ConfigRegion(&MPU_InitStruct);
	/* Enables the MPU */
	HAL_MPU_Enable(MPU_HFNMI_PRIVDEF);
 
}
 

and created a loader:

MEMORY
{
...
 RAM (xrw)   : ORIGIN = 0x24000000, LENGTH = 384K
 RAM_NOCACHE (xrw)   : ORIGIN = 0x24060000, LENGTH = 1024K - 384K
...
}
 
...
 
  .DATA_RAM_NOCACHE (NOLOAD) :
 {  . = ALIGN(4);
  *(.DATA_RAM_NOCACHE)     
  *(.DATA_RAM_NOCACHE*) 
  . = ALIGN(4);    
 } >RAM_NOCACHE 

When using memory of just 512Kb with 1 MPU area defined things work as expected but a Hard Fault occurs when I try the above - a memory alignment error - more details to follow...)

Is this because there are 2 regions. How can it be done thanks

1 ACCEPTED SOLUTION

Accepted Solutions
Pavel A.
Evangelist III

> MPU_InitStruct.BaseAddress = 0x24060000;

> MPU_InitStruct.Size = MPU_REGION_SIZE_512KB;

Base address of a region must be aligned on the region size.

View solution in original post

3 REPLIES 3
Claydonkey
Senior

empty

Pavel A.
Evangelist III

> MPU_InitStruct.BaseAddress = 0x24060000;

> MPU_InitStruct.Size = MPU_REGION_SIZE_512KB;

Base address of a region must be aligned on the region size.

Claydonkey
Senior

Does that mean that starting at 0x24060000 - 3 * 256Kb areas should be assigned?

> MPU_InitStruct.Number = MPU_REGION_NUMBER0;

> MPU_InitStruct.BaseAddress = 0x24060000;

> MPU_InitStruct.Size = MPU_REGION_SIZE_256KB;

> MPU_InitStruct.Number = MPU_REGION_NUMBER1;

> MPU_InitStruct.BaseAddress = 0x240A0000;

> MPU_InitStruct.Size = MPU_REGION_SIZE_256KB;

> MPU_InitStruct.Number = MPU_REGION_NUMBER2;

> MPU_InitStruct.BaseAddress = 0x240E0000;

> MPU_InitStruct.Size = MPU_REGION_SIZE_256KB;

Does that mean that starting at 0x24060000 - a 1 * 128Kb area ?

and at at 0x24080000 a 1 * 512Kb region?

Obvs tried it and bingo!

Works a charm. Thank you