买了原子的STM32H7R开发板,主要关注HyperRAM和HyperFlash的用法。 

第一次看了sys_mpu_config函数的代码,没看懂,反复看有点心得

1. MPU的作用

MPU:Memory Protection Unit,内存保护单元。

MPU存储器保护单元,它可以实施对存储器(主要是内存和外设寄存器)的保护,以使软件更加健壮和可靠。在使用前,必须根据需要对其编程。如果没有启用MPU,则等同于系统中没有配MPU。

MPU有如下的能力可以提高系统的可靠性:

  • 阻止用户应用程序破坏操作系统使用的数据。

  • 阻止一个任务访问其它任务的数据区,从而把任务隔开。

  • 可以把关键数据区设置为只读,从根本上消除了被破坏的可能。

  • 检测意外的存储访问,如,堆栈溢出,数组越界。

  • 此外,还可以通过MPU设置存储器regions的其它访问属性,比如,是否缓区,是否缓冲等。

2. 内存分配

3. 最多设置16个Region,设置的时候,只能依次设置Regon0,Region1,。。。

   区域可以覆盖,Region Number越高优先级越高

#define MPU_REGION_NUMBER0 0U
#define MPU_REGION_NUMBER1 1U
#define MPU_REGION_NUMBER2 2U
#define MPU_REGION_NUMBER3 3U
#define MPU_REGION_NUMBER4 4U
#define MPU_REGION_NUMBER5 5U
#define MPU_REGION_NUMBER6 6U
#define MPU_REGION_NUMBER7 7U
#define MPU_REGION_NUMBER8 8U
#define MPU_REGION_NUMBER9 9U
#define MPU_REGION_NUMBER10 10U
#define MPU_REGION_NUMBER11 11U
#define MPU_REGION_NUMBER12 12U
#define MPU_REGION_NUMBER13 13U
#define MPU_REGION_NUMBER14 14U
#define MPU_REGION_NUMBER15 15U

4. TEX与S C B组合有不同的访问方式

 对应三种访问形式:

Strongly Ordered Memory(强序内存):这种内存类型适用于访问特定的外设寄存器和共享内存区域等,它的访问顺序不能被改变。在这种内存类型下,访问该内存区域的数据会直接被发送到总线上,而不会被缓存。

Device Memory(设备内存):这种内存类型适用于访问外设的数据缓冲区和寄存器等,它的访问顺序可以被改变。在这种内存类型下,访问该内存区域的数据会被缓存,但缓存策略不同于普通的数据缓存。

Normal Memory(普通内存):这种内存类型适用于访问普通的数据和程序代码等,它的访问顺序可以被改变。在这种内存类型下,访问该内存区域的数据会被缓存,并且可以使用通用的缓存策略,如写回、写直通等。 

5 AccessPermission决定了访问形式(不可访问、只读、只写、读写)

 

#define MPU_REGION_NO_ACCESS 0U
#define MPU_REGION_PRIV_RW 1U
#define MPU_REGION_PRIV_RW_URO 2U
#define MPU_REGION_FULL_ACCESS 3U
#define MPU_REGION_PRIV_RO 5U
#define MPU_REGION_PRIV_RO_URO 6U

6. 一般先设置背景域(4GB范围)

7. 源码【原子开发板提供】

