6EP1931-2DC21 内存保护单元(MPU)是一种硬件机制,通过只允许代码访问需要的内存和外设来提高嵌入式设备的安全性。应用程序可以组织为进程(process),每个进程访问自己的内存和外设。MPU不仅阻止应用程序代码访问其区域以外的内存或外设,而且还可以用于检测堆栈溢出。
我们基于ARM Cortex-M MCU中的MPU,讨论一下MPU所提供的一些特性。
MPU是什么?
内存保护单元(MPU)是一种硬件机制,只允许需要访问某些资源的代码访问相应的内存和外设。MPU常用于安全关键应用,如医疗设备、航空电子设备、工业控制、核电站等,提高嵌入式应用的稳定性和安全性。
在IoT应用中,也可以通过MPU限制对内存和外设的访问,提高产品的安全性。例如,可以通过MPU机制隐藏加密密钥以拒绝攻击者访问;使用MPU隔离Flash控制器也可以防止攻击者更改应用程序,只允许受信任的代码执行代码更新。
通过MPU将RTOS任务划分为进程,如图1所示。每个进程可以包含任意数量的任务。进程内的任务可以访问分配给该进程的内存和外设。增加MPU时,从任务的角度几乎不用更改,除非任务之间存在交互。
进程间可以通过共享内存进行通信,两个进程的MPU配置表中将出现相同的区域。
应用中也可以包含具有完全权限的系统级任务和ISR,允许它们访问所有内存、外设或CPU。
当违规发生时,系统的行为取决于应用程序,是哪个任务违规。例如,如果违规是由图形用户界面(GUI)造成的,可以终止并重新启动GUI,并且不会影响系统的其它部分。但是,如果违规任务控制一个制动器,则异常处理程序可能需要在重启任务之前立即停止制动器。
理想情况下,在产品开发过程中会捕获并纠正访问违规,否则,系统设计人员将需要评估所有可能的结果,并决定发生这种情况时该做什么。
使用MPU检测堆栈溢出
在基于RTOS的应用中,每个任务都需要单独的堆栈空间。堆栈溢出可能是基于RTOS的系统开发人员所面临的最常见的问题之一。如果没有硬件帮助,堆栈溢出检测可以由软件实现,但软件方式不能及时捕获溢出,可能导致产品不稳定。MPU可以帮助防止堆栈溢出。
MPU域可用于堆栈溢出检测,使用一个小的域(RedZone)来覆盖每个任务堆栈的底部。配置MPU属性,如果有任何代码尝试写入该区域,将触发MPU异常。域的大小决定了该方法在捕获堆栈溢出方面的效率。
区域越大,堆栈溢出捕获的可能性就越大,同时堆栈可用的RAM就越少。换言之,RedZone域被认为是不可用的内存,它被用来检测非法写入。开始时可以将RedZone大小设置为32个字节,如果任务堆栈为512个字节,那么32个字节约占用6%,剩余480个字节的可用堆栈空间。
另一种检测方法是将整个任务堆栈封装为一个MPU区域,允许读写操作。该方法有两个问题:首先,在Cortex-M(ARMv7M架构)上,堆栈的大小需为2的幂,并且必须在幂边界(即32、64、128、256、512等)上对齐。
如果嵌入式应用有足够的RAM,那么这不是问题;然而,在资源受限的应用 (如Cortex-M MCU)中,在减少浪费的同时设置合适的堆栈内存会很复杂。其次,该方法不允许写同一进程中的其它任务堆栈,不允许进程中的任务通过堆栈传递信息。
6EP1931-2DC21 IC697BEM713 IC697BEM721 IC697BEM731
IC697BEM733 IC697BEM741 IC697BEM761
IC697CBL700 IC697CBL709 IC697CBL803
IC697CBL811 IC697CBL826 IC697CGR772
IC697CGR935 IC697CMM711
IC697CMM712 IC697CMM741 IC697CMM742
IC697CPM790 IC697CPU731 IC697CPU780
IC697CPU788 IC697CPU789 IC697CPX772
IC697CPX782 IC697CPX928 IC697CPX935
IC697CSE784 IC697CSE925 IC697GDH701
IC697GDS701 IC697HSC700 IC697LBR701
IC697MCS704 IC697MDL240 IC697MDL241
IC697MDL250 IC697MDL251 IC697MDL252
IC697MDL253 IC697MDL254 IC697MDL340
IC697MDL341 IC697MDL350 IC697MDL640
IC697MDL651 IC697MDL652 IC697MDL653
IC697MDL654 IC697MDL671 IC697MDL740
IC697MDL750 IC697MDL752 IC697MDL753
IC697MDL940 IC697MEM713 IC697MEM715
IC697MEM717 IC697MEM719 IC697MEM731
IC697MEM732 IC697MEM733 IC697MEM735
IC697MLX000 IC697MSC800 IC697MSC801
IC697MSC802 IC697PCM711 IC697PWR710
IC697PWR711 IC697PWR720 IC697PWR724
IC697PWR748 IC697RCM711 IC698ACC701 IC698ACC720
IC698ACC735 IC698CHS009 IC698CHS017