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.

RE: Memory Map for Msp430fr57xx Family

Other Parts Discussed in Thread: MSP430FR5739

Hello,

I work with msp430fr5739 device.

I wonder if there is any description of unused memory space between info_a and RAM: 300h memory slots and between RAM and FRAM: a200h slots.

I need pretty large arrays of doubles to process time series from accelerometer, but the only available space seems to be an information space: 1900-18ff.

MEMORY MAP of the MSP430FR5739 
0000-0FFF = peripherals (4 KB)
1000-17FF = bootstrap loader BSL0..3 (ROM 4x512 B) 
1800-187F = info B (FRAM 128 B) 
1880-18FF = info A (FRAM 128 B) 
1900-19FF = N/A (mirrored into info space) 
1A00-1A7F = device descriptor info (FRAM 128 B) 
1A80-1BFF = unused (385 B)
1C00-1FFF = RAM (1 KB)
2000-C1FF = unused (41472 B) 
C200-FF7F = code memory (FRAM 15743 B) 
FF80-FFFF = interrupt vectors (FRAM 127 B) 

I tried writing to these sections, but lately when trying to read I got totally wrong values.

I am stuck here for a couple of days and would really appreciate your help.

 

  • Hi Sergei,

    You cannot use unused areas in the memory map to store data - in some cases there might be no memory there at all (just a gap left so addresses line up for other devices etc), and in some cases there might be ROM or something here that is not actually writeable or accessible. Either way these unused areas in the map can't be used by user code.

    Sergei Kasatkin said:
    I need pretty large arrays of doubles to process time series from accelerometer, but the only available space seems to be an information space: 1900-18ff.

    It sounds like your root problem is that you have large arrays that you want to store, but do not have enough RAM to do so. What you can do is you can store these arrays in FRAM - the area C200-FF7F is marked "code memory" but the beauty of FRAM is that you can partition this area and have a segment where you store variables in here as well, accessing it just like RAM.

    There are a few other threads on this forum discussing how to set a variable to be in FRAM instead of RAM if you do a search. There is also this application note www.ti.com/lit/pdf/slaa628 that has some helpful advice about partitioning FRAM - see chapter 3 in particular for detailed advice, including advice for CCS and IAR.

    One more thing you will want to make sure to do when placing variables in FRAM is to also enable MPU protections - this can help keep you from accidentally overwriting your application code if you set your application code segment to read/execute only. Then you can leave your segment containing your arrays with read/write access.

    I hope this helps to point you in the right direction.

    Regards,

    Katie

  • Thank you for quick reply!

  • One more question.

    Can I add somehow section from information space to fram group? Like make something like that

    RAM : origin = 0x1C00, length = 0x0400
    FRAM : (origin = 0xC200, length = 0x3D80) + (origin = 0x1880 length = 0x100)

    and then create a group in fram:

    GROUP(READ_WRITE_MEMORY)
    {
       .cio        : {}                   /* C I/O BUFFER                      */
       .sysmem     : {}                   /* DYNAMIC MEMORY ALLOCATION AREA    */
       .myVars     : {}  //space allocated to store variables in FRAM
    } ALIGN(0x0800), RUN_START(fram_rw_start)
    so that it will automatically use two sections: initial fram and information sectors.

  • I think when you make sections they usually have to be contiguous. If you have an array for example it can't be a single array but residing partly in INFO mem addresses and partly in FRAM. If you had multiple arrays and one was small enough to fit in INFO memory it could be placed there though.

    Is there a reason to want to use INFO mem? The code FRAM is fairly large - but maybe your code space is taking up a lot of room too?

    -Katie

  • Hi Sergei,

    It is hard to correlate a # of lines of C code to an amount of kB of code space, because you could do something pretty complex that will generate many assembly instructions in a single line of C code. It can also be hard to know what is the problem without knowing your code.

    Does your code use a lot of multiplications, divisions, complex math functions, floating point operations, etc? This can start to take a lot of instructions depending on what you're doing. Using things like printf support can also take a lot of space. You may want to try changing your optimization level and set it to optimize for size over speed, and look into things like IQMathLib. You also may want to see if there are ways you may be able to modify or restructure your code to try to help optimize it to take less space.

    You also might want to try looking at your .map file for the project in the Debug folder - this will show you where different functions and variables have been placed - it might help you see what functions are taking up the bulk of your code space.

    Regards,

    Katie

  • Yaay! it worked! Thank you!

    So I filled out created arrays and it worked fine.

    But then after I used written by me void function, that uses sqrt function as well - it shows an error again:

    A program will not fit into available memory. placement with alignment fails for section "ALL_FRAM" size 0x580d . Available memory ranges: lnk_msp430fr5739.cmd /DataCollection line 129 C/C++ Problem

    So I don't quite understand.

    Before using this function everything was fine, AND .text should have occupied only x200 memory slots:

    GROUP(EXECUTABLE_MEMORY)
    {
    .text : {} /* Code */
    } ALIGN(0x0200), RUN_START(fram_rx_start)

    However from the picture above you can see, that .text accupies much more memory: 4104 slots!

    I tried changing the size of .text in fram and it didnt help..

  • I can't even check how much memory my function takes as I can't execute it at all because of the lack of memory.

    It works in Visual Studio, so I just replaced it in CCS:

    I'm trying to find an autocorrelation function here:

    input: int data[size_buf ] - is an array of x-values from accelerometer, stored in fram(x400)

    output: float autocorrelation[size_buf] - also stored in fram(x800)

    void ACF(int data[])
    {
    	// data - filtered data from x-axis
    	int i = 0;
    	for(i = 0; i < size_buf - 2; i++)
    	{
    		// searching for different parts of the formula:
    		float av1 = 0; // average values for further calculations
    		float av2 = 0;
    		int k = 0;
    		for (k = i + 1; k < size_buf; k++)
    		{
    			av1 += data[k];
    			av2 += data[k - 1 - i];
    		}
    		av1 = av1/(size_buf - 1 - i);
    		av2 = av2/(size_buf - 1 - i);
    //numerator: float numerator = 0; k = 0; for (k = i + 1; k < size_buf; k++) { numerator += (data[k] - av1) * (data[k - 1] - av2); }
    //denominator: float sav1 = 0;// square av values float sav2 = 0; float denominator = 0; k = 0; for (k = i + 1; k < size_buf; k++) { sav1 += (data[k] - av1) * (data[k] - av1); sav2 += (data[k - 1] - av2) * (data[k - 1] - av2); } denominator = sqrt(sav1 * sav2);

    // output autocorrelation[i] = numerator / denominator; } }

  • These are results from optimizer assistant:

  • Oh my God :D

    I'm totally lost.

    Again. When I don't use ACF function:

    1st step:

    SECTIONS
    {
        GROUP(ALL_FRAM)
        {
        // MY GROUP FOR ARRAYS:
    		GROUP(READ_WRITE_MEMORY)
    		{
    		   .cio        : {}                   /* C I/O BUFFER                      */
    		   .sysmem     : {}                   /* DYNAMIC MEMORY ALLOCATION AREA    */
    		   .xAxis     : {}  //space allocated to store variables in FRAM
    		} ALIGN(0x200), RUN_START(fram_rw_start)
    
    		GROUP(READ_WRITE_MEMORY)
    		{
    		   .cio        : {}
    		   //.sysmem     : {}
    		   .yAxis     : {}  //space allocated to store variables in FRAM
    		} ALIGN(0x200), RUN_START(fram_rw_start)
    		GROUP(READ_WRITE_MEMORY)
    		{
    		   .cio        : {}
    		   //.sysmem     : {}
    		   .zAxis     : {}  //space allocated to store variables in FRAM
    		} ALIGN(0x200), RUN_START(fram_rw_start)
    		GROUP(READ_WRITE_MEMORY)
    		{
    		   .cio        : {}
    		   //.sysmem     : {}
    		   .myVars     : {}  //space allocated to store variables in FRAM
    		} ALIGN(0x400), RUN_START(fram_rw_start)
    
           GROUP(READ_WRITE_MEMORY)
           {
              .TI.persistent : {}                /* For #pragma persistent            */
              .cio        : {}                   /* C I/O buffer                      */
              .sysmem     : {}                   /* Dynamic memory allocation area    */
           } ALIGN(0x0200), RUN_START(fram_rw_start)
    
           GROUP(READ_ONLY_MEMORY)
           {
              .cinit      : {}                   /* Initialization tables             */
              .pinit      : {}                   /* C++ constructor tables            */
              .init_array : {}                   /* C++ constructor tables            */
              .mspabi.exidx : {}                 /* C++ constructor tables            */
              .mspabi.extab : {}                 /* C++ constructor tables            */
              .const      : {}                   /* Constant data                     */
           } ALIGN(0x0200), RUN_START(fram_ro_start)
    
           GROUP(EXECUTABLE_MEMORY)
           {
              .text       : {}                   /* Code                              */
           } ALIGN(0x0200), RUN_START(fram_rx_start)
        } > FRAM

    2. Now I can define int x[200],y[200],z[200], float autocorrelation[200] arrays,which take:

    x,y,z array -> 200*2bytes = 400bytes = x190 slots in fram memory each

    autocorrelation array -> 200*4bytes = 800bytes = x320 slots in fram memory

    3. Next I build the project -> go to .map file and everything here seems fine.

    4. I uncomment ACF function. Debug, it shows error: 

    program will not fit into available memory. placement with alignment fails for section "ALL_FRAM" size 0x463d . Available memory ranges: lnk_msp430fr5739.cmd /DataCollection line 129 C/C++ Problem

    5. Check .map file:

    name                        origin            length         used         unused

      FRAM                  0000c200   00003d80  00000000  00003d80

    SECTION ALLOCATION MAP
     output                                  attributes/
    section   page    origin      length       input sections
    --------  ----  ----------  ----------   ----------------
    .cio       0    00000000    00000000     FAILED TO ALLOCATE
    .sysmem    0    00000000    00000000     FAILED TO ALLOCATE
    .xAxis     0    00000000    00000190     FAILED TO ALLOCATE
    .cio       0    00000200    00000000     FAILED TO ALLOCATE
    .yAxis     0    00000200    00000190     FAILED TO ALLOCATE
    .cio       0    00000400    00000000     FAILED TO ALLOCATE
    .zAxis     0    00000400    00000190     FAILED TO ALLOCATE
    .cio       0    00000800    00000000     FAILED TO ALLOCATE
    .myVars    0    00000800    00000320     FAILED TO ALLOCATE
    .TI.persistent 
    *          0    00000c00    00000000     FAILED TO ALLOCATE
    .cio       0    00000c00    00000000     FAILED TO ALLOCATE
    .sysmem    0    00000c00    00000000     FAILED TO ALLOCATE
    .cinit     0    00000c00    0000020a     FAILED TO ALLOCATE
    .pinit     0    00000e0a    00000000     FAILED TO ALLOCATE
    .init_array 
    *          0    00000e0a    00000000     FAILED TO ALLOCATE
    .mspabi.exidx 
    *          0    00000e0a    00000000     FAILED TO ALLOCATE
    .mspabi.extab 
    *          0    00000e0a    00000000     FAILED TO ALLOCATE
    .const     0    00000e0a    00000010     FAILED TO ALLOCATE
    .text      0    00001000    00002c5a     FAILED TO ALLOCATE
    .data      0    00001c00    000001b6     UNINITIALIZED
  • ops, i thought it will run automatically, didn't know I had to press green triangle.

    Can't delete this post, sorry

  • I solved all my problems! Thank you for advising fixed point arythmetic library! It was a crucial moment in my problem.

    Now I have a bug:

    So, now I have flashing lights while I tilt the board - as in initial user experience example.

    And when the array fills out with 200 samples from accelerometer it starts sending data to laptop. And starting from this moment flashing lights don't work for some time and if I keep board not moving, than after sending lights work in a normal way again. But if I continue tilting the board while sending data to laptop - it stops working. And I assume that the problem might be in interruption handlers. What if I disable all interruptions while sending data? Will it resolve my problem? How do you think?

    In ADC10IV interrupt handler I change only one variable that doesnt affect anyhow the process of sending..

  • Hi Sergei,

    This is just a guess, but if you have interrupt driven code with interrupts for reading accelerometer + interrupts for sending data back to PC, it could be that you are having interrupts block each other. For example, if the reading of the accelerometer is (inherently in the device) a lower priority interrupt than sending the data, and the code doesn't handle the case where you have both of these come in at once or things are happening quickly enough, it could be that the sending data interrupt flag is getting set quickly enough that it keeps re-entering that interrupt and never servicing your accel. interrupt. (this is a guess b/c I don't know how you have everything set up).

    There are some other threads in this forum that handle similar cases if you do a search. General advice is to try to optimize your ISRs to keep them absolutely as short as possible - for example don't call a lot of functions in the ISR, don't try to send an entire packet from inside the ISR but rather get in the ISR, acknowledge the interrupt in some way (set a software variable etc) and get back out - handle the rest of processing (like arranging a data packet to be sent) in your main loop as much as possible just based on these software flags. That way your ISRs hopefully won't block each other. You can also do things in your software ISR to try to check flags for other interrupts and figure out if something needs to be done for handling those (basically helping work-around the normal priority of the device interrupts to handle more in your own priority). Increasing CPU frequency so part executes instructions faster to get through the ISR quickly can also help sometimes.

    A strategy to help figure out what's going on can be setting unused GPIOs high/low to indicate when you enter and exit a particular ISR or function - doing this with a few parts of your code, you can then monitor these lines on a scope or logic analyzer to see if your code for example is constantly staying in the same ISR and the other one is never getting a chance to be serviced.

    Unfortunately this is a tricky issue and is very specific to the application itself, so a bit hard to help you debug - it will probably take some iterative changes and work for you to get it working for your own particular case.

    Regards,

    Katie

**Attention** This is a public forum