自学内容网 自学内容网

【单片机外设】MPU及Cache学习与开发

 该篇主要:参考正点原子教程和安富莱教程

安富莱_STM32-V7_MPU及Cache部分.pdf


目录

1. 内存保护单元(MPU)介绍(了解)

1.1. 内存保护单元(memory protection unit),简称:MPU

1.1.1. MPU的功能:

1.1.2. MPU的好处:

MPU可作为管理员:管理权限、管理通行规则和路径

具体好处

1.2. MPU的使用:

1.2.1. MPU配置保护内存区域:

1.2.1.1. 默认配置的保护区域:背景区,序号(-1)

1.2.1.2. 可配置的保护内存区域:0-15

1.2.2. MPU设置内存区域的访问权限:MPU_REGION_XX_XX - XXX访问

1.2.3. MPU配置内存区域的访问属性:内存类型(Normal/Device/S..o..)

三种内存类型对应的情景:可缓存,可缓冲,可共享

可共享:主机(Master)间数据同步

不同配置下(访问属性:内存类型,是否缓存,是否缓冲,是否共享)的性能情况:

2. Cache简介(了解)

2.1. Cache简介:

2.2. Cache使用:对SRAM的-读操作、写操作

2.2.1. Core读Cache:读操作

2.2.2. Core写Cache:写操作

2.3. 数据不一致问题解决:

3. MPU相关寄存器介绍(熟悉)

3.1. MPU类型寄存器(MPU_TYPE):是否支持MPU,可配置8(F7)/16(H7)个保护区域

3.2. MPU控制寄存器(MPU_CTRL):设置MPU使能

PRIVDEFENA位的影响:

M3:

H7:

3.3. MPU区域编号寄存器(MPU_RNR):选中要配置的(0-7(F7)/0-15(H7))区域

3.4. MPU基地址寄存器(MPU_RBAR):设置区域的起始地址

3.5. MPU区域属性和容量寄存器(MPU_RASR):设置每个区域的属性【重点】

XN位:指令访问

AP位:访问权限,通常使用全访问

TEX位:设置Cache策略

SRD位:使能当前区域的子区域

4. MPU相关HAL库驱动介绍(掌握)

4.1. void HAL_MPU_Enable(uint32_t MPU_Control)

4.2. MPU HAL相关结构体-MPU_Region_InitTypeDef

5. MPU基本配置步骤(掌握)

5.1. 通过配置TEX C B S =>> 来配置内存类型,Cache策略

6. 编程实战——分析总框图!!!(掌握)

6.1. 实战代码

6.2. 分析总框图(全屏看)

可以通过微调整来实现程序高速运行,前提是稳定性

7. H7的内存模型:H7内存默认映射与属性

7.1. H7内存默认映射

8. 通过Keil Debug来查看MPU配置(MDK局限:只能显示8个区域)

8.1. 菜单栏打开:

8.2. Memory Protection Unit (MPU)工具

8.3. 执行完MPU配置代码后,在工具内查看MPU配置情况

9. 课堂总结


1. 内存保护单元(MPU)介绍(了解)

1.1. 内存保护单元(memory protection unit),简称:MPU

1.1.1. MPU的功能:

  • 设置不同存储区域的存储器访问权限(特权级、用户级)
  • 设置存储器(内存和外设)属性(可缓存、可缓冲、可共享)

1.1.2. MPU的好处:

MPU可作为管理员:管理权限、管理通行规则和路径

具体好处

1.2. MPU的使用:

1.2.1. MPU配置保护内存区域:

MPU可配置保护8/16个内存区域,每个区域最小要求256字节,且每个区域还可配置为8个子区域(大小一样)

H7的存储器映射:

  • STM32的地址空间共4GB(即有2^32个地址),需要将地址和内存映射起来。
  • ST将这些地址划分成块,根据不同芯片中内存大小,映射长度也不同。
    • 每个地址映射1个(u8)字节

  • F7可配置8个保护内存区域,单个区域>256字节,并且可细分为8个子区域
  • H7可配置16个保护内存区域,单个区域>256字节,并且可细分为8个子区域

16(>256,不一致)*8(相同大小)

此处配置内存区域的范围是整个单片机的内核地址

1.2.1.1. 默认配置的保护区域:背景区,序号(-1)

对没有配置保护规则的内存区域统一管理

1.2.1.2. 可配置的保护内存区域:0-15
  • 编号为优先级:0~15 优先级越来越高
  • (配置)规则:访问属性和权限
  • 重叠或嵌套下,重叠部分按着优先级高的内存区配置规则执行

