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.

CCS: Allocating local variables to FRAM

Other Parts Discussed in Thread: MSP430FR5969

Tool/software: Code Composer Studio

I couldn't find this with a bit of digging. 

#pragma PERSISTENT puts global variables to FRAM as expected. This is fine and good but if I have a local 256 byte array, it'd be nice to be able to store that to FRAM instead of SRAM as well. 1/8th of 2kB SRAM right there.

As far as I can tell, you can only assign global variables to FRAM, period. Is there a (sane) way around this somehow? Obviously for conventional thinking, using a bunch of global variables is double plus ungood and you have to maintain some kind of naming scheme etc to tie a particular global array to a particular function. This also does mean you're allocating more memory than you really need since you're always keeping "foo[256]" and "bar[256]" allocated in memory although they may not be needed simultaneously. 

  • WAG, but have you tried "static"? That simply creates a non-stack variable that has the scope of an auto.
  • Yeah, it goes to .data and doesn't get de-allocated. The #pragma DATA_SECTION also only works on "file level" global variables.

    Now that you mention it, at least as far as hiding the variable is concerned, I could split the associated function to a separate source file. That still does not address the problem that the memory is never de-allocated.
  • Olli Mannisto said:
    That still does not address the problem that the memory is never de-allocated.

    The TI ARM, MSP430 and C2000 compilers support the C99 Variable Length Arrays feature which allows variables to allocated from the heap, and the memory reclaimed when it goes out of scope.

    Since the heap can be placed in FRAM maybe that will help in your case.

    Be aware that the Variable Length Array allocate code doesn't appear to thread safe, and so can cause failures if used in a SYS/BIOS program; see MSP432P401R: Program goes into a hard fault when array is variable size.

  • I created the attached project for a MSP430FR5969 which demonstrates that variable-length-arrays can be allocated using the TI MSP430 v16.2.LTS compiler. The output reports that the variable-length-array was allocated at address 0x51f2 which is in FRAM (in part of the heap):

    String fo
    String formatted in
    String formatted in a VLA of 
    String formatted in a VLA of length 40 
    String formatted in a VLA of length 50 at 0x51f2
    String formatted in a VLA of length 60 at 0x51f2
    String formatted in a VLA of length 70 at 0x51f2
    String formatted in a VLA of length 80 at 0x51f2
    String formatted in a VLA of length 90 at 0x51f2

    I did note for small memory devices the run time library code has a significant size overhead, in that the init_curr_vla_pool() function in <ccs_install_root>\ccsv7\tools\compiler\ti-cgt-msp430_16.9.1.LTS\lib\src\vla_alloc.cpp allocates an initial 3000 byte buffer to manage the VLA storage pool. As a result had to set the heap size in the project to 4096 bytes before could successfully create a variable-length-array.

    MSP430FR5969_VLA.zip

  • Interesting idea. Malloc also uses heap so that's two different ways of allocating variable amounts of (non global) data. You just have to crank up the heap amount if you're going that direction. In fact using malloc would let you use global but dynamic allocation which is nice.

    I haven't had time to go into SYS/BIOS and/or TIRTOS route as I've been too busy with actually writing firmware.. Naturally that makes it harder and harder to convert things to run on RTOS.