0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

如何按进程对RAM进行分组与Cortex-M MPU使用建议

星星科技指导员 来源:嵌入式计算设计 作者:Jean Labrosse 2022-06-10 07:19 次阅读

在本系列关于将 RTOS 与 MPU 结合使用的最后一部分中,我们将了解如何按进程对 RAM 进行分组,并以使用 Cortex-M MPU 时的建议列表作为结尾。

到目前为止,我们已经了解了 MPU 是什么以及它如何帮助将任务和流程相互隔离。我们还研究了如何设置 Cortex-M MPU,发现它非常易于使用。使用 MPU 的复杂性更多地与组织应用程序的内存有关,而不是更新这个非常有用的设备的机制。

在本系列关于将 RTOS 与 MPU 结合使用的最后一部分中,我们将了解如何按进程对 RAM 进行分组,并以使用 Cortex-M MPU 时的建议列表作为结尾。

创建 MPU 进程表

使用 MPU 时最大的困难可能是按进程对内存进行分组并创建 MPU 进程表。这部分是因为您需要更深入地了解您的工具链:编译器、汇编器和链接器/定位器。

假设我使用的是 IAR 工具链(即 EWARM),但概念非常相似,您可以根据自己使用的工具调整这些概念。除非另有说明,否则链接器会将数据(即 RAM)放置在图 2 所示的三个部分之一中。

未初始化的数据

零初始化数据

初始化数据

顾名思义,未初始化的数据对应于在编译时未赋予初始值或未声明为静态的变量。

零初始化数据对应于声明为静态并在启动时初始化为零的数据。链接器将其分组为一个连续的块,以便启动代码可以执行块集(为 0)。

初始化数据对应于具有初始值的数据(例如 int x = 10;)。同样,链接器将这些数据分组到一个连续的块中,但在 ROM 中创建一个并行块,其中包含 RAM 中每个相应变量的初始值。启动时,整个块从 ROM 复制到 RAM。

pYYBAGKgaeiAcEvuAACbPR5E-EY102.png

【图2 | RAM 部分。]

如前所述,进程的 RAM 必须连续分组,如图 3 所示。为此,我们需要绕过编译器/链接器标准部分并创建将按进程分组的新部分。工具链通常能够创建多个零块和初始化部分,如图 3 所示。

poYBAGKgae-AWKT_AACu_X-6jGA358.png

【图3 | 基于 MPU 的应用程序的 RAM 部分。]

创建命名的 RAM 部分

要按进程对数据进行分组,我们需要使用 EWARM #pragma 指令 default_variable_attributes 并将所有要在一个进程中分组的变量包装在一起。

#pragma default_variable_attributes = @”.Process1”

// All variables that we want to be part of the section named “.Process1”。

#pragma default_variable_attributes =

如果您的应用程序包含在汇编语言文件中声明的变量,那么您还需要确保汇编语言文件包含适当的汇编程序指令。

按块对 RAM 进行分组

您的应用程序肯定会包含不一定与任何特定进程相关联的代码。在这种情况下,最好为这些模块创建命名部分,然后将这些部分组合成一个公共代码块。然后,您将使用上述#pragma 指令创建不同的命名段,每个模块一个,并使用链接器的 块 指令(如下所示)对这些段进行分组。

define block COMMON_RAM_BLOCK with alignment = 4K, size = 4K

{

section .DRIVER_RAM,

section .COMMOM_RAM,

section .MATH_RAM,

section .STRING_RAM,

}

define block PROCESS_AI_RAM_BLOCK with alignment = 16K, size = 16K

{

section .AI_DRIVER_RAM, // Analog input driver

section .RTD_LIN_RAM, // RTD linearization

section .THERMOCOUPLE_LIN_RAM, // Thermocouple linearization

section .UNIT_CONVERSION_RAM, // Shared RAM with AO module

}

define block PROCESS_AO_RAM_BLOCK with alignment = 8K, size = 8K

{

section .AO_DRIVER_RAM, // Analog output driver

section .4_20MA_LIN_RAM, // 4-20 mA linearization

section .ACTUATOR_LIN_RAM, // Actuator linearization

section .UNIT_CONVERSION_RAM, // Shared RAM with AI module

}

define block SHARED_RAM_BLOCK with alignment = 2K, size = 2K

{

}

您会注意到 block 指令允许您指定内存块的大小和对齐方式。为了将块的起始地址放置在 MPU 进程表中,两个值必须相同,这一点很重要。此外,每个块所需的 RAM 量取决于应用程序。为了便于说明,我决定使用 16K、8K、4K 和 2K 字节。

定位 RAM 块

