什么是Cortex-M内核的MPU(内存保护单元)?
扫描二维码
随时随地手机看文章
关注、星标公众号,不错过精彩内容
作者:strongerHuang
微信公众号:strongerHuang
估计大家经常看见MCU、MPU、MMU等这类缩写词,但你们了解什么是MPU吗?
1写在前面
不知道大家有没有关注过Cortex-M内核的一些内容,在STM32大部分型号中都有MPU。
2
认识MPU,及作用-
阻止用户应用程序破坏操作系统使用的数据。 -
阻止一个任务访问其它任务的数据区,从而把任务隔开。 -
可以把关键数据区设置为只读,从根本上消除了被破坏的可能。 -
检测意外的存储访问,如,堆栈溢出,数组越界。 -
此外,还可以通过MPU设置存储器regions的其它访问属性,比如,是否缓区,是否缓冲等。
3
了解野指针回顾一下, 什么是指针?指针在内存中实际上是一个无符号整数(unsigned int),但是它的值被赋予特殊的解释:表示变量或函数的地址。所以才被形象地称为“指针”,就好像指向谁家似的。在使用指针前, 都必须先让它指向有意义的, 并且允许由程序使用的实体——数据和代码。而所谓“野指针”, 就是指某个指针变量的值因故超出合法的范围, 使其“枪口” 乱指。程序逻辑错误、 数组越界、 堆栈溢出、 指针未经初始化、 对缓存与缓冲的处理不当、 多任务环境中的紊乱条件, 甚至是恶意地破坏等, 都可以制造出野指针。如果使用野指针去读取或修改内存, 则被读取或修改的位置是不可预料的。前者导致读回来的都是乱掉的数据, 后者则会破坏未知用途的数据。这常常导致系统发生莫名其妙的功能紊乱, 严重时会使系统毫无征兆,没有理由地失控、死机。
野指针就像“肉里的刺, 酱里的蛆” 一般:一个野指针就足以毁掉整个系统, 而且极其隐蔽, 很难通过症状来找出是哪里存在野指针, 甚至都不能判定症状是否因野指针造成(程序大了其它 bug 也很多,并且也能导致相同的症状)。对于通常的单片机系统,是没有任何办法来防止野指针的破坏的, 完全靠程序员的素质和自律。但智者千虑, 必有一失。尤其是当程序规模变得很大时,复杂度会呈指数上升,千头万绪纠缠不清, 就算是谨慎如诸葛亮,聪明如比尔·盖茨的天才,也不敢保证没有漏网之鱼。
4
进一步了解MPU5
MPU学习资料1.STM32内存映射
2.MPU 的寄存器组
特权级的程序代码(如OS内核和异常服务例程)
用户级的程序代码
特权级程序的数据存储器,位于代码区中(data_stack)
用户级程序的数据存储器,位于代码区中(data_stack)
通用的数据存储器,位于其它存储器区域中(如, SRAM)
系统设备区,只允许特权级访问,如NVIC和MPU的寄存器所有的地址区间
常规外设区,如UART, ADC等
3.Cube HAL配置MPU例子
void MPU_RegionConfig(void)
{
MPU_Region_InitTypeDef MPU_InitStruct;
/* Disable MPU */
HAL_MPU_Disable();
/* Configure RAM region as Region N°0, 8kB of size and R/W region */
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.BaseAddress = 0x20000000;
MPU_InitStruct.Size = MPU_REGION_SIZE_8KB;
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_SHAREABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER0;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.SubRegionDisable = 0x00;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/* Configure FLASH region as REGION N°1, 1MB of size and R/W region */
MPU_InitStruct.BaseAddress = 0x08000000;
MPU_InitStruct.Size = MPU_REGION_SIZE_1MB;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER1;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/* Configure FMC region as REGION N°2, 0.5GB of size, R/W region */
MPU_InitStruct.BaseAddress = 0x60000000;
MPU_InitStruct.Size = MPU_REGION_SIZE_512MB;
MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER2;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/* Enable MPU */
HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
}
C++中字符编码的转换
手把手教你用STM32Trust生成加密固件
ELF相比Hex、Bin文件格式有哪些与众不同?
长按前往图中包含的公众号关注
免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!