MSP430FR5969: SRAM/FRAM test and memory allocation

Part Number: MSP430FR5969

Tool/software:

Hi. I want to perform a test to check if the memory in MSP430FR5969 is working correctly.

I have a simple function that has a local array and two loops. The first loop assigns loop index to each element of the array. The second loop checks if each element of the array is equal to the loop index. I assume the array is allocated in stack section in RAM. When I change the size of the the local array, "Memory Allocation" panel in TI CCS still reports same RAM and stack usage, and reported FRAM and FRAM2 usage doesn't change either. If I change the size of the array to a value as large as the RAM size of the microcontroller, I receive no warning for this from TI CCS but the microcontroller resets every time the RAM test function is called. TI CCS generates an "array is too large" only if I change the size of the local array to a size larger than combined SRAM and FRAM size of the microcontroller. Why doesn't CCS generate this error reliably? What am I missing? How can I make sure that I don't run into allocation problems?

I looked into the linker file of the microcontroller for memory section addresses. In there, RAM origin is 0x1C00 and length is 0x0800. So assumably, first address of the RAM section is 0x1C00 and the last address is 0x23FF. When I debug the function described above, the local array has elements with addresses out of RAM range as expected. But I also noticed that the sections and their addresses are not continous, there are some unused addresses between memory sections. The memory is mapped as below in the table, starting from the lowest memory address to the highest, and I also included the memory map specification section from the linker file. I don't know how to read the linker file, therefore I want to ask if my interpretation is correct or wrong, if there are unmapped ranges in memory. If there are actually unmapped ranges, do they exist in the chip, even though they are not mapped? If they exist, what are they used for?

I also want to perform an instruction integrity check with a checksum algorithm or CRC module. How can I know at which address the instructions reside? Can I use the information in the .map file generated in the project folder? Or would you have a different recommendation?

Thanks.

Start address End address
SFR 0x0000 0x000F
PERIPHERALS_8BIT 0x0010 0x00FF
PERIPHERALS_16BIT 0x0100 0x01FF
unmapped range 0x0200 0x17FF
INFOD 0x1800 0x187F
INFOC 0x1880 0x18FF
INFOB 0x1900 0x197F
INFOA 0x1980 0x19FF
unmapped range 0x1A00 0x1BFF
RAM 0x1C00 0x23FF
unmapped range 0x2400 0x43FF
FRAM 0x4400 0xFF7F
signatures and interrupt vectors 0xFF80 0xFFFF
FRAM2 0x10000 0x13FF7

/****************************************************************************/
/* Specify the system memory map                                            */
/****************************************************************************/

