This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Determine RAM usage in MSP430

Genius 4170 points

Other Parts Discussed in Thread: MSP430F2274, TEST2

Hello,

 

today with a rather simple question: How do i exactly know what memory space i got left in my MSP430. To make it easy for you I post everything i know:

 

I am using the MSP430F2274, it is supposed to have 32 kB Flash and 1 kB RAM.

 

I know my *.map file and so can determine some memory:

        name            origin    length      used     unused   attr    fill
----------------------  --------  ---------  --------  --------  ----  --------
  SFR                   00000000   00000010  00000000  00000010  RWIX
  PERIPHERALS_8BIT      00000010   000000f0  00000000  000000f0  RWIX
  PERIPHERALS_16BIT     00000100   00000100  00000000  00000100  RWIX
  RAM                   00000200   00000400  0000030d  000000f3  RWIX                                                <---------- so i know 0x0400 means 1 kB of total RAM

 

as i can also read out i assume my used RAM space is 0x030D which is 781 Bytes.

 

So i can do my math and get a free RAM usage of around 243 Byte, is that true? Of course i assume there might be other memory segments not listet in the RAM above which also use RAM, but i dont know that for sure, and i can think of a growing Stack, which i dont know how big it gets in total, in the CCS it is set to 80 Bytes maximum, so perhaps i have around 243 - 80 = 163 Bytes left.

Am i right there?

 

Now comes the questioning part:

For implementation of a ModBus-Stack, i want to define an rather big array of values, so i can manipulate and read them out.

 

so when i define a new array,e.g.

static unsigned short modbus_array[N];

my maximum N should be the calculated BYtes which are left, or in this example because short is 16 bit it should be half of the calculated Bytes?

 

As a little help, CCS tells me when i am exceeding my RAM, can anyone please tell me if i have to look for my Stack usage for my own, since the Stack is growing from one side to the other, so my Code wont destroy itself? And perhaps someone has some good ideas on how to look out for memory usage in an easy way.

 

Since CCS is only telling some strange codes sizes when you trying to debug:

MSP430: Program loaded. Code Size - Text: 6300 bytes  Data: 602 bytes

So i suppose Text means the Flash usage and Data means the RAM usage.

 

Thanks for taking interest.

