【问题标题】:When does my microcontroler uses my Flash or my RAM?我的微控制器何时使用我的闪存或 RAM?
【发布时间】:2016-08-01 20:54:06
【问题描述】:

我目前正在 Atmel SAML21J 微控制器上开发嵌入式应用程序,我有 256KB 闪存和 40KB SRAM 存储器。当我在 MCU 上编写我的应用程序时,我收到以下消息:

Program Memory Usage     66428 bytes    24,6 % Full
Data Memory Usage     29112 bytes    71,1 % Full

这似乎意味着即使在我开始运行我的代码之前,我已经拥有 71% 的完整 RAM。

我想知道以下几点:

  • RAM 中定义了什么,Flash 中定义了什么?

  • 我可以做些什么来使用更多的闪存(即只有 24% 已满)来节省 SRAM 上的空间,以及如何做?

  • 我看到了一个“.ld”文件,它指定了我的堆栈大小:如果我将其设置得更高,它会在 RAM 中留出更多空间吗?
  • 在这个 .ld 文件中,内存(闪存 + SRAM)是否被视为一个唯一的内存实体? (意思是SRAM的地址开始和flash的结束,例如?)

即使我阅读了很多关于这个主题的东西,这对我来说仍然是阴暗的,如果你们能在这方面启发我,我将不胜感激。 谢谢。

【问题讨论】:

  • 我不明白。您正在为嵌入式应用程序构建,因此您可以绝对控制内存映射中的段和段放置。您应该已经知道您要问的一切!如果您想要更详细的信息,请查看您的链接器映射文件。
  • ..当然还有你的用户手册。
  • Martin James,我知道,但所有这些对我来说都是阴暗的,回答这些问题将有助于我管理内存映射。我还没有这样做,因为这对我来说有点难以理解。
  • 如果没有您的硬件和软件构建的所有详细信息,就没有答案。只有你有那个。嵌入式作业的内存计划对于 SO 问题来说过于宽泛,它需要对您的整体设计有深入的了解。

标签: c memory compilation linker


【解决方案1】:
  1. 放置(定义)的位置和内容:

    • 堆栈(放置在堆栈中的局部变量)、所有全局变量、使用特殊关键字指定的函数(例如,__ramfuc 用于 IAR)从 RAM 运行 - 放置在 RAM 中。
    • 所有函数(运行的地方没有区别)、所有常量、变量初始化值都放在 Flash 中。值得一提的是,对于 AVR,您需要使用关键字 PROGMEM 将任何常量放入 Flash(函数不需要),而对于 ARM,关键字 const 就足够了。
  2. 为了节省 RAM 空间,您可以(按有效性排序):

    • 在 Flash 中放置大表和文本常量(也包括调试消息)
    • 合并全局缓冲区(使用联合)并将其用于不同时间的不同任务
    • 减少堆栈大小,堆栈溢出可能会出现问题 - 因此您必须减少函数嵌套
    • 对全局标志使用位掩码而不是字节
  3. 如果您增加堆栈大小:由于堆栈放置在 RAM 中,因此您会增加 RAM 使用率。

  4. Flash 和 RAM 存储器具有不同的地址范围,因此从 .ld 文件 您可以通过链接器知道每个变量或函数的对齐位置:

    /* Memories definition in *.ld file */
    MEMORY
    {
        RAM (xrw)       : ORIGIN = 0x20000000, LENGTH = 128K
        ROM (rx)        : ORIGIN = 0x8000000, LENGTH = 1024K
    }
    /* Sections */
    SECTIONS
    {
        /* The program code and other data into ROM memory */
        .text :
        {
            ...
        } >ROM
    }
    

    我们有:

    • 128Kb 的 RAM 地址范围 [0x20000000, 0x2001FFFF]
    • 1Mb 的 Flash 地址范围 [0x08000000, 0x080FFFFF]
    • 以及如何将部分text 放置到闪存中的示例。

    成功编译项目后,您可以打开文件./[Release|Debug]/output.map查看每个函数和变量的放置位置:

     .text.main     0x08000500       0xa4 src/main.o
                    0x08000500                main
     ...
     .data          0x20000024      0x124 src/main.o
                    0x20000024                io_buffer
    

    函数main放在Flash内存中,全局变量io_buffer放在RAM内存中。

【讨论】:

  • 但是如果所有的全局变量和函数都是从 RAM 中运行的,为什么我已经使用了这么多的 SRAM 呢?如果我使用 malloc 分配变量,它会使用更少的 RAM 吗?
  • 全局变量始终在 RAM 中,但如果您没有使用特殊预处理器的关键字将其定义为从 RAM 运行,则函数将从闪存运行。
  • 其他段、堆、bss、文本和数据可以被我的闪存使用那个特定的预处理器变量?
  • 没有闪存只能用于常量值。 More explain variables location.
  • Flash是读写内存,可惜只能用于只读数据。 ://
猜你喜欢
  • 2020-04-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-28
  • 1970-01-01
  • 1970-01-01
  • 2020-11-17
相关资源
最近更新 更多