1.2.2. MPU设置内存区域的访问权限:MPU_REGION_XX_XX - XXX访问

1.2.3. MPU配置内存区域的访问属性:内存类型(Normal/Device/S..o..)

Strongly ordered:强序

三种内存类型对应的情景:可缓存,可缓冲,可共享

三种内存类型的性能体现

  • Normal
  • Device
  • S..o..

可共享:主机(Master)间数据同步
  • 适用范围:
    • 多主机访问单从机时
    • 另一个主机的数据可能还在缓存中,未同步到从机上
    • 那当前主机访问的从机数据就是有误的
  • 共享使能:
    • 开启共享 ≈ 关闭Cache
    • 开关共享: 读操作速度影响大,写操作基本没有影响

不同配置下(访问属性:内存类型,是否缓存,是否缓冲,是否共享)的性能情况:

2. Cache简介(了解)

Cache:高级缓存,结合MPU使用(由MPU来指定内存区域的Cache策略)

F4有MPU但是没有Cache,所以一般不用MPU

2.1. Cache简介:

  • Cache:高级缓存(因为处于CPU中,主频与CPU一致)
    • 可实现
  • Cache分为:
    • 数据缓存D-Cache
      • 可解决CPU加速访问SRAM

SRAM主频<CPU主频

    • 指令缓存I-Cache
  • Cache操作:由MPU指定区域的Cache策略
    • 使能
    • 禁止
    • 清空
    • 无效化

2.2. Cache使用:对SRAM的-读操作、写操作

  • 读写命中:Cache hit
  • 读写丢失:Cache miss

2.2.1. Core读Cache:读操作

Core可以理解为CPU

RT RA对应处理方式的缩写

2.2.2. Core写Cache:写操作

Core可以理解为CPU

WT WB NWA对应处理方式的缩写

2.3. 数据不一致问题解决:

  • 设置共享

浪费了Cache资源

  • 软件对Cache进行维护:在读写操作之前,调用解决对应情况的api

Cache配置相关函数:

SCB_EnableICache
SCB_DisableICache
SCB_InvalidateICache
SCB_EnableDCache
SCB_DisableDCache
SCB_InvalidateDCache
SCB_CleanDCache
SCB_CleanInvalidateDCache
SCB_InvalidateDCache_by_addr
SCB_CleanDCache_by_addr
SCB_CleanInvalidateDCache_by_addr

3. MPU相关寄存器介绍(熟悉)

Region:区域

📎Cortex M3权威指南(中文).pdf

📎STM32H7编程手册.pdf

3.1. MPU类型寄存器(MPU_TYPE):是否支持MPU,可配置8(F7)/16(H7)个保护区域

通过对DREGION的配置:MPU支持的区域数量

  • 0:不支持MPU
  • >0:支持MPU
    • 0x08
    • 0x10

3.2. MPU控制寄存器(MPU_CTRL):设置MPU使能

PRIVDEFENA位的影响:

M3:

H7:

3.3. MPU区域编号寄存器(MPU_RNR):选中要配置的(0-7(F7)/0-15(H7))区域

3.4. MPU基地址寄存器(MPU_RBAR):设置区域的起始地址

3.5. MPU区域属性和容量寄存器(MPU_RASR):设置每个区域的属性【重点】

XN位:指令访问

功能是在该区域能不能执行代码

AP位:访问权限,通常使用全访问

TEX位:设置Cache策略

不同配置下(访问属性:内存类型,是否缓存,是否缓冲,是否共享)的性能情况

注意,性能由TEX,C,B,S等其他共同影响的

SRD位:使能当前区域的子区域

15:8的每一位,给0:子region使能,1:失能

直接给SRD0x00,代表全使能

4. MPU相关HAL库驱动介绍(掌握)

这里仅讲使能、配置(主要讲结构体)函数

4.1. void HAL_MPU_Enable(uint32_t MPU_Control)

MPU_HFNMI_PRIVDEF_NONE
MPU_HARDFAULT_NMI
MPU_PRIVILEGED_DEFAULT
MPU_HFNMI_PRIVDEF

使用:HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);

4.2. MPU HAL相关结构体-MPU_Region_InitTypeDef

将配置好的该结构体对象,传入

5. MPU基本配置步骤(掌握)

5.1. 通过配置TEX C B S =>> 来配置内存类型,Cache策略

6. 编程实战——分析总框图!!!(掌握)

解读工程📎H750-实验12 内存保护(MPU)实验.zip

6.1. 实战代码

