在你的嵌入式项目中使用 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)的情况下,也将存储此数据的镜像。

你还应该警惕,使用 MPU 可能很困难,有时甚至令人沮丧。嵌入式开发人员设计应用程序需要更多时间,因为必须为每个任务考虑 MPU 区域。这些区域中的错误,例如不正确的区域长度、权限或未正确链接应用程序的数据,可能会导致调试混乱。

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论

微信小程序

微信扫一扫体验

立即
投稿

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部