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/MSP430FR5969: Understanding (HIGH) modifier with RAM memory section, use and applicability to other memory sections

Part Number: MSP430FR5969
Other Parts Discussed in Thread: MSP430WARE

Tool/software: Code Composer Studio

Apologies if this has been answered elsewhere. Google and the forum searches were not fruitful.

I am trying to place large volume data in NOINIT arrays in FRAM and FRAM2 on the MSP430FR5969. To do this I have modified the default linker command file in the following manner:

.TI.noinit :{} > RAM changed to .TI.noinit :{} >> FRAM | FRAM2

I have noticed the use of the HIGH keyword, for instance with .stack :{} > RAM (HIGH), and am wondering what its meaning/use is and  whether it is applicable to FRAM? Relatedly I am trying to understand best practice for placing data arrays in well organized memory locations, for instance, if I wanted to align my noinit array with the end of FRAM or the beginning of FRAM2, what are the tools available for doing this?

  • The section .TI.noinit cannot be allocated to flash memory (FRAM or FRAM2).  Ordinary arrays, which are not subject to the NOINIT pragma or attribute, must go in memory which can be read and written, i.e. RAM.  NOINIT arrays have this same restriction, for the same reason.  The only difference between an ordinary array and a NOINIT array is whether the array is zero initialized before main starts.  An ordinary array is zero initialized, while a NOINIT array is not.  

    Thanks and regards,

    -George

  • The HIGH keyword is described in the Assembly Language Tool's User's Guide section 8.5.5.2.4 "Controlling Placement Using the HIGH Location Specifier"

    [Edit - I can't get the forum to accept the URL for this link.  See http://downloads.ti.com/docs/esd/SLAU131/index.html and navigate from there --Archaeologist]

  • Thanks Archaeologist! Will do.
  • Hi George,

    Thanks for the response. Please note the FR5969 is a Ferroelectric RAM based device, not flash. FRAM can be treated as fungible for the purposes of data and code storage. Moreover, the code snippet I included in the original post for the linker command file works as desired which suggests that your reply is not accurate.

    Thanks again for the response.
  • Hi Bret,

    Are you trying to store variables or constants? If it is variables, then I recommend using the #pragma PERSISTENT on the arrays. This will place all of this data together in memory automatically, at the beginning of the FRAM memory. The reason you want to group all of your read/write FRAM together is because the device has an MPU that is used to set different permissions (read/write/execute) on different areas of FRAM - you want to make sure to use the MPU because it helps to protect your code from accidentally being overwritten for example if you write off the end of an array. See MSP430 FRAM Technology – How To and Best Practices www.ti.com/.../slaa628 section 6.4.1 for more information about how CCS can automatically partition your FRAM and enable your MPU for you, if you use the PERSISTENT pragma for designating your variables.

    I recommend keeping your data in lower FRAM if possible (instead of FRAM2), because it is easier to access there (you have to use intrinsics like __data20_write_char() to write to or read from 20-bit address space). But, if you are storing so much data that this is not feasible, please see this other thread: e2e.ti.com/.../2055681 or let me know and we can discuss further your best options for linker file modification. See also that we include examples of LZ4 compression as part of our FRAM Utilities included in MSP430Ware: dev.ti.com/.../ This could let you compress data and store that in FRAM if that makes sense for your application (since it sounds like you need so much storage).


    Regards,
    Katie

  • Hi Katie. Thanks for the reply. Indeed I am storing a data array for long term sensor data storage (R/W). I had hoped to use both sections of FRAM to increase capacity but if necessary I can stick to the lower block. I do not want to have to include special directives to achieve basic operation as others will be using this sensor network and for maximum understandability I would like the code to be as clean as possible. With regard to using the PERSISTENT pragma rather than the NOINIT pragma, I found that PERSISTENT wants me to pre-initialize the data array and typing out the correct number of bytes (4000 plus) doesn't sound very appealing, however, if I am overlooking some simple tool to bypass this inconvenience I would be happy to consider it.

    Kind regards

  • Bret Bronner said:
    With regard to using the PERSISTENT pragma rather than the NOINIT pragma, I found that PERSISTENT wants me to pre-initialize the data array and typing out the correct number of bytes (4000 plus) doesn't sound very appealing

    As per the C standard if a partial initializer is used the remaining elements will be implicitly initialized to zero.

    E.g. in the following example of a 4000 element array for a MSP430FR5969 explicitly only initialized the first element and the large_array was then allocated in FRAM:

    #include <msp430.h> 
    
    #pragma PERSISTENT(large_array)
    int large_array[4000] = {0};
    
    /*
     * main.c
     */
    int main(void) {
        WDTCTL = WDTPW | WDTHOLD;	// Stop watchdog timer
    	
        large_array[0]++;
    
    	return large_array[0];
    }
    

  • Hi Bret,

    Glad that we could help. As Chester mentioned, I think you should be able to just initialize it with = {0}; Please let us know if you run into more questions - you can post in the MSP low-power microcontroller forum too!

    Regards,
    Katie
  • Thanks Chester, I see that and will use it from now on. Cheers.