/**
 ****************************************************************************************************
 * @file        mpu.c
 * @author      正点原子团队(ALIENTEK)
 * @version     V1.0
 * @date        2020-03-22
 * @brief       MPU内存保护 驱动代码
 * @license     Copyright (c) 2020-2032, 广州市星翼电子科技有限公司
 ****************************************************************************************************
 * @attention
 *
 * 实验平台:正点原子 STM32H750开发板
 * 在线视频:www.yuanzige.com
 * 技术论坛:www.openedv.com
 * 公司网址:www.alientek.com
 * 购买地址:openedv.taobao.com
 *
 * 修改说明
 * V1.0 20200322
 * 第一次发布
 *
 ****************************************************************************************************
 */

#include "./SYSTEM/usart/usart.h"
#include "./SYSTEM/delay/delay.h"
#include "./BSP/LED/led.h"
#include "./BSP/MPU/mpu.h"


/**
 * @brief       设置某个区域的MPU保护
 * @param       baseaddr: MPU保护区域的基址(首地址)
 * @param       size:MPU保护区域的大小(必须是32的倍数,单位为字节)
 * @param       rnum:MPU保护区编号,范围:0~15,最大支持16个保护区域
 * @param       de:禁止指令访问;0,允许指令访问;1,禁止指令访问
 * @param       ap:访问权限,访问关系如下:
 *   @arg       0,无访问(特权&用户都不可访问)
 *   @arg       1,仅支持特权读写访问
 *   @arg       2,禁止用户写访问(特权可读写访问)
 *   @arg       3,全访问(特权&用户都可访问)
 *   @arg       4,无法预测(禁止设置为4!!!)
 *   @arg       5,仅支持特权读访问
 *   @arg       6,只读(特权&用户都不可以写)
 *   @note      详见:STM32H7编程手册.pdf,4.6.6节,Table 91.
 * @param       sen:是否允许共用;0,不允许;1,允许
 * @param       cen:是否允许cache;0,不允许;1,允许
 * @param       ben:是否允许缓冲;0,不允许;1,允许
 * @retval      0, 成功; 1, 错误;
 */
uint8_t mpu_set_protection(uint32_t baseaddr, uint32_t size, uint32_t rnum, uint8_t de, uint8_t ap, uint8_t sen, uint8_t cen, uint8_t ben)
{
    MPU_Region_InitTypeDef mpu_region_init_handle;           /* MPU初始化句柄 */
    HAL_MPU_Disable();                                       /* 配置MPU之前先关闭MPU,配置完成以后在使能MPU */

    mpu_region_init_handle.Enable = MPU_REGION_ENABLE;       /* 使能该保护区域 */
    mpu_region_init_handle.Number = rnum;                    /* 设置保护区域 */
    mpu_region_init_handle.BaseAddress = baseaddr;           /* 设置基址 */
    mpu_region_init_handle.Size = size;                      /* 设置保护区域大小 */
    mpu_region_init_handle.SubRegionDisable = 0X00;          /* 禁止子区域 */
    mpu_region_init_handle.TypeExtField = MPU_TEX_LEVEL0;    /* 设置类型扩展域为level0 */
    mpu_region_init_handle.AccessPermission = ap;            /* 设置访问权限 */
    mpu_region_init_handle.DisableExec = de;                 /* 是否允许指令访问 */
    mpu_region_init_handle.IsShareable = sen;                /* 是否允许共享 */
    mpu_region_init_handle.IsCacheable = cen;                /* 是否允许cache */
    mpu_region_init_handle.IsBufferable = ben;               /* 是否允许缓冲 */
    HAL_MPU_ConfigRegion(&mpu_region_init_handle);           /* 配置MPU */
    
    HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);                  /* 开启MPU */
    return 0;
}

/**
 * @brief       设置需要保护的存储块
 * @note        必须对部分存储区域进行MPU保护,否则可能导致程序运行异常
 *              比如MCU屏不显示,摄像头采集数据出错等等问题
 * @param       无
 * @retval      无
 */
