STM32H7系列MPU与CACHE以及RAM

一、启用cache

启用cache很简单,就是这两句,分别打开I-Cache和D-Cache,但是如果只使用这两句,再操作DMA和FLASH时就很有可能遇到问题,后面会具体说明。

    SCB_EnableICache();//使能I-Cache
    SCB_EnableDCache();//使能D-Cache

二、使用MPU

这里是一个RAM的MPU保护配置。

    /* 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 = D1_AXISRAM_BASE;
    MPU_InitStruct.Size = MPU_REGION_SIZE_512KB;
    MPU_InitStruct.SubRegionDisable = 0x0;
    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_NOT_SHAREABLE;
    MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
    MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;

    HAL_MPU_ConfigRegion(&MPU_InitStruct);

    /* Enables the MPU */
    HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);

首先是配置MPU时需要先关闭MPU,HAL_MPU_Disable();启用HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);其中的参数是MPU的控制策略

//默认区域(default region)不允许访问,并且在硬故障,NMI和FAULTMASK处理程序期间禁用MPU
#define  MPU_HFNMI_PRIVDEF_NONE      ((uint32_t)0x00000000)    
//默认区域(default region)不允许访问,并且在硬故障,NMI和FAULTMASK处理程序期间启用MPU
#define  MPU_HARDFAULT_NMI           ((uint32_t)0x00000002)
//默认区域(default region)仅允许特权访问,并且在硬故障,NMI和FAULTMASK处理程序期间禁用MPU
#define  MPU_PRIVILEGED_DEFAULT      ((uint32_t)0x00000004)
//默认区域(default region)仅允许特权访问,并且在硬故障,NMI和FAULTMASK处理程序期间启用MPU
#define  MPU_HFNMI_PRIVDEF           ((uint32_t)0x00000006)

第一个配置参数MPU_InitStruct.Enable,可以赋值是为MPU_REGION_ENABLE、MPU_REGION_DISABLE,分别代表这个区域的MPU是否启用。

第二个配置参数MPU_InitStruct.Number,可以赋值MPU_REGION_NUMBER0、MPU_REGION_NUMBER1、MPU_REGION_NUMBER2...一共是8个,代表所配置保护内存区域的编号。

第三个配置参数MPU_InitStruct.BaseAddress,可以赋值的就是各个内存块的首地址,这里的D1_AXISRAM_BASE是0x24000000,是一个512K的RAM。

第四个配置参数MPU_InitStruct.Size,就是所保护内存的大小,MPU_REGION_SIZE_512KB就是要保护区域的大小,还有其他大小可选,具体可以看宏定义中所定义的大小。

第五个配置参数MPU_InitStruct.SubRegionDisable,是配置子区域,每个MPU配置的内存区域都被分为了8个子区域,数值从0~255,每一个bit对应着一个子区域的禁用(1)或者启用(0)。最高位(控制最后一个子区域,最低位控制第一个子区域,最后注意的是大于128字节才可以使用子区域。

第六个配置参数MPU_InitStruct.AccessPermission是配置RAM的读写权限。

/** @defgroup CORTEX_MPU_Region_Permission_Attributes CORTEX MPU Region Permission Attributes
  * @{
  */
#define  MPU_REGION_NO_ACCESS      ((uint8_t)0x00)    //禁止所有情况下的访问(读/写)
#define  MPU_REGION_PRIV_RW        ((uint8_t)0x01)    //仅允许在特权模式下读写
#define  MPU_REGION_PRIV_RW_URO    ((uint8_t)0x02)    //特权模式下可读写,用户模式下只读
#define  MPU_REGION_FULL_ACCESS    ((uint8_t)0x03)    //完全访问,特权和用户模式下都可以读写
#define  MPU_REGION_PRIV_RO        ((uint8_t)0x05)    //仅允许在特权模式下读取
#define  MPU_REGION_PRIV_RO_URO    ((uint8_t)0x06)    //特权和用户模式下都只读

第七个配置参数MPU_InitStruct.DisableExec,表示代码是否在RAM中可执行,MPU_INSTRUCTION_ACCESS_ENABLE代表可执行。

最后的4个参数需要一起看,

MPU_InitStruct.TypeExtField;MPU_InitStruct.IsShareable;MPU_InitStruct.IsCacheable;MPU_InitStruct.IsBufferable

TypeExtField

IsCacheable IsBufferable IsShareable cache功能
MPU_TEX_LEVEL0 1 0 x Write through, no write allocate
MPU_TEX_LEVEL0 1 1 x Write back, no write allocate
MPU_TEX_LEVEL1 0 0 x Non-cacheable
MPU_TEX_LEVEL1 1 1 x Write back, write and read allocate

1.Write through, no write allocate(透写)

(1)写入策略:如果cache命中,则同时向cache和对应的内存区域中写入;如果未命中,则只写入对应的内存区域,不开辟新的cache。
(2)读取策略:如果cache命中,则直接从cache中读取,不再读取对应的内存区域,如果cache未命中,则开辟对应的cache区域,并从对应的内存区域中将数据同步至cache,并读取cache。

2.Write back, write and read allocate

(1)写入策略:如果cache命中,则只写入cache,不再写入到对应的内存区域;如果未命中,则开辟对应的cache,并同时向cache和对应的内存区域写入。
(2)读取策略:如果cache命中,则直接从cache中读取,不再读取对应的内存区域,如果cache未命中,则开辟对应的cache区域,并从对应的内存区域中将数据同步至cache,并读取cache。

3.Write back, no write allocate

(1)写入策略:如果cache命中,则只写入cache,不再写入到对应的内存区域;如果未命中,则只写入对应的内存区域,不开辟新的cache。
(2)读取策略:如果cache命中,则直接从cache中读取,不再读取对应的内存区域,如果cache未命中,则开辟对应的cache区域,并从对应的内存区域中将数据同步至cache,并读取cache。

通过上面介绍的特性,可以看到,使用的时候最好使用Write through, no write allocate这种模式,因为cache命中,则同时向cache和对应的内存区域中写入,不用担心数据的不统一。H7系列使用cache代码的执行速度提高两倍以上,当然这个两倍只是我大概试了一下。

三、RAM

1.TCM区

速度 地址 总线 大小
ITCM 400MHz 0x0000 0000 64bit 64KB
DTCM 400MHz 0x2000 0000 64bit 128KB

2.AXI SRAM区

速度 地址 总线 大小
AXI SRAM 200MHz 0x2400 0000 64bit 512KB

3.SRAM1、SRAM2、SRAM3区

速度 地址 总线 大小
SRAM1 200MHz 0x3000 0000 32bit 128KB
SRAM2 200MHz 0x3002 0000 32bit 128KB
SRAM3 200MHz 0x3004 0000 32bit 32KB

4.SRAM4区

速度 地址 总线 大小
SRAM4 200MHz 0x3800 0000 32bit 64KB

5.Backup SRAM区

速度 地址 总线 大小
Backup SRAM 200MHz 0x3880 0000 32bit 4KB

STM32H7系列MPU与CACHE以及RAM_第1张图片

结合这张图,可以看出ITCM、DTCM、AXI SRAM是不可以使用DMA的。

如果使用了可以使用DMA的SRAM,需要注意,如果开启了CACHE,记得要配置MPU,否则DMA数据很有可能是不更新的。再操作flash的时候,也要注意清除D-CACHE,否则写入会有问题。

你可能感兴趣的:(stm32,嵌入式硬件,单片机)