STM32 MPU(Memory Protection Unit,内存保护单元)是STM32微控制器中的一个重要功能模块,用于增强系统的安全性和稳定性。它通过定义内存区域的访问权限,防止非法访问或意外修改关键数据,从而避免系统崩溃或数据损坏。
1. MPU 的主要功能
内存区域划分:将内存划分为多个区域,每个区域可独立配置。
访问权限控制:为每个区域设置读、写、执行权限。
特权级别控制:区分特权和非特权访问,限制非特权代码对关键资源的访问。
异常处理:当发生非法访问时,触发异常(如MemManage Fault),便于调试和错误处理。
2. MPU 的配置步骤
定义内存区域:
确定区域的起始地址和大小。
选择区域编号(STM32通常支持8个区域)。
设置访问权限:
配置读、写、执行权限。
设置特权和非特权访问权限。
启用区域:
通过MPU寄存器启用配置的区域。
启用MPU:
在系统控制寄存器中启用MPU。
3. MPU 寄存器
MPU_TYPE:指示MPU支持的区域数量。
MPU_CTRL:控制MPU的启用和默认内存映射。
MPU_RNR:选择当前配置的区域编号。
MPU_RBAR:设置区域的基地址。
MPU_RASR:配置区域大小和访问权限。
对于MPU的基本配置,可以使用STM32CubeMX软件工具来完成,该开发工具可以使我们的学习变得更加轻松便捷。
在CubeMX中配置MPU涉及到设置内存地址、访问权限和Cache规则,以实现对AXISRAM的高速访问。以下是配置MPU的基本步骤:
设置MPU控制模式: MPU控制模式有四种,可以通过配置MPU_CTRL寄存器来选择。例如,可以选择“Background Region Privileged access only + MPU Enable during hard fault, NMI and FAULTMASK handlers”,这意味着在硬件故障、NMI和FAULTMASK处理程序期间,只有特权软件可以访问默认内存映射。
配置MPU区域: 在MPU区域设置中,需要使能MPU区域,并设置基地址(例如0x1000)和区域大小(例如512KB)。此外,还需要配置子区域禁用、TEX域等级、访问权限、指令访问等等;
MPU软件软件代码分享:
void MPU_Config(void)
{
MPU_Region_InitTypeDef MPU_InitStruct = {0};
/* Disables the MPU */
HAL_MPU_Disable();
/** Initializes and condivs the Region and the memory to be protected
*/
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER0;
MPU_InitStruct.BaseAddress = 0x1000;
MPU_InitStruct.Size = MPU_REGION_SIZE_512B;
MPU_InitStruct.SubRegionDisable = 0x0;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL1;
MPU_InitStruct.AccessPermission = MPU_REGION_NO_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_BUFFERABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/* Enables the MPU */
HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
}
在主函数中,直接执行之前编写好的串口输出代码
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5);
/* Insert delay 500ms */
HAL_Delay(500);
printf("Hello STM32! Hello congconggege! Hello STM32U083RC!\r\n");
// if (HAL_RNG_GenerateRandomNumber(&hrng, &aRandom32bit) != HAL_OK)
// {
// /* Random number generation error */
// Error_Handler();
// }
// printf("aRandom32bit=%16d\r\n",aRandom32bit);
}
注意事项
区域重叠:多个区域重叠时,编号较高的区域优先级更高。
性能影响:启用MPU可能增加内存访问延迟,需权衡安全性与性能。
调试:非法访问会触发异常,调试时需检查异常处理机制。
应用场景
RTOS任务隔离:在多任务系统中,保护各任务的内存区域。
固件保护:防止关键代码或数据被篡改。
外设保护:限制对关键外设寄存器的访问。
全部评论