CPU|嵌入式开发:为什么要使用 MPU?

CPU|嵌入式开发:为什么要使用 MPU?

在你的嵌入式项目中使用MPU 可以为你节省大量的挫折、时间和金钱 。 MPU对嵌入式开发人员的最大单一好处是它能够在开发早期捕获错误 , 尽早发现错误可显着缩短开发时间 , 在项目后期修复代码中的错误可以减少文档和测试代码所需的返工 , 另一方面 , 尽早修复错误将减少项目后期代码中存在的错误数量 , 这将简化识别和修复剩余错误的过程 , 因为同时出现多个错误的可能性较小 , 这有助于你保持更可预测的时间表并防止意外延迟 。
MPU如何实现这一点?最明显的方法是保护所有与当前正在执行的代码无关的数据 。 一个简单的例子可以只用两个RTOS 任务A 和B 来构建 。 任务A 和B 不应相互交互 , 但存在一个错误 , 任务A 可能会意外写入任务B 偶尔使用的某些数据 , 覆盖此数据不影响任务A 的正确运行 。 但是当任务B 尝试使用损坏的数据时 , 任务B 可能会出现意外故障 。 如果没有配置MPU 来防止任务A 写入任务B的数据 , 这个错误可能需要嵌入式开发人员很长时间才能找到 。 如果错误很微妙或任务B 很少使用该数据 , 则此问题将特别难以解决 。 然而 , 对于MPU , 错误的写入操作会立即导致异常 , 从而让你能够确定导致错误的代码行 。
在某些架构上 , MPU甚至可以帮助你检测NULL 指针取消引用 , 因为你可以设置MPU 区域以防止非特权代码访问0x0 处的内存 。
应用程序中设计良好的一组MPU 区域可以明确保护重要的内存区域以防止出现特定问题 。 一个很好的例子是通过将缓冲区放在MPU 区域的末尾来防止缓冲区溢出 。 你还可以将你的任务堆栈放置在任何非特权代码无法访问的区域 。 如果这样做 , 那么每个任务必须使用自己的MPU 区域之一来明确授予自己对自己堆栈的访问权限 。 使用 MPU迫使你真正考虑应用程序的结构 , 以便你在任务之间干净地分离数据 , 从而产生更健壮和可维护的代码库 。

什么时候不使用MPU?
有两种主要情况使嵌入式开发人员不会在处理器上使用MPU;一个简单的项目和一个性能关键的项目 。 第一个很简单;一个非常简单的应用程序可能无法从使用MPU 所增加的复杂性中受益 。 无需设置涵盖闪存、RAM和外围设备的MPU 区域 , 你的闪烁演示可能就可以完成 。
如果你需要处理器的每一滴性能 , 那么使用MPU 的开销可能会让你大吃一惊 。 使用MPU 的FreeRTOS端口中的任务上下文切换例程更长 , 因为每个任务都有多个MPU 区域需要编程 。 当新任务被上下文切换时 , RTOS必须对每个任务MPU区域进行编程 , 并执行其通常的职责 , 例如堆叠使用过的寄存器 。 此外 , 由于内核代码和数据受MPU保护 , 因此所有内核函数调用都必须受包装函数保护 。 这个包装函数只是在调用内核函数之前提升处理器的特权级别 , 然后恢复特权并返回 。 这不仅会增加运行代码所需的时间 , 而且可能会增加任务所需的堆栈大小 。 任务的控制块还必须在其MPU 区域上存储信息 , 并且在某些安全关键RTOS(如SAFERTOS)的情况下 , 也将存储此数据的镜像 。
【CPU|嵌入式开发:为什么要使用 MPU?】你还应该警惕 , 使用MPU可能很困难 , 有时甚至令人沮丧 。 嵌入式开发人员设计应用程序需要更多时间 , 因为必须为每个任务考虑MPU区域 。 这些区域中的错误 , 例如不正确的区域长度、权限或未正确链接应用程序的数据 , 可能会导致调试混乱 。