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.

RAM usage info

Other Parts Discussed in Thread: MSP430F47176


I have a question on the RAM usage of MSP430F47176 (8KB RAM).

Attached at the bottom of this post is the sample code, I used for the check.


When I set "char g_zbuf[5000]", the memory usage info obtained from the IAR
is as follows.
----
176 bytes of CODE memory
5,080 bytes of DATA memory (+19 absolute)
5 bytes of CONST memory
----

When I execute the program, the program does not reach to the 1st line
of the main() "WDTCTL = WDTPW +WDTHOLD;". It seems that there is something
wrong with the memory usage (overflow?).

I guess that the rest of the RAM (8000 - 5080 bytes) is not enough to execute
the code properly. However, how can I find how much memory should I keep
except for the RAM used in the code (e.g., 5080 in this case)?

====================

#include <msp430x471x6.h>
#include <string.h>

char g_zbuf[5000]; 

void main(void)
{
   
    WDTCTL = WDTPW +WDTHOLD;                  // Stop WDT
   
    strcpy(g_zbuf, "TEST");

    _NOP();
   
    _BIS_SR(LPM0_bits);                       // Enter LPM0
}

 

  • Hello OKY,

    Please have a look at the similar post here.

    By default the MSP430 WDT is active and is likely expiring, resetting the device, prior to the RAM array being initialized at runtime in the C startup execution. Using __low_level_init (when using IAR IDE) or _system_pre_init() (when using CCS IDE) to disable the WDT prior to RAM initialization should resolve the issue.

    Hope this help.

    Regards, Zack 

  • Thank you for your reply, Zack Albus.

     

    I will read through the link to understand the problem better.

     

    Best regards

     

     

     

  •  

    I could avoid this problem according to the information of the link.

     

    Thank you very much, Zack.

     

     

     

  • On mspgcc (not IAR/CCE) the reset function disables the watchdog - for exactly this reason. But I wasn't happy with this solution (in case of an ESD event, the WDT should be active all the time). So I wrote my own startup code completely, by taking the original code and adding a watchdog tigger every copied/cleared byte. This makes the initialisation slower, but more safe than disabling the WDT before doing the init.

    In your case, there should be an easier solution. For mspgcc, you can place variables (such as your huge array) into an uninitialized section. It only reserves space in ram, but is neither copied from flash to ram nor filled with 0 at startup. So it does not add to the initialisation time.
    If you don't need your array to be initialized with zeroes at startup (you can do so manually later, if really necessary), you can go this way.
    Or you dynamically allocate the 5k ram with malloc. It may waste additional 2 or 4 bytes ram for the memory handling, but if you allocate the memory at startup and do not frequently allocate and free memory, malloc isn't that bad.

  • Thank you for your reply.

    I am sorry for this late reply.

     

    Jens-Michael Gross said:

    In your case, there should be an easier solution. For mspgcc, you can place variables (such as your huge array) into an uninitialized section. It only reserves space in ram, but is neither copied from flash to ram nor filled with 0 at startup. So it does not add to the initialisation time.
    If you don't need your array to be initialized with zeroes at startup (you can do so manually later, if really necessary), you can go this way.

    I am checking the manual for MSP, but if you don't mind, I would like to ask you.

    How can we declare  the "array without initialization"? We have auto variables, static variable in function, global variable and static variable in the global.  

    Do we use some directive such as 'volatile' or so to have array withou initizaliation?

     

    Jens-Michael Gross said:

    Or you dynamically allocate the 5k ram with malloc. It may waste additional 2 or 4 bytes ram for the memory handling, but if you allocate the memory at startup and do not frequently allocate and free memory, malloc isn't that bad.

    In this case, I am worried when the software stopped in the middle by some cause, the memory is not released correctly before the code goes to free(); sentence.

     

     

  • OKY said:
    How can we declare  the "array without initialization"?


    I don't know for CCE or IAR. On mspgcc you do

    unsigned int array[100] __attribute__ ((section(".noinit")));

    This will tell the linker to reserve ram for this array, but will not include this reserved space into the area where initialization data is copied from flash to ram at startup or where data is erased. If these are just fixed buffers which are written to later, the no-initis no problem, also for variables which are initialized at startup in the code, maybe depending on other circumstances.
    Also, I used this for variables which hold counters. If a reset happens, these counters are not reset. There's a guard value too which will be set after start and let me detect with some certainity whether it was a real Power-up adn the counters are holding random values or whether there was a reset for other reasons and the counters are valid. (we had some devices in a very hostile environment with much EM, so saving the counters across a reset was necessary)

    OKY said:
    In this case [malloc], I am worried when the software stopped in the middle by some cause, the memory is not released correctly before the code goes to free(); sentence.

    No need to worry. If the program stops and the device resets, the RAM is freed automatically. Also, there is no need to free the memory at all if you continuously need it (like receive buffers for the UART ISR). Using malloc just does not add this memory to the pre-allocated and initialized ram area. Of course you'll need to keep track of your ram usage.

  • Thank you very much for your reply, again, Jens-Michael.

     

    Jens-Michael Gross said:

    How can we declare  the "array without initialization"?


    I don't know for CCE or IAR. On mspgcc you do

    unsigned int array[100] __attribute__ ((section(".noinit")));

    [/quote]

    Thank you for presenting the example for CCE. I will check the manual of IAR.

     

    Jens-Michael Gross said:

    In this case [malloc], I am worried when the software stopped in the middle by some cause, the memory is not released correctly before the code goes to free(); sentence.

    No need to worry. If the program stops and the device resets, the RAM is freed automatically. Also, there is no need to free the memory at all if you continuously need it (like receive buffers for the UART ISR). Using malloc just does not add this memory to the pre-allocated and initialized ram area. Of course you'll need to keep track of your ram usage.

    [/quote]

    I am not still a good programmer, so please allow me to ask you.

    Does the memory leak happen only during the programme is being executed?

    I thought that malloc holds the memory, and the memory is not released even after the program stops (without free()), causing the memory leakage.

    Does the problem of memory leakage become severe only for a system which works without 'reset' for a long time?

     

  • OKY said:

    ..........

    How can we declare  the "array without initialization"? We have auto variables, static variable in function, global variable and static variable in the global.  

    Do we use some directive such as 'volatile' or so to have array withou initizaliation?

    ............

    __no_init char g_zbuf[5000]; 

  • OKY said:
    Thank you for presenting the example for CCE.

    MSPGCC, not CCE. It's another compiler, a free, non-commercial one from the GNU toolchain.

    OKY said:
    Does the memory leak happen only during the programme is being executed?

    The malloc function and its management is part of the program. If the program is restarted, malloc will also restart adn management is set back to zero.

    OKY said:
    I thought that malloc holds the memory, and the memory is not released even after the program stops (without free()), causing the memory leakage.
    Does the problem of memory leakage become severe only for a system which works without 'reset' for a long time?

    On systems with an OS that starts different programs, malloc() just interfaces an OS function that does the ressource management. And depending on the OS, locked ressources are not freed if there is no request to free them. So if a program exits without freeing its ressources, they remain locked.
    In Windows, this sometiems happens if a program was writing to a file. If the program exits without closing the file, it may happen (especially if it is not a local file on HD) tha tthe file will be still marked as open and you cannot rename or delete it until a reboot.

    The memory management, however, usually detects that memory had been locked by a program and all is automatically freed on program exit.

    Memory leakage is only a problem if a program dynamically requests memory for its job (e.g. to store incoming  data packets), keeps it (until a packet has been processed) and forgets to free them (because the packet processing had been interrupted etc.) Then the program requests more an dmore memory until there's no more available.

    On MSP, you usually don't have an OS and do not start different programs. And if you just allocate your buffers at startup and never again, then there is no memory leaking.

    (p.s.: C++ dynamicall allocates memory each time you create an object. na dif you forget to destroy the objects if no longer used, this leads to memory leakage. Also chained lists can be a problem if improperly implemented)

  • Thank you very much for your detailed information, Jens-Michael.

    > MSPGCC, not CCE. It's another compiler, a free, non-commercial one from the GNU toolchain.

     Sorry for mistake.

     

    Jens-Michael Gross said:

    The memory management, however, usually detects that memory had been locked by a program and all is automatically freed on program exit.

    Memory leakage is only a problem if a program dynamically requests memory for its job (e.g. to store incoming  data packets), keeps it (until a packet has been processed) and forgets to free them (because the packet processing had been interrupted etc.) Then the program requests more an dmore memory until there's no more available.

    On MSP, you usually don't have an OS and do not start different programs. And if you just allocate your buffers at startup and never again, then there is no memory leaking.

    (p.s.: C++ dynamicall allocates memory each time you create an object. na dif you forget to destroy the objects if no longer used, this leads to memory leakage. Also chained lists can be a problem if improperly implemented)

    So it seems safe to use malloc() under MSP without OS.

    I do not use C++ dynamically memory allocation. Nor chained lists.

     

    I will consider to use malloc() depending on the case where I do not need initialization.

     

    Thank you again.

     

  •  

    For the IAR EW, I can use "__no_init" type modifier to have array without initialization.

     

    __no_init  int  data[5000];

     

    It is written in EW430_CompilerReference.pdf.

     

     

**Attention** This is a public forum