MEMORY
{
    SFR                     : origin = 0x0000, length = 0x0010
    PERIPHERALS_8BIT        : origin = 0x0010, length = 0x00F0
    PERIPHERALS_16BIT       : origin = 0x0100, length = 0x0100
    RAM                     : origin = 0x1C00, length = 0x0800
    INFOA                   : origin = 0x1980, length = 0x0080
    INFOB                   : origin = 0x1900, length = 0x0080
    INFOC                   : origin = 0x1880, length = 0x0080
    INFOD                   : origin = 0x1800, length = 0x0080
    FRAM                    : origin = 0x4400, length = 0xBB80
    FRAM2                   : origin = 0x10000,length = 0x3FF8 /* Boundaries changed to fix CPU47 */
    JTAGSIGNATURE           : origin = 0xFF80, length = 0x0004, fill = 0xFFFF
    BSLSIGNATURE            : origin = 0xFF84, length = 0x0004, fill = 0xFFFF
    IPESIGNATURE            : origin = 0xFF88, length = 0x0008, fill = 0xFFFF
    INT00                   : origin = 0xFF90, length = 0x0002
    INT01                   : origin = 0xFF92, length = 0x0002
    INT02                   : origin = 0xFF94, length = 0x0002
    INT03                   : origin = 0xFF96, length = 0x0002
    INT04                   : origin = 0xFF98, length = 0x0002
    INT05                   : origin = 0xFF9A, length = 0x0002
    INT06                   : origin = 0xFF9C, length = 0x0002
    INT07                   : origin = 0xFF9E, length = 0x0002
    INT08                   : origin = 0xFFA0, length = 0x0002
    INT09                   : origin = 0xFFA2, length = 0x0002
    INT10                   : origin = 0xFFA4, length = 0x0002
    INT11                   : origin = 0xFFA6, length = 0x0002
    INT12                   : origin = 0xFFA8, length = 0x0002
    INT13                   : origin = 0xFFAA, length = 0x0002
    INT14                   : origin = 0xFFAC, length = 0x0002
    INT15                   : origin = 0xFFAE, length = 0x0002
    INT16                   : origin = 0xFFB0, length = 0x0002
    INT17                   : origin = 0xFFB2, length = 0x0002
    INT18                   : origin = 0xFFB4, length = 0x0002
    INT19                   : origin = 0xFFB6, length = 0x0002
    INT20                   : origin = 0xFFB8, length = 0x0002
    INT21                   : origin = 0xFFBA, length = 0x0002
    INT22                   : origin = 0xFFBC, length = 0x0002
    INT23                   : origin = 0xFFBE, length = 0x0002
    INT24                   : origin = 0xFFC0, length = 0x0002
    INT25                   : origin = 0xFFC2, length = 0x0002
    INT26                   : origin = 0xFFC4, length = 0x0002
    INT27                   : origin = 0xFFC6, length = 0x0002
    INT28                   : origin = 0xFFC8, length = 0x0002
    INT29                   : origin = 0xFFCA, length = 0x0002
    INT30                   : origin = 0xFFCC, length = 0x0002
    INT31                   : origin = 0xFFCE, length = 0x0002
    INT32                   : origin = 0xFFD0, length = 0x0002
    INT33                   : origin = 0xFFD2, length = 0x0002
    INT34                   : origin = 0xFFD4, length = 0x0002
    INT35                   : origin = 0xFFD6, length = 0x0002
    INT36                   : origin = 0xFFD8, length = 0x0002
    INT37                   : origin = 0xFFDA, length = 0x0002
    INT38                   : origin = 0xFFDC, length = 0x0002
    INT39                   : origin = 0xFFDE, length = 0x0002
    INT40                   : origin = 0xFFE0, length = 0x0002
    INT41                   : origin = 0xFFE2, length = 0x0002
    INT42                   : origin = 0xFFE4, length = 0x0002
    INT43                   : origin = 0xFFE6, length = 0x0002
    INT44                   : origin = 0xFFE8, length = 0x0002
    INT45                   : origin = 0xFFEA, length = 0x0002
    INT46                   : origin = 0xFFEC, length = 0x0002
    INT47                   : origin = 0xFFEE, length = 0x0002
    INT48                   : origin = 0xFFF0, length = 0x0002
    INT49                   : origin = 0xFFF2, length = 0x0002
    INT50                   : origin = 0xFFF4, length = 0x0002
    INT51                   : origin = 0xFFF6, length = 0x0002
    INT52                   : origin = 0xFFF8, length = 0x0002
    INT53                   : origin = 0xFFFA, length = 0x0002
    INT54                   : origin = 0xFFFC, length = 0x0002
    RESET                   : origin = 0xFFFE, length = 0x0002
}

  • This all seems pretty pointless. FRAM gets checked every time it gets accessed automatically by the ECC in theFRAM hardware. You can enable interrupts so you can execute some code in the event of an error.

    As for memory allocation, the compiler can only handle that by making assumptions. It is easy to confuse. So in order to avoid allocation errors, you have to keep it in mind. Don''t allocate large arrays, either global or automatic, unless you know there is space available.

  • The point is, the microcontroller needs to check itself while it is in its application environment. I want to do that via march tests in sram and fram of the microcontroller. It is preferable to have the array as large as possible.

  • Hi Andy,

    Those "unmapped" regions will typically not exist at all, the hardware addresses are locations so the CPU knows how to access the non-volatile memory or RAM regions, the addresses be sequential from FRAM to Peripheral Addresses to Interrupt addresses etc. Have large breaks protects against any overflow as well to prevent unexpected "valid" access to a region.

    Do you have optimization in your code? That could be a potential cause to why you don't get allocation issues until you actually overflow the total available memory.

    To read the linker, you are correct it is the Origin + Length = End Address.

    Regards,
    Luke

  • Have large breaks protects against any overflow as well to prevent unexpected "valid" access to a region.

    See also VMAIE.

**Attention** This is a public forum