我们现在可以使用两个链接器指令将所有块放置在 MCU 的可寻址空间中:区域和位置:

define region RAM = Mem:[from 0x20000000 size 64K];

place in RAM

{

block RAM_ALL with fixed order

{

block PROCESS_AI_RAM_BLOCK,

block PROCESS_AO_RAM_BLOCK,

block COMMON_RAM_BLOCK,

block SHARED_RAM_BLOCK

}

}

region 指令指定 MCU 的可寻址存储器。如果您的 RAM 并非全部连续,则可能有不同的区域指令。

RAM 指令中的位置指定在 RAM 区域中定位块。您会注意到我们需要将块放入块中以指定块放置的顺序。事实上,为了减少浪费的空间量,应该先使用较大的块。

为每个任务创建 MPU 进程表

现在 RAM 按进程分组,您可以返回并编辑每个任务/进程的 MPU 表。但是,要做到这一点,编译器必须知道块的名称,因此,您需要使用 #pragma section 指令,如下所示:

#pragma section = “COMMON_RAM_BLOCK”

#pragma section = “PROCESS_AI_RAM_BLOCK”

#pragma section = “PROCESS_AO_RAM_BLOCK”

#pragma section = “SHARED_RAM_BLOCK”

这两个进程表现在可以如下所示(假设您没有使用包含上一节中描述的每个任务回调的版本):

poYBAGKgaf2AEDSdAAPEVRXjNXg790.png

poYBAGKgageAGEBbAAO6FLgyE5w297.png

建议

以下是使用 Armv7-M MPU 时的一些建议。

在非特权模式下运行用户代码:

可以使用 MPU,但仍以特权模式运行所有应用程序代码。当然,这意味着应用程序代码将能够更改 MPU 设置,因此会破坏拥有 MPU 的目的之一。最初以特权模式运行应用程序可能会更容易迁移应用程序代码。但是,在某些时候,您的大部分应用程序代码都需要在非特权模式下运行,因此您需要添加 SVC 处理程序。

将 PRIVDEFENA 设置为 1:

这允许特权代码访问完整的内存映射。理想情况下,您的大多数应用程序将在非特权模式下运行,只有 ISR 和 RTOS 将在特权模式下运行。此建议可避免为每个任务使用三个 MPU 区域,以授予特权代码访问任何 RAM 位置、任何代码和任何外围设备。将 PRIVDEFENA 设置为 1 的决定可能已经由 RTOS 供应商做出,您无法更改。

ISR 具有完全访问权限:

每当识别到中断并启动 ISR 时,处理器就会切换到特权模式。由于 PRIVDEFENA 将设置为 1,因此 ISR 无论如何都可以访问 I/O 位置的任何内存。您根本不想在进入 ISR 时重新配置 MPU,并在退出时重新配置它。因此,ISR 应该被视为系统级代码,因此确实应该被允许具有完全访问权限。

此外,ISR 应始终尽可能短,并简单地向任务发出信号以执行中断设备所需的大部分工作。当然,这假设 ISR 是内核感知的,并且任务有相当多的工作来处理中断设备。例如,处理以太网数据包不应该在 ISR 级别完成。但是,可以直接在 ISR 中切换 LED 或更新脉冲宽度调制 (PWM) 定时器的占空比。

将 XN 位设置为 1:

如果您的应用程序代码不希望在 RAM 外执行代码,则应为所有 RAM 或外围区域设置 RASR 寄存器的 eXecute Never 位。为外围设备设置 XN 位可能看起来很奇怪,但它不会伤害并防止黑客试图进入您的系统。

限制外围设备对其进程的访问:

您应该留出一个或多个 MPU 区域来限制进程只能访问其自己的外围设备。换句话说,如果一个进程管理 USB 端口,那么它应该只能访问 USB 外围设备或与 USB 控制器需求相关的外围设备,例如 DMA

限制 RTOS API

系统设计人员需要确定哪些 RTOS API 应可用于应用程序代码。具体来说,您想防止应用程序代码在系统初始化后创建和删除任务或其他 RTOS 对象(如信号量、队列等)吗?换句话说,RTOS 对象是否应该只在系统启动时创建,而不是在运行时创建?如果是这样,那么 SVC 处理程序查找表应该只包含您想要向应用程序公开的 API。然而,即使 ISR 在特权模式下运行并因此可以访问任何 RTOS API,一个好的 RTOS 仍会阻止从 ISR 创建和删除 RTOS 对象。

在 RTOS 空间中分配 RTOS 对象:

