1

I am currently developing an embedded application on the Atmel SAML21J microcontroller, and I have 256KB Flash memory, and a 40KB SRAM memory. When I program my app on the MCU, I have the following message :

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

It seems to mean that even before I start to run my code, I already have a 71% full RAM.

I would like to know the following things:

  • what is defined in the RAM, and what is defined in the Flash ?

  • can I do something to use more of my Flash (that is only 24% full) to save space on the SRAM, and how ?

  • I saw a ".ld" file that specifies the size of my stack : will it leave me more space in the RAM if I make it higher ?
  • In this .ld file, is the memory (Flash + SRAM) considered as one unique memory entity ? (meaning that the addresses of the SRAM starts and the end of the flash, for example ?)

Even if I read a lot of things on this subject, this is still shady to me, and I would really appreciate if you guys enligthened me on that. Thanks.

YohjiNakamoto
  • 373
  • 2
  • 12
  • I don't understand. You are building for an embedded application, so you have absolute control over the segment and section placement in the memory map/s. You should already know everything you are asking! If you want finer detail, look at your linker map file. – Martin James Apr 11 '16 at 15:38
  • ..and, of course, your user manual. – Martin James Apr 11 '16 at 15:41
  • Martin James, I know, but all of this is shady to me, and having an answer to those questions will help me manage the memory map. I haven't done that already, because it's kinda hard to understand to me. – YohjiNakamoto Apr 11 '16 at 15:42
  • There can be no answer without all the details of your hardware and software build. Only you have that. A memory plan for an embedded job is too broad for an SO question, it needs intimate knowedge of your overall design. – Martin James Apr 11 '16 at 15:52

1 Answers1

2
  1. Where and what placed (defined):

    • Stack (local variables placed in stack), all global variables, functions that specificied with special keyword (for ex. __ramfuc for IAR) as runned from RAM - are placed in RAM.
    • All functions (no differents where it's will run), all constants, variables initialization values are placed in Flash. Worth mentioning for AVR you need to use keyword PROGMEM to place any constant to Flash (functions don't need that), while for ARM keyword const will be enough.
  2. For save RAM space you can (in order of effectiveness):

    • place big tables and text constants (debug messages too) in Flash
    • merge global buffers (with unions) and use it for differents task in different time
    • reduce size of stack, there could be problems with stack overflow - so you must reduce functions nesting
    • use bitmasks for global flags instead of bytes
  3. If you insrease stack size: since stack placed in RAM so you increase RAM usage.

  4. Flash and RAM memories have different address ranges, so from .ld file you can know where each variable or function aligned by linker:

    /* 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
    }
    

    There we have:

    • 128Kb of RAM address range [0x20000000, 0x2001FFFF]
    • 1Mb of Flash address range [0x08000000, 0x080FFFFF]
    • And example how section text placed to Flash memory.

    And theh after success compile project you can open file ./[Release|Debug]/output.map for see where each functions and variables are placed:

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

    Function main is placed in Flash memory, global variable io_buffer is placed in RAM memory.

imbearr
  • 999
  • 7
  • 22
  • But if all global variables and functions are runnend from RAM, how come I have already such a high amount of my SRAM used ? Does it use less RAM if I allocate variables with malloc ? – YohjiNakamoto Apr 12 '16 at 07:32
  • Global variables always in RAM, but functions is run from flash if you don't define it as runned from RAM with special preprocessor's keyword. – imbearr Apr 12 '16 at 07:39
  • And the other segments, heap, bss, text and data can be used by my flash with that specific preprocessor variable ? – YohjiNakamoto Apr 12 '16 at 07:46
  • No flash may bee used for constatnt values only. [More explain variables location.](http://stackoverflow.com/questions/14588767/where-in-memory-are-my-variables-stored-in-c) – imbearr Apr 12 '16 at 07:46
  • Flash is read and write memory, that's a shame it can be used only for read-only data. :/ – YohjiNakamoto Apr 12 '16 at 07:49
  • Flash may be rewrited only with erasing sector, and it have limited count of rewrite cycles. You can use it for save some data by your software sequence, but not automatically. – imbearr Apr 12 '16 at 07:55
  • Thanks for answer. However I don't think I have access to the PROGMEM macro, I have an arm processor... – YohjiNakamoto Apr 12 '16 at 15:08
  • Yeah! I'm very suprised that is Atmel and not AVR. So where problem? Keyword _const_ will be enought for arm-gcc-noeabi. – imbearr Apr 12 '16 at 15:13