H750XB 的内存地址划分
M7 处理器的内存映射:(标准来源于 ARM)
ARM 划定了一个大致的内存分配区间,如上图所示。各个厂商再根据自己芯片的实际情况进行详细的划分。
如 STM32H750XB 芯片的划分如下。H750XB 芯片的内存划分:(来源于H750XB参考手册第二章第二节)
H750XB 芯片各个 SRAM 所能支持的大小:
在工程中进行 MPU 配置
MPU_InitStruct 结构体各项说明:
typedef struct
{
uint8_t Enable; /*!< Specifies the status of the region.
This parameter can be a value of @ref CORTEX_MPU_Region_Enable */
uint8_t Number; /*!< Specifies the number of the region to protect.
This parameter can be a value of @ref CORTEX_MPU_Region_Number */
uint32_t BaseAddress; /*!< Specifies the base address of the region to protect.*/
uint8_t Size; /*!< Specifies the size of the region to protect.
This parameter can be a value of @ref CORTEX_MPU_Region_Size */
uint8_t SubRegionDisable; /*!< Specifies the number of the subregion protection to disable.
This parameter must be a number between Min_Data = 0x00
and Max_Data = 0xFF */
uint8_t TypeExtField; /*!< Specifies the TEX field level.
This parameter can be a value of @ref CORTEX_MPU_TEX_Levels */
uint8_t AccessPermission; /*!< Specifies the region access permission type.
This parameter can be a value of @ref
CORTEX_MPU_Region_Permission_Attributes */
uint8_t DisableExec; /*!< Specifies the instruction access status.
This parameter can be a value of @ref
CORTEX_MPU_Instruction_Access */
uint8_t IsShareable; /*!< Specifies the shareability status of the protected region.
This parameter can be a value of @ref
CORTEX_MPU_Access_Shareable */
uint8_t IsCacheable; /*!< Specifies the cacheable status of the region protected.
This parameter can be a value of @ref
CORTEX_MPU_Access_Cacheable */
uint8_t IsBufferable; /*!< Specifies the bufferable status of the protected region.
This parameter can be a value of @ref
CORTEX_MPU_Access_Bufferable */
}MPU_Region_InitTypeDef;
-
Enable:指定是否使能某个 MPU 单元;
-
Number:用于指定该 MPU 单元的序号。在 H750XB 芯片中最多可以支持 16 个 Region(区域),序号越大优先级就越高。当两个 Region 出现重叠时,以高优先级的 Region 的属性为主;
-
BaseAddress:指定 Region 的启始地址。可以参考上面的 H750XB 内存分配详细情况进行配置;
-
Size:区域大小;
-
SubRegionDisable:一个区域能够被划分成8个相等大小子区域。
对于划分的原区域需要大于等于 256 bytes,对于小于 256 bytes 的区域,该行为的未定义的。要划分子区域可以通过设置 MPU_RASR 寄存器的 SRD 域来实现,该域有 8 位,因此可以分别控制 8 个子区域的使能与否。(这也是只能划分 8 个子区域的原因)
least significant 的位控制第一个子区域,most significant 的位控制最后一个子区域。
设置位 0x00 表示使能所有区域。
对于未使能的区域,该子区域的属性不受主区域的控制,如果没有 background Region 或者其它覆盖在该子区域上的 other Region,那么对该子区域的访问将会触发一个 fault 错误。
-
DisableExec:指示是否可以存取指令(instruction);
-
TypeExtField、IsShareable、IsCacheable、IsBufferable 的设置参考下图:
write-back、write and read allocate 等术语的说明可以参考:
write-back/write-through/write-allocate/write-no-allocate说明_Bin Watson的博客-CSDN博客
在代码中的 MPU 配置,由 MPU_Config()
来完成:
static void MPU_Config( void )
{
MPU_Region_InitTypeDef MPU_InitStruct;
/* 禁止 MPU */
HAL_MPU_Disable();
/* 配置AXI SRAM的MPU属性为Write back, Read allocate,Write allocate */
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.BaseAddress = 0x24000000;
MPU_InitStruct.Size = MPU_REGION_SIZE_512KB;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER0;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL1;
MPU_InitStruct.SubRegionDisable = 0x00;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/* 配置FMC扩展IO的MPU属性为Device或者Strongly Ordered */
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.BaseAddress = 0x60000000;
MPU_InitStruct.Size = ARM_MPU_REGION_SIZE_64KB;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE; /* 不能用MPU_ACCESS_CACHEABLE;会出现2次CS、WE信号 */
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER1;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.SubRegionDisable = 0x00;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/* 配置SRAM1的属性为Write through, read allocate,no write allocate */
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.BaseAddress = 0x30000000;
MPU_InitStruct.Size = ARM_MPU_REGION_SIZE_128KB;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER2;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.SubRegionDisable = 0x00;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/* 配置SRAM2的属性为Write through, read allocate,no write allocate */
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.BaseAddress = 0x30020000;
MPU_InitStruct.Size = ARM_MPU_REGION_SIZE_128KB;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER3;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.SubRegionDisable = 0x00;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/* 配置SRAM3的属性为Write through, read allocate,no write allocate */
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.BaseAddress = 0x30040000;
MPU_InitStruct.Size = ARM_MPU_REGION_SIZE_32KB;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER4;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.SubRegionDisable = 0x00;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/* 配置SRAM4的属性为Write through, read allocate,no write allocate */
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.BaseAddress = 0x38000000;
MPU_InitStruct.Size = ARM_MPU_REGION_SIZE_64KB;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER5;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.SubRegionDisable = 0x00;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/*使能 MPU */
HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
}