Seb

 

  • Hello,

     

    now i tried a little bit and i found something really interesting:

    I was working around my Code to make it smaller and smaller, in order to get more free memory in my RAM for non volatile memory, so i deleted a lot of unnecassary code.

     

    My CCS now says, so was really happy to read it :)

    MSP430: Program loaded. Code Size - Text: 5380 bytes  Data: 90 bytes      I thought i reduced from before over 600 BYtes to now 90 Bytes thats pretty awesome.

     

    Next i took a look into the map file and:

    RAM                   00000200   00000400  000003e1  0000001f  RWIX

    There the RAM usage is pretty the same as before, so what is happening there?

     

    What exactly is the CCS trying to tell me with those seemingly random numbers??? Can i use them or should i never trust those missleading numbers of hell...

     

    Thanks again

     

  • Hi Seb,

     

    I don't know if the Stack size is included in the RAM usage - easy way to find out is to change your allocated stack size and see how it affects the map file.

    Yes for 16bit variables the array size N will have to be less than or equal to num_bytes_space/2.

    Code composer won't tell you much about the stack usage (I think IAR is a bit more intelligent here).  A useful test is to fill the stack with a known sequence of characters, leave the code to run for a while and then read the stack contents and see how far the sequence has been interrupted.  This will give you an idea of how much of the stack is being used.

    When downloading to the device I don't think "Data" means "RAM" but refers instead to fixed data (e.g. const variables) and preinitialised data.  Have a look at the assembly language user tools (slau131) for a bit of information.  Sometimes commands setting variables to fixed values seems to result in bytes swapping between "Data" and "Text" totals depending on what mood the compiler seems to be in!

     

    Chris.

  • Hello Chris,

     

    thanks for your reply, this makes things a little bit clearer.

    It explains why my Data-Size seems to be shrinking, while the RAM usage is likely to be the same.

     

    The thing with the stack size  could help me in future so thanks for the tip.

    Which leads me to another question, is the stack size limited to the maximum size defined in the CCS, which is 80 Bytes right now? or does it simply grow bigger and bigger if it needs to?

     

    I ask this, because i am a little afraid of a growing stack, since i have a couple of rather big Interrupt Service Routines. So i could imagine a Stack which is growing into my normal Code-area, which of course will destroy or corrupt my normal program code.

     

    Thanks and Greetings.

    Seb

  • Hi Seb,

    The stack area will just be a fixed number of bytes and the used portion grows and shrinks during operation.  The danger is that there is no protection for the used space growing outside of the allocated stack space, risking overwriting other variables and/or code that is contained in RAM.  Once you get to this stage the program operation will become unpredictable.  Code/data contained in flash should be protected as the flash memory controller has to be setup correctly before flash can be overwritten.  Be careful of re-entrant code such as ISRs that enable GIE before completion and functions that are called recursively as these can lead to stack overflow problems.

    Sounds like it might be worth running the stack test to see how much is being used up.

     

    Chris.

  • To answer the discrepancy of data size and used ram, I think, the listed Data size contains only initialized data.
    Initialized data is what needs to be stored in flash and copied to ram before the program starts. It refers to all variables which are explicitely initialized with a value in your code. All other variables can be just filled with zeroes on program start (and CCS doesn't even do this, while most other C compilers do, but it is NOT required by the standard)
    But uninitialized data of course still occupies ram space.

    One thing you can do is to define data you do not change as 'const'. In this case, it is placed in flash and NOT copied to ram, and does not require ram space.

    I too think that the configured stack size is part of the 'used ram' amount. This is to make the linker complain if there is not enough space left for the desired stack size. However, there is no way to really configure the stack size - the stack grows as it wants. So this setting is only for triggering a linker error or a debugger warning if it finds the stack pointer outside the 'configured' area when hitting a breakpoint.

  • Jens-Michael Gross said:

    One thing you can do is to define data you do not change as 'const'. In this case, it is placed in flash and NOT copied to ram, and does not require ram space.

     It will still show up as "data" though as it's still initialized data. I'm not aware of an easy way to determine the ram usage of a given program. See also the discussion on Micheal Barr's blog on stack overflows and how to handle them (or well at least how you can try to).

  • Bernhard Weller said:
     It will still show up as "data" though as it's still initialized data

    Sure? Well, it's a linker specific output, so everythign can mean everything, there is no standard. :)

    Bernhard Weller said:
    See also the discussion on Micheal Barr's blog on stack overflows


    Well stack usage is dynamic and can vary depending on the runtime parameters of a program. (like incoming data).
    Also, usage of malloc() adds to the programs ram usage and doesn't show up at compile time.

    so yes, program ram usage can only be analyzed by knowing things about the program the compiler cannot easily know.
    e.g. if two function in different source files call each other, neither compiler nor linker can detect it but it will lead to unlimited stack usage (stack overflow, since stack space is limited)
    But if you know that you don't use dynamic space allocation like malloc, and do not use recursions in your code by design, do not use nested interrupts and do not use goto or inline/explicit assembly code that pushes things ont he stack, you can calculate the ram usage to the exact byte size. (I don't say it is easy).

  • Jens-Michael Gross said:

    Sure? Well, it's a linker specific output, so everythign can mean everything, there is no standard. :)

     Well at least in code composer studio it does. I just tried:

    static const uint8_t test[10] = {1,2,3,4,5,6,7,8,9,10}; -> Text: 66 bytes Data: 12 bytes

    uint8_t test[10] = {1,2,3,4,5,6,7,8,9,10}; -> Text: 162 bytes Data: 18 bytes

    uint8_t test[10]; -> Text: 66 bytes Data: 2 bytes

    The main body just was:

    void main(void)
    {
    WDTCTL = WDTPW+WDTHOLD; // Stop WDT

      volatile uint8_t test2 = test[P1IN];
    }

  • Bernhard Weller said:

    static const uint8_t test[10] = {1,2,3,4,5,6,7,8,9,10}; -> Text: 66 bytes Data: 12 bytes

    uint8_t test[10] = {1,2,3,4,5,6,7,8,9,10}; -> Text: 162 bytes Data: 18 bytes

    uint8_t test[10]; -> Text: 66 bytes Data: 2 bytes

    That's a very interesting result.
    The second line indicates that the linker did add init-code for copying the init values to the Text portion (whopping 96 bytes!)
    Smart thing - especially if this code is that large. (that it is that large is much less smart)
    I wonder why the Data size has increased by 6 bytes too. Does this init code also require 6 bytes global data? That's weird.
    My own init code (replacing the default mspgcc init code to keep the WDT active during init) is only a few bytes (30 or so) including the loop for erasing uninitialized and 0-initialized data, and does not need any ram at all.

**Attention** This is a public forum