void mpu_memory_protection(void)
{
    /* 保护整个DTCM,共128K字节,允许指令访问,禁止共用,允许cache,允许缓冲 */
    mpu_set_protection(0x20000000, MPU_REGION_SIZE_128KB, MPU_REGION_NUMBER1, MPU_INSTRUCTION_ACCESS_ENABLE,
                       MPU_REGION_FULL_ACCESS, MPU_ACCESS_NOT_SHAREABLE, MPU_ACCESS_CACHEABLE, MPU_ACCESS_BUFFERABLE);

    /* 保护整个AXI SRAM,共512K字节,允许指令访问,禁止共用,允许cache,允许缓冲 */
    mpu_set_protection(0x24000000, MPU_REGION_SIZE_512KB,MPU_REGION_NUMBER2, MPU_INSTRUCTION_ACCESS_ENABLE,
                       MPU_REGION_FULL_ACCESS, MPU_ACCESS_NOT_SHAREABLE, MPU_ACCESS_CACHEABLE, MPU_ACCESS_BUFFERABLE);

    /* 保护整个SRAM1~SRAM3,共288K字节,允许指令访问,禁止共用,允许cache,允许缓冲 */
    mpu_set_protection(0x30000000, MPU_REGION_SIZE_512KB,MPU_REGION_NUMBER3, MPU_INSTRUCTION_ACCESS_ENABLE,
                       MPU_REGION_FULL_ACCESS, MPU_ACCESS_NOT_SHAREABLE, MPU_ACCESS_CACHEABLE, MPU_ACCESS_BUFFERABLE);

    /* 保护整个SRAM4,共64K字节,允许指令访问,禁止共用,允许cache,允许缓冲 */
    mpu_set_protection(0x38000000, MPU_REGION_SIZE_64KB, MPU_REGION_NUMBER4, MPU_INSTRUCTION_ACCESS_ENABLE,
                       MPU_REGION_FULL_ACCESS, MPU_ACCESS_NOT_SHAREABLE, MPU_ACCESS_CACHEABLE, MPU_ACCESS_BUFFERABLE);

    /* 保护MCU LCD屏所在的FMC区域,,共64M字节,允许指令访问,禁止共用,禁止cache,禁止缓冲 */
    mpu_set_protection(0x60000000, MPU_REGION_SIZE_64MB, MPU_REGION_NUMBER5, MPU_INSTRUCTION_ACCESS_ENABLE,
                       MPU_REGION_FULL_ACCESS, MPU_ACCESS_NOT_SHAREABLE, MPU_ACCESS_NOT_CACHEABLE, MPU_ACCESS_NOT_BUFFERABLE);

    /* 保护SDRAM区域,共64M字节,允许指令访问,禁止共用,允许cache,允许缓冲 */
    mpu_set_protection(0XC0000000, MPU_REGION_SIZE_64MB, MPU_REGION_NUMBER6, MPU_INSTRUCTION_ACCESS_ENABLE,
                       MPU_REGION_FULL_ACCESS, MPU_ACCESS_NOT_SHAREABLE, MPU_ACCESS_CACHEABLE, MPU_ACCESS_BUFFERABLE);

    /* 保护整个NAND FLASH区域,共256M字节,禁止指令访问,禁止共用,禁止cache,禁止缓冲 */
    mpu_set_protection(0X80000000, MPU_REGION_SIZE_256MB, MPU_REGION_NUMBER7, MPU_INSTRUCTION_ACCESS_DISABLE,
                       MPU_REGION_FULL_ACCESS, MPU_ACCESS_NOT_SHAREABLE, MPU_ACCESS_NOT_CACHEABLE, MPU_ACCESS_NOT_BUFFERABLE);
}

/**
 * @brief       MemManage错误处理中断
 *   @note      进入此中断以后,将无法恢复程序运行!!
 *
 * @param       无
 * @retval      无
 */
void MemManage_Handler(void)
{
    LED1(0);                            /* 点亮LED1(GREEN LED) */
    printf("Mem Access Error!!\r\n");   /* 输出错误信息 */
    delay_ms(1000);
    printf("Soft Reseting...\r\n");     /* 提示软件重启 */
    delay_ms(1000);
    NVIC_SystemReset();                 /* 软复位 */
}

6.2. 分析总框图(全屏看)

可以通过微调整来实现程序高速运行,前提是稳定性

7. H7的内存模型:H7内存默认映射与属性

参考H7的编程手册📎STM32H743勘误手册.pdf📎STM32H7xx参考手册(V3中文版).pdf📎STM32H7xx参考手册.pdf📎STM32H7编程手册.pdf

7.1. H7内存默认映射

8. 通过Keil Debug来查看MPU配置(MDK局限:只能显示8个区域)

8.1. 菜单栏打开:

8.2. Memory Protection Unit (MPU)工具

8.3. 执行完MPU配置代码后,在工具内查看MPU配置情况

9. 课堂总结

内存保护(MPU)实验(课堂总结).pdf


原文地址:https://blog.csdn.net/m0_74209072/article/details/144289282

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!