任务堆栈位于进程的内存空间内。然而,RTOS 对象(信号量、队列、任务控制块等)最好分配在内核空间中并通过引用进行访问。换句话说,您不想在进程的内存空间中分配 RTOS 对象,因为这意味着应用程序代码可以有意或无意地修改这些对象,而无需通过 RTOS API。

没有全局堆:

将 MPU 设置为使用全局堆(即所有进程使用的堆)几乎是不可能的,因此您应该尽可能避免使用这些堆。相反,如前所述,如果进程需要动态分配的内存(例如以太网帧缓冲区),则应允许进程特定的堆。

不要禁用中断:

如果您的应用程序在非特权模式下运行,任何禁用中断的尝试都将被忽略。这样做的问题是,您不会从 CPU 获得中断 未被 禁用的指示。

如果您的应用程序在非特权模式下运行并且您尝试通过 NVIC 禁用中断,则会触发总线故障。

保护对代码的访问:

尽管 MPU 区域通常用于提供或限制对 RAM 和外围设备的访问,但如果您有空闲区域并且能够按进程组织代码(通过链接器命令),那么限制代码对代码的访问可能很有用。这可以防止某些类型的安全攻击,例如 Return-to-libc [2]。

减少进程间通信

就像任务应该设计得尽可能独立一样,流程也应该遵循同样的规则。因此,要么进程不相互通信,要么将进程间通信保持在最低限度。

如果您必须与其他进程通信,只需留出一个包含输出和输入缓冲区的共享区域。发送方将其数据放入输出缓冲区,然后触发中断以唤醒接收进程。一旦数据被处理,响应(如果需要)可以放在发送者的缓冲区中,并且可以使用中断来通知发送者。

确定遇到 MPU 故障时该怎么做:

理想情况下,在开发过程中检测并纠正所有 MPU 故障。您应该计划由于意外故障或错误或您的系统受到安全攻击而在现场发生故障。在大多数情况下,建议对每个任务或每个进程都有一个受控的关闭顺序。是否重新启动有问题的任务、进程内的所有任务或整个系统取决于故障的严重程度。

有办法记录和报告故障:

理想情况下,您有办法记录(可能记录到文件系统)并显示故障原因,以允许开发人员解决问题。

结论

内存保护单元 (MPU) 是将对内存和外围设备的访问限制为仅需要访问这些资源的代码的硬件。如果任务试图访问其分配空间之外的内存位置或外围设备,则会触发 CPU 异常,并且根据应用程序,必须采取纠正措施。

Cortex-M MCU 中的 MPU 是一个相当简单的设备,并且相对容易配置。然而,使用 MPU 的复杂性更倾向于按进程分配存储(主要是 RAM)以及创建将在上下文切换期间加载到 MPU 中的 MPU 进程表。

最后,我提供了一个建议列表,这些建议可以更好地在您的应用程序中使用 MPU。

单独的软件无法阻止对未分配给 RTOS 环境中任务的内存或外围设备的访问。您需要硬件来实现这一点,而 MPU 是目前 Cortex-M (Armv7-M) 上唯一可以做到这一点的机制。

迁移应用程序以使用 MPU 是一个相当简单但乏味的过程。添加 MPU 也会给您的应用程序带来开销:在上下文切换期间您需要加载额外的寄存器,并且用户代码应该在非特权模式下运行以避免此类代码更改 MPU 设置。

审核编辑:郭婷

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • mcu
    mcu
    +关注

    关注

    146

    文章

    16829

    浏览量

    349672
  • 寄存器
    +关注

    关注

    31

    文章

    5280

    浏览量

    119738
  • MPU
    MPU
    +关注

    关注

    0

    文章

    338

    浏览量

    48684
