理解与应用 MPU的特权与用户模式 前言5 P2 R( X; i$ q8 j$ b STM32系列支持MPU内存保护单元,可用来设定内存的属性和访问权限。MPU的应用笔记提到,将属性寄存器(MPU_RASR)配置成某一个值,在特权(Privileged permissions)和用户模式(Unprivileged permissions)的访问许可是不同的,甚至可将用户模式的权限设置成不可访问。那么,什么是MPU的特权模式和用户模式呢? 接下来我们在这篇文章来理解这些名词,并讨论在STM32 MCU代码中如何使用内存保护单元MPU的特权与用户模式。1 W9 N$ I$ }; Q5 d! x 8 j% _3 |, w* _5 L4 i) O+ A MPU(Memory Protection Unit)& S) L; ^6 }8 C# N3 S( O MPU内存保护单元可以用来使嵌入式系统更加健壮与安全。它可以阻止用户应用程序破坏系统关键数据。它可以通过将内存SRAM区域定义成不可执行,来阻止代码注入型攻击。也可以用来改变内存的性质,例如是否允许缓存(Cache)。: Q: L% ^) i. y8 i: d 用来设置内存属性的 MPU_RASR寄存器字段描述如下:4 H( i# t' q( x! g+ ? 图表 1 MPU_RASR字段# g6 Y5 M! E% P $ W7 n. ]6 a. X 在MPU_RASR中用来设置数据访问许可的AP字段详细设置选项如下: 1 l: m: o/ E N. D- l: T' T7 D 图表 2 内存访问权限设置' Q) x1 x' M5 _* M) | ( P% ^2 r. k( Z9 d 特权模式(Privileged mode)与用户模式(UnPrevileged mode) 特权模式与用户模式是指Cortex内核的执行模式。它不是MPU的一部分,但与MPU单元有关联。当代码运行在特权模式下,代码拥有所有的访问许可;而代码运行在用户模式,则访问权限受限制。限制包括在系统设计阶段就定义的可运行指令限制,可访问内存以及外设限制。也包括由MPU单元动态所定义的内存访问规则。2 a5 x8 N; t. Z" W# s" x 从特权模式进入用户模式,只需使用MSR指令操作CONTROL寄存器。但是,不可以直接从用户模式转入特权模式,必须经过一个异常处理操作模式,比如SVC( Supervisor Calls)。在异常处理通过操作CONTROL寄存器,可从用户模式回到特权模式。请注意,特权线程与异常处理线程,都是在特权模式下运行。 如下图所示: , A2 {( B! B3 t# x* k 在代码中结合特权与用户模式使用MPU* g {; T! t, d( r0 S# `& t/ J. z6 | 1. 开发环境 开发板: STM32 L476RG NUCLEO 开发工具:STM32Cube_FW_L4_V1.7.0$ I! v3 p0 c7 J a* ~6 I IAR/Keil 注:也可以选择其他STM32系列并选择相应的开发板与固件库。 2. 开发目标定义 在软件中定义一块数组,使用MPU将该区域配成仅可从特权模式下进行访问,并验证用户模式下访问会导致内存管理异常或者硬错误。 . X! F# f" l& f# r: U g4 r 图表 3 特权模式与用户模式的切换' Y" Y! @3 i/ N- Q1 q f) G 3. 代码资源与整合 STM32 Cube固件库提供了大量的例程供学习和重用。查找STM32Cube_FW_L4_V1.6.0可以发现,固件库已分别实现了特权模式与用户模式的切换(CORTEXM_ModePrivilege),和MPU的配置(CORTEXM_MPU)。& F, W2 @' Q9 W# O2 X 我们需要将两个例程整合在一起来实现我们的开发目标。注意你选择其他STM32系列也是没有问题的,也支持MPU功能。9 `. a+ \1 K# ?' G& }3 D8 C 复制CORTEXM_MPU\Src\stm32_mpu.c 到CORTEXM_ModePrivilege\Src目录下 复制CORTEXM_MPU\Inc\stm32_mpu.h到CORTEXM_ModePrivilege\Inc目录下 打开CORTEXM_ModePrivilege工程文件,将stm32_mpu.c和stm32_mpu.h添加到工程文件中。IAR与Keil略有不同,在IAR下只需添加C文件。 2 X. L' W, E( Z' c # m8 g, M- z0 S6 L7 Z0 Z 4. 修改与增加代码$ a7 D3 U; J% k3 B0 a 新增加的代码以红色表示; y, Z7 L3 k% E8 g0 B. \7 t ●在主程序中包含stm32_mpu.h- j* I5 s/ N0 P* o ●在主程序里调用MPU配置函数 n& z! {0 d6 F$ E( |0 o9 [ 要对使用的内存进行MPU配置,未被MPU配置的资源将视之为不可访问。这是MPU_Config必须被使用的原因。 ●修改MPU_AccessPermConfig将数组区域配置成我们设计的权限并增加测试代码。 MPU_AccessPermConfig在特权模式下运行,故测试代码不会触发异常。1 V* A, q, f4 J- v ●在用户模式下尝试读写数组 参考代码中直接访问数组,很容易被编译器优化掉而不能发挥测试作用。这里加了个判断后写的操作,使编译器不去优化它。 至此,可以编译成功运行来体会特权模式与用户模式的MPU的不同配置。执行到主程序中新加的数组访问代码,会产生内存管理异常。6 n L$ E6 Q# [ D 5. 关键代码分析2 D) e, X, X: A; K ●从特权模式进入用户模式。直接设置CONTROL寄存器。 ●从用户模式回到特权模式,需要触发异常处理 ●在异常处理中将线程回到特权模式执行( E8 h# u) n5 L4 L6 U" o) w5 W ●若用户模式下代码试图访问无权限数据将产生内存管理异常,从而进入下述函数。 : [( w" Y3 K+ d5 ^. Z: `0 @ 6 o+ y* H" [9 _) K* S5 H 结论 本文档介绍了MPU的特权与用户模式,并整合与修改已有代码进行了应用。在实际中可将MPU与Cortex运行模式结合,可使应用更加健壮与安全。 文档下载 # d) J- z w! u) @8 U& W 更多实战经验# H/ ]; P0 {: d+ }* e7 ~5 s |
【STM32MP135-DK】裸机移植shell
【STM32MP13DK】 在Linux主机上交叉编译一个Hello Word应用
STM32MP135F-DK 开箱&开发环境搭建&硬件设计分析
意法半导体在意大利建SiC整合制造厂
轻松地实现ClassB在STM32CubeIDE上的移植
ST历史小知识(6)- 与世界共同塑造美好明天
ST历史小知识(5)- SiC衬底进一步发展
ST历史小知识(4)- 投资未来
ST历史小知识(3) - 布局新兴半导体工艺
ST历史小知识(2)-多重应用,走出低谷
谢谢分享