void sys_mpu_config(void)
{
MPU_Region_InitTypeDef mpu_region_init_struct = {0};
uint32_t region_index = 0;

/* 关闭MPU */
HAL_MPU_Disable();

/* 配置背景域(0x00000000~0xFFFFFFFF,4GB) */
mpu_region_init_struct.Enable = MPU_REGION_ENABLE;
mpu_region_init_struct.Number = region_index++;
mpu_region_init_struct.BaseAddress = 0x00000000;
mpu_region_init_struct.Size = MPU_REGION_SIZE_4GB;
mpu_region_init_struct.SubRegionDisable = 0x87;
mpu_region_init_struct.TypeExtField = MPU_TEX_LEVEL0;
mpu_region_init_struct.AccessPermission = MPU_REGION_NO_ACCESS;
mpu_region_init_struct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
mpu_region_init_struct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
mpu_region_init_struct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
mpu_region_init_struct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
HAL_MPU_ConfigRegion(&mpu_region_init_struct);

/* 配置ITCM对应区域(0x00000000~0x0000FFFF,64KB) */
mpu_region_init_struct.Enable = MPU_REGION_ENABLE;
mpu_region_init_struct.Number = region_index++;
mpu_region_init_struct.BaseAddress = 0x00000000;
mpu_region_init_struct.Size = MPU_REGION_SIZE_64KB;
mpu_region_init_struct.SubRegionDisable = 0x00;
mpu_region_init_struct.TypeExtField = MPU_TEX_LEVEL1;
mpu_region_init_struct.AccessPermission = MPU_REGION_FULL_ACCESS;
mpu_region_init_struct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
mpu_region_init_struct.IsShareable = MPU_ACCESS_SHAREABLE;
mpu_region_init_struct.IsCacheable = MPU_ACCESS_CACHEABLE;
mpu_region_init_struct.IsBufferable = MPU_ACCESS_BUFFERABLE;
HAL_MPU_ConfigRegion(&mpu_region_init_struct);

/* 配置DTCM对应区域(0x20000000~0x2000FFFF,64KB) */
mpu_region_init_struct.Enable = MPU_REGION_ENABLE;
mpu_region_init_struct.Number = region_index++;
mpu_region_init_struct.BaseAddress = 0x20000000;
mpu_region_init_struct.Size = MPU_REGION_SIZE_64KB;
mpu_region_init_struct.SubRegionDisable = 0x00;
mpu_region_init_struct.TypeExtField = MPU_TEX_LEVEL1;
mpu_region_init_struct.AccessPermission = MPU_REGION_FULL_ACCESS;
mpu_region_init_struct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
mpu_region_init_struct.IsShareable = MPU_ACCESS_SHAREABLE;
mpu_region_init_struct.IsCacheable = MPU_ACCESS_CACHEABLE;
mpu_region_init_struct.IsBufferable = MPU_ACCESS_BUFFERABLE;
HAL_MPU_ConfigRegion(&mpu_region_init_struct);

/* 配置AXI-SRAM1~4对应区域(0x24000000~0x24071FFF,456KB) */
mpu_region_init_struct.Enable = MPU_REGION_ENABLE;
mpu_region_init_struct.Number = region_index++;
mpu_region_init_struct.BaseAddress = 0x24000000;
mpu_region_init_struct.Size = MPU_REGION_SIZE_512KB;
mpu_region_init_struct.SubRegionDisable = 0x00;
mpu_region_init_struct.TypeExtField = MPU_TEX_LEVEL1;
mpu_region_init_struct.AccessPermission = MPU_REGION_FULL_ACCESS;
mpu_region_init_struct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
mpu_region_init_struct.IsShareable = MPU_ACCESS_SHAREABLE;
mpu_region_init_struct.IsCacheable = MPU_ACCESS_CACHEABLE;
mpu_region_init_struct.IsBufferable = MPU_ACCESS_BUFFERABLE;
HAL_MPU_ConfigRegion(&mpu_region_init_struct);

/* 配置AHB-SRAM1~2对应区域(0x30000000~0x30007FFF,32KB) */
mpu_region_init_struct.Enable = MPU_REGION_ENABLE;
mpu_region_init_struct.Number = region_index++;
mpu_region_init_struct.BaseAddress = 0x30000000;
mpu_region_init_struct.Size = MPU_REGION_SIZE_32KB;
mpu_region_init_struct.SubRegionDisable = 0x00;
mpu_region_init_struct.TypeExtField = MPU_TEX_LEVEL1;
mpu_region_init_struct.AccessPermission = MPU_REGION_FULL_ACCESS;
mpu_region_init_struct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
mpu_region_init_struct.IsShareable = MPU_ACCESS_SHAREABLE;
mpu_region_init_struct.IsCacheable = MPU_ACCESS_CACHEABLE;
mpu_region_init_struct.IsBufferable = MPU_ACCESS_BUFFERABLE;
HAL_MPU_ConfigRegion(&mpu_region_init_struct);

/* 配置FMC LCD对应区域(0x60000000~0x63FFFFFF,64MB) */
mpu_region_init_struct.Enable = MPU_REGION_ENABLE;
mpu_region_init_struct.Number = region_index++;
mpu_region_init_struct.BaseAddress = 0x60000000;
mpu_region_init_struct.Size = MPU_REGION_SIZE_64MB;
mpu_region_init_struct.SubRegionDisable = 0x00;
mpu_region_init_struct.TypeExtField = MPU_TEX_LEVEL0;
mpu_region_init_struct.AccessPermission = MPU_REGION_FULL_ACCESS;
mpu_region_init_struct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
mpu_region_init_struct.IsShareable = MPU_ACCESS_SHAREABLE;
mpu_region_init_struct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
mpu_region_init_struct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
HAL_MPU_ConfigRegion(&mpu_region_init_struct);

/* 配置XSPI NOR Flash对应区域(0x90000000~0x91FFFFFF,32MB) */
mpu_region_init_struct.Enable = MPU_REGION_ENABLE;
mpu_region_init_struct.Number = region_index++;
mpu_region_init_struct.BaseAddress = 0x90000000;
mpu_region_init_struct.Size = MPU_REGION_SIZE_32MB;
mpu_region_init_struct.SubRegionDisable = 0x00;
mpu_region_init_struct.TypeExtField = MPU_TEX_LEVEL1;
mpu_region_init_struct.AccessPermission = MPU_REGION_FULL_ACCESS;
mpu_region_init_struct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
mpu_region_init_struct.IsShareable = MPU_ACCESS_SHAREABLE;
mpu_region_init_struct.IsCacheable = MPU_ACCESS_CACHEABLE;
mpu_region_init_struct.IsBufferable = MPU_ACCESS_BUFFERABLE;
HAL_MPU_ConfigRegion(&mpu_region_init_struct);

/* 配置XSPI HyperRAM对应区域(0x70000000~0x71FFFFFF,32MB) */
mpu_region_init_struct.Enable = MPU_REGION_ENABLE;
mpu_region_init_struct.Number = region_index++;
mpu_region_init_struct.BaseAddress = 0x70000000;
mpu_region_init_struct.Size = MPU_REGION_SIZE_32MB;
mpu_region_init_struct.SubRegionDisable = 0x00;
mpu_region_init_struct.TypeExtField = MPU_TEX_LEVEL1;
mpu_region_init_struct.AccessPermission = MPU_REGION_FULL_ACCESS;
mpu_region_init_struct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
mpu_region_init_struct.IsShareable = MPU_ACCESS_SHAREABLE;
mpu_region_init_struct.IsCacheable = MPU_ACCESS_CACHEABLE;
mpu_region_init_struct.IsBufferable = MPU_ACCESS_BUFFERABLE;
HAL_MPU_ConfigRegion(&mpu_region_init_struct);

/* 使能MPU */
HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
}

posted on 2025-01-13 11:34  Muniar  阅读(400)  评论(0)    收藏  举报