收藏 人收藏

    评论

    相关推荐

    瑞萨电子基于Arm Cortex-A55和双Cortex-M33 MPU的SOM方案 加速物联网设计

    基于Arm Cortex-A55(1.1GHz)和双Cortex-M33(250MHz)MPU的SOM(系统模块)方案,该方案可加快物联网应用的开发进程,并降低其设计风险。 系统框图
    的头像 发表于 08-15 17:23 1772次阅读
    瑞萨电子基于Arm <b class='flag-5'>Cortex</b>-A55和双<b class='flag-5'>Cortex-M</b>33 <b class='flag-5'>MPU</b>的SOM方案 加速物联网设计

    使用Keil uVision对TLE9893_2QK Evalkit进行编程,显示\"未找到Cortex-M SW设备\",为什么?

    我正在使用 Keil uVision 对 TLE9893_2QK Evalkit 进行编程。 当我尝试调试时,得到以下错误信息。 我还收到一个窗口,显示\"未找到 Cortex-M SW
    发表于 06-03 08:10

    瑞萨MCU/MPU开发板概述

    瑞萨MCU/MPU开发板 介绍           FPB-RA6E2 (200MHz Arm Cortex-M33,64引脚,ROM:256KB,RAM:40KB,板载SEGGER J-Link
    的头像 发表于 04-15 08:35 581次阅读
    瑞萨MCU/<b class='flag-5'>MPU</b>开发板概述

    Cortex-M0+内核介绍

    和8位的价位实现32位性能。处理器的低门数使其能够部署在需要简单功能的应用中。 作为ARM Cortex-M处理器系列的最新成员,32位Cortex-M0+处理器采用了低成本90纳米低功耗(LP)工艺,耗电量仅9μA/MHz,约为主流8位或16位处理器的1/3,却能提供更
    的头像 发表于 03-27 09:13 890次阅读
    <b class='flag-5'>Cortex-M</b>0+内核介绍

    产品详解 | 瑞萨电子RZ/T2M MPU

    产品详解 | 瑞萨电子RZ/T2M MPU
    的头像 发表于 03-13 08:05 498次阅读
    产品详解 | 瑞萨电子RZ/T2<b class='flag-5'>M</b> <b class='flag-5'>MPU</b>

    Cortex-M3芯片有哪些

    Cortex-M3芯片是一款基于ARM架构的低功耗、高性能的嵌入式处理器。目前市面上有众多厂商生产了基于Cortex-M3内核的芯片,如意法半导体的STM32F系列、恩智浦半导体的LPC1800系列等。这些芯片广泛应用于工业控制、智能家居、物联网等领域。
    的头像 发表于 03-11 17:07 1455次阅读

    Cortex-M85内核单片机如何快速上手

    2022年4月,Arm推出了全新的MCU级内核Cortex-M85。截止目前(2024年2月),Cortex-M85是最新、最强的Cortex-M内核。
    发表于 02-29 09:35 629次阅读
    <b class='flag-5'>Cortex-M</b>85内核单片机如何快速上手

    入门级64位ARM®CORTEX®-A55 MPU数据手册

    电子发烧友网站提供《入门级64位ARM®CORTEX®-A55 MPU数据手册.pdf》资料免费下载
    发表于 02-19 10:59 0次下载
    入门级64位ARM®<b class='flag-5'>CORTEX</b>®-A55 <b class='flag-5'>MPU</b>数据手册

    请问mbed物联网操作系统会成为cortex-m中的android吗?

    mbed 物联网操作系统会成为cortex-m中的android吗?
    发表于 01-17 07:14

    Arm Cortex-M52的主要特性和规格

    Arm Cortex-M52是一款采Arm Helium 技术的新型微控制器内核,旨在将AI功能引入更小、成本更低的物联网设备,而不是基于Arm Cortex-M55内核的SoC,Arm Cortex-M52架构如下图所示。
    的头像 发表于 01-02 11:12 1275次阅读
    Arm <b class='flag-5'>Cortex-M</b>52的主要特性和规格

    Cortex-M3 技术参考手册

    电子发烧友网站提供《Cortex-M3 技术参考手册.pdf》资料免费下载
    发表于 12-25 09:18 3次下载

    IC芯片型号的那些后缀怎么看?

    STM3代表的是ARM Cortex-M内核的32位微控制器。
    的头像 发表于 11-29 15:24 1834次阅读

    业界首款基于Arm Cortex-M85的超高性能MCU

    瑞萨电子重磅发布了业界首款基于Arm Cortex-M85处理器的全新超高性能MCU:RA8M1系列微处理器。 RA8系列产品具备业界卓越的6.39 CoreMark/MHz测试分数,缩小了MCU与MPU之间的性能差距。
    发表于 11-10 09:44 484次阅读

    Cortex-M系列的单片机调试仿真器有哪些?

    Cortex-M系列的单片机各大公司都有出品,从M0到M7 型号太多了。 为了开发他们仿真器型号也出了不少。 希望大家能罗列一下。 除了Jlink V8Jlink V9ST-link等。还有什么。 每个仿真器的使用范围和特点
    发表于 11-03 06:42

    RT-Thread支持瑞萨全新超高性能Arm® Cortex®-M85 MCU

    大加快应用开发速度。  Arm 最强MCU内核ArmCortex-M85 Cortex-M85基于Armv8.1-M架构,提供了Cortex-M系列中最高的标量和信号处理性能,其
    的头像 发表于 11-02 12:40 2173次阅读
    RT-Thread支持瑞萨全新超高性能Arm® <b class='flag-5'>Cortex</b>®-<b class='flag-5'>M</b>85 MCU