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.

stack inside FRAM on MSP430 (Ink_msp430fr6989.cmd)

Other Parts Discussed in Thread: MSP430FR6989, MSP430FR5859

Hey everyone,

I am working on a new project and I would like everything, main code, variables, stack, etc to be inside the FRAM on the MSP430FR6989. Currently, if I put all the of the variables in FRAM it works fine. I can follow the arrays into a spot in FRAM, but I cannot follow variables into FRAM (I'm 90% sure it just sits inside the stack pointer, which is inside SRAM). 

If I put .stack as going into FRAM it will compile and run on code composer, but then it will go into boot_special.c and not properly run the code, all without me even running the program. 

It'll go into this section in boot_special:

/*****************************************************************************/
/* C_INT00_NOINIT_NOEXIT_MPU_INIT() - Specialized version of _c_int00 that */
/* initializes the FRAM memory protection */
/* unit and does not perform auto */
/* initialization and calls abort */
/* directly. */
/*****************************************************************************/
#pragma CLINK(_c_int00_noinit_noargs_noexit_mpu)
CSTART_DECL _c_int00_noinit_noargs_noexit_mpu()
{
STACK_INIT();
__mpu_init();
_system_pre_init();
main(0);
abort();
}

and then go into pre_init.c

I'm just currently messing around with the linker command file (Ink_msp430fr6989.cmd) and changing everything to FRAM vs. RAM

GROUP(SIGNATURE_SHAREDMEMORY)
{
.ipesignature : {} /* IPE Signature */
.jtagpassword : {} /* JTAG Password */
} > IPESIGNATURE

.bss : {} > FRAM /* Global & static vars */
.data : {} > FRAM /* Global & static vars */
.TI.noinit : {} > FRAM /* For #pragma noinit */
.stack : {} > FRAM (HIGH) /* Software system stack */
.tinyram : {} > TINYRAM /* Tiny RAM */

.infoA : {} > INFOA /* MSP430 INFO FRAM Memory segments */
.infoB : {} > INFOB
.infoC : {} > INFOC
.infoD : {} > INFOD

normally .bss, .data, .TI.noinit, and .stack are all RAM and not FRAM.

I would think the desire to put the stack in the FRAM would not be uncommon, and that it would work. I'm actually sure it'll work because in the Best Practices for FRAM that I see all over (www.ti.com/.../slaa628.pdf) in section 3 it says you can place stacks inside FRAM.

I am still somewhat new to the more assembly level programming stuff, so I would appreciate any help in getting the stack inside the FRAM, or any method of simply putting variables, constants, and main executable code inside of FRAM and out of normal RAM. 

  • What do you mean by "cannot follow variables into FRAM"?

  • First of all, are you concerned about available amount of FRAM and SRAM? Or power consumption, operating speed, data retention after power cycle etc.? If not, there is not much difference between FRAM and SRAM.

    You put your global/static data in FRAM so you can "see" them, you will be able to "see" them if there were in SRAM too.

    If you cannot "see" your other data in SRAM stack, you will not be able to "see" them if there were in FRAM either.
  • I am a little concerned about available SRAM, but more about I just want to see everything in FRAM because I would like everything to be there once it powers down, and I mean everything.

    I'm sorry for the confusion, when I say see them I mean follow "memory browser" inside of code composer. It lets me see all of the values of every single memory location inside of the MSP.

    I hope everyone can see this alright. On the bottom right is where I can see all of the memory locations. FRAM "starts" at 0x4400, with everything above it being SRAM. on the top right is all of the registers. It shows  the stack pointer address (currently at 0x0023FC (outside of FRAM).  The bottom left contains the linker I am trying to edit. I have edited lines 189 to 191. If I edit 192 so that it says FRAM it will start getting weird on me.

    When I say I see them in FRAM, I mean I see then in the memory address after 0x4400 (where FRAM starts for the MSP430FR6989). For example on line 0x0044IE on the bottom right, it has values of 2010 4030 ect ect. That was me saving an array of 10, 20, 30, 40 etc (just to see where it would go). When it comes to simple variables (such as uint8_t i = 0;) I will follow the assembly code and it appears to only be saving it to the Stack Pointer, nowhere else. 

    Hopefully, this clears up some of what I was trying to say.

  • Please change stack to FRAM and post the content of the generated map file under Debug folder.

  • What if you change that "0x4400" into "0x2400"?

  • FRAM map.txt

    I uploaded it in a .txt format, in case someone doesn't have Code Composer handy. They have the same format, I double checked.

    The parts of the file concerning the stack I have below:

    123 .stack     0    0000fee0    000000a0     UNINITIALIZED
    124                  0000fee0    00000004     rts430x_lc_rd_eabi.lib : boot.obj (.stack)
    125                  0000fee4    0000009c     --HOLE--
    
    295      Stack:             0      0         160    
    296   +--+------------------+------+---------+---------+
    297      Grand Total:       184    68        160  
    
    1699 0000ff80  __STACK_END
    1700 000000a0  __STACK_SIZE
    
    1738 0000fee0  _stack 
    
    1753 GLOBAL SYMBOLS: SORTED BY Symbol Address 
    1754
    1755 address   name                             
    1756 -------   ----                             
    1757 00000001  __mpu_enable                     
    1758 000000a0  __STACK_SIZE                     
    1759 00000100  SFRIE1        
    
    3156 00004400  _c_int00_noinit_noargs_noexit_mpu
    3157 00004400  fram_ipe_end                     
    3158 00004400  fram_ipe_start                   
    3159 00004400  fram_rw_start                    
    3160 00004400  fram_rx_start                    
    3161 00004416  __TI_ISR_TRAP                    
    3162 0000a501  mpu_ctl0_value                   
    3163 0000fee0  _stack                           
    3164 0000ff80  __STACK_END

    On my particular device, FRAM starts at value 0x4400 (which can be seen on lines 3156 and beyond.

  • Unfortunatly, they is just a search bar. I just searched the address 0x4400 to look at FRAM. This is what it looks like if I search 0x2400


    0x0023E0 0046 0001 1122 AAAF 5604 0000 0062 0001 FFFF BCAB DECD FFEF 5511 4433 4416 0000
    0x002400 3FFF 3FFF 3FFF 3FFF 3FFF 3FFF 3FFF 3FFF 3FFF 3FFF 3FFF 3FFF 3FFF 3FFF 3FFF 3FFF
    0x002420 3FFF 3FFF 3FFF 3FFF 3FFF 3FFF 3FFF 3FFF 3FFF 3FFF 3FFF 3FFF 3FFF 3FFF 3FFF 3FFF
  • The SRAM is from 0x001C00 to 0x0023FF. So you actually can see the contents of SRAM in the Memory Browser.

    The first line, 0x0023E0 ..., shows the contents of last 32 bytes of the SRAM. Currently, the stack is in SRAM and the stack pointer is pointing at 0x0023FC. Hence the content of the stack is:
    0x0023FC 4416 0000
    only 4 bytes and nothing else. The rest of SRAM contends meaningless garbage. Your "variable in stack" are nowhere to be seen.

    The reason is, those variables are dynamically allocated in the stack as needed. They are nowhere at the time you use the Memory Browser. You need to do it during the "life-time" of those variables to see them.

    Now if you put the stack in FRAM instead of SRAM, the same thing will happen. It is no-better and no-worse.
  • I guess that makes sense, but I am still curious why it would stop in the first place. I'm testing all of this in the debugger in code composer, and when I try and run it with the stack in FRAM it will down a route I am unfamiliar with. It will do all of the following before the code actually starts, ie while it is initializing the program.

    /*****************************************************************************/
    /* C_INT00_NOINIT_NOEXIT_MPU_INIT() - Specialized version of _c_int00 that   */
    /*                                    initializes the FRAM memory protection */
    /*                                    unit and does not perform auto         */
    /*                                    initialization and calls abort         */
    /*                                    directly.                              */
    /*****************************************************************************/
    #pragma CLINK(_c_int00_noinit_noargs_noexit_mpu)
    CSTART_DECL _c_int00_noinit_noargs_noexit_mpu()
    {
       STACK_INIT();
       __mpu_init();
       _system_pre_init();
       main(0);
       abort();
    }
    
    
    ======================================================================================================
    The code I can find on STACK_INIT(); is from a header file called boot.h
    ======================================================================================================
    
    #include <stdlib.h>
    #include <_lock.h>
    
    extern int _args_main();
    extern int main(int argc);
    extern void exit(int status);
    extern void _auto_init();
    
    #if defined(__LARGE_CODE_MODEL__)
    #define CSTART_DECL __attribute__((section(".text:_isr"))) void __interrupt
    #else
    #define CSTART_DECL void __interrupt
    #endif
    
    __asm("\t.global __STACK_END");
    
    /*---------------------------------------------------------------------------*/
    /* Macro to initialize stack pointer.  Stack grows towards lower memory.     */
    /*---------------------------------------------------------------------------*/
    #if defined(__LARGE_DATA_MODEL__)
    #define STACK_INIT() __asm("\t   MOVX.A\t   #__STACK_END,SP")
    #else
    #define STACK_INIT() __asm("\t   MOV.W\t    #__STACK_END,SP")
    #endif
    
    
    ======================================================================================================
    It will go through and stop on _system_pre_init();, which has this following code:
    ======================================================================================================
    
    /*****************************************************************************/
    /* _SYSTEM_PRE_INIT() - _system_pre_init() is called in the C/C++ startup    */
    /* routine (_c_int00()) and provides a mechanism for the user to             */
    /* insert application specific low level initialization instructions prior   */
    /* to calling main().  The return value of _system_pre_init() is used to     */
    /* determine whether or not C/C++ global data initialization will be         */
    /* performed (return value of 0 to bypass C/C++ auto-initialization).        */
    /*                                                                           */
    /* PLEASE NOTE THAT BYPASSING THE C/C++ AUTO-INITIALIZATION ROUTINE MAY      */
    /* RESULT IN PROGRAM FAILURE.                                                */
    /*                                                                           */
    /* The version of _system_pre_init() below is skeletal and is provided to    */
    /* illustrate the interface and provide default behavior.  To replace this   */
    /* version rewrite the routine and include it as part of the current project.*/
    /* The linker will include the updated version if it is linked in prior to   */
    /* linking with the C/C++ runtime library.                                   */
    /*****************************************************************************/
    
    int _system_pre_init(void)
    {
        return 1;
    }
    
    
    ======================================================================================================
    The header file for this section is called boot_hooks.h
    ======================================================================================================
    
    #ifndef _TI_BOOT_HOOKS_H
    #define _TI_BOOT_HOOKS_H
    
    extern int _system_pre_init(void);
    extern void _system_post_cinit(void);
    
    #endif
    
    

    I am terribly for the format of code, I hope it makes sense. When the code is initializing for debug it will go through boot_special.c. Inside of boot special, it will run through STACK_INIT(); , __mpu_init(); , and then freeze on _system_pre_init(); (which I think is where I am supposed to write custom init code)? The following is the entire boot_special.c

    boot_special.txt
    /*****************************************************************************/
    /* BOOT_SPECIAL.C   v15.12.3 - Specialized boot routines                     */
    /*                                                                           */
    /* Copyright (c) 2013-2016 Texas Instruments Incorporated                    */
    /* http://www.ti.com/                                                        */
    /*                                                                           */
    /*  Redistribution and  use in source  and binary forms, with  or without    */
    /*  modification,  are permitted provided  that the  following conditions    */
    /*  are met:                                                                 */
    /*                                                                           */
    /*     Redistributions  of source  code must  retain the  above copyright    */
    /*     notice, this list of conditions and the following disclaimer.         */
    /*                                                                           */
    /*     Redistributions in binary form  must reproduce the above copyright    */
    /*     notice, this  list of conditions  and the following  disclaimer in    */
    /*     the  documentation  and/or   other  materials  provided  with  the    */
    /*     distribution.                                                         */
    /*                                                                           */
    /*     Neither the  name of Texas Instruments Incorporated  nor the names    */
    /*     of its  contributors may  be used to  endorse or  promote products    */
    /*     derived  from   this  software  without   specific  prior  written    */
    /*     permission.                                                           */
    /*                                                                           */
    /*  THIS SOFTWARE  IS PROVIDED BY THE COPYRIGHT  HOLDERS AND CONTRIBUTORS    */
    /*  "AS IS"  AND ANY  EXPRESS OR IMPLIED  WARRANTIES, INCLUDING,  BUT NOT    */
    /*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR    */
    /*  A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT    */
    /*  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
    /*  SPECIAL,  EXEMPLARY,  OR CONSEQUENTIAL  DAMAGES  (INCLUDING, BUT  NOT    */
    /*  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,    */
    /*  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY    */
    /*  THEORY OF  LIABILITY, WHETHER IN CONTRACT, STRICT  LIABILITY, OR TORT    */
    /*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE    */
    /*  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.     */
    /*                                                                           */
    /*****************************************************************************/
    #include "boot.h"
    #include "boot_hooks.h"
    
    #ifdef __TI_RTS_BUILD
    /*---------------------------------------------------------------------------*/
    /* __TI_default_c_int00 indicates that the default TI entry routine is being  */
    /* used.  The linker makes assumptions about what exit does when this symbol */
    /* is seen. This symbols should NOT be defined if a customized exit routine  */
    /* is used.                                                                  */
    /*---------------------------------------------------------------------------*/
    __asm("__TI_default_c_int00 .set 1");
    #endif
    
    extern void __mpu_init(void);
    
    /*****************************************************************************/
    /* C_INT00_NOARGS() - Specialized version of _c_int00 that does not handle   */
    /*                    arguments passed to main.                              */
    /*****************************************************************************/
    #pragma CLINK(_c_int00_noargs)
    CSTART_DECL _c_int00_noargs()
    {
       STACK_INIT();
       if(_system_pre_init() != 0) _auto_init();
       main(0);
       exit(1);
    }
    
    /*****************************************************************************/
    /* C_INT00_NOEXIT() - Specialized version of _c_int00 that directly calls    */
    /*                    abort and skips cleanup in exit.                       */
    /*****************************************************************************/
    #pragma CLINK(_c_int00_noexit)
    CSTART_DECL _c_int00_noexit()
    {
       STACK_INIT();
       if(_system_pre_init() != 0) _auto_init();
       _args_main();
       abort();
    }
    
    /*****************************************************************************/
    /* C_INT00_NOINIT_NOEXIT() - Specialized version of _c_int00 that does not   */
    /*                           perform auto initialization and calls abort     */
    /*                           directly.                                       */
    /*****************************************************************************/
    #pragma CLINK(_c_int00_noinit_noargs_noexit)
    CSTART_DECL _c_int00_noinit_noargs_noexit()
    {
       STACK_INIT();
       _system_pre_init();
       main(0);
       abort();
    }
    
    /*****************************************************************************/
    /* C_INT00_NOINIT_NOEXIT() - Specialized version of _c_int00 that does not   */
    /*                           perform auto initialization and calls abort     */
    /*                           directly.                                       */
    /*****************************************************************************/
    #pragma CLINK(_c_int00_noargs_noexit)
    CSTART_DECL _c_int00_noargs_noexit()
    {
       STACK_INIT();
       if (_system_pre_init() != 0) _auto_init();
       main(0);
       abort();
    }
    
    /*****************************************************************************/
    /* C_INT00_MPU_INIT() - Specialized version of _c_int00 that initializes the */
    /*                      FRAM memory protection unit.                         */
    /*****************************************************************************/
    #pragma CLINK(_c_int00_mpu)
    CSTART_DECL _c_int00_mpu()
    {
       STACK_INIT();
       __mpu_init();
       if(_system_pre_init() != 0)  _auto_init();
       _args_main();
       exit(1);
    }
    
    /*****************************************************************************/
    /* C_INT00_NOARGS_MPU_INIT() - Specialized version of _c_int00 that          */ 
    /*                             initializes the FRAM memory protection unit   */
    /*                             and does not handle arguments passed to main. */
    /*****************************************************************************/
    #pragma CLINK(_c_int00_noargs_mpu)
    CSTART_DECL _c_int00_noargs_mpu()
    {
       STACK_INIT();
       __mpu_init();
       if(_system_pre_init() != 0) _auto_init();
       main(0);
       exit(1);
    }
    
    /*****************************************************************************/
    /* C_INT00_NOEXIT_MPU_INIT() - Specialized version of _c_int00 that          */
    /*                             initializes the FRAM memory protection unit   */
    /*                             and directly calls abort and skips cleanup in */
    /*                             exit.                                         */
    /*****************************************************************************/
    #pragma CLINK(_c_int00_noexit_mpu)
    CSTART_DECL _c_int00_noexit_mpu()
    {
       STACK_INIT();
       __mpu_init();
       if(_system_pre_init() != 0) _auto_init();
       _args_main();
       abort();
    }
    
    /*****************************************************************************/
    /* C_INT00_NOINIT_NOEXIT_MPU_INIT() - Specialized version of _c_int00 that   */
    /*                                    initializes the FRAM memory protection */
    /*                                    unit and does not perform auto         */
    /*                                    initialization and calls abort         */
    /*                                    directly.                              */
    /*****************************************************************************/
    #pragma CLINK(_c_int00_noinit_noargs_noexit_mpu)
    CSTART_DECL _c_int00_noinit_noargs_noexit_mpu()
    {
       STACK_INIT();
       __mpu_init();
       _system_pre_init();
       main(0);
       abort();
    }
    
    /*****************************************************************************/
    /* C_INT00_NOINIT_NOEXIT_MPU_INIT() - Specialized version of _c_int00 that   */
    /*                                    initializes the FRAM memory protection */
    /*                                    unit and does not perform auto         */
    /*                                    initialization and calls abort         */
    /*                                    directly.                              */
    /*****************************************************************************/
    #pragma CLINK(_c_int00_noargs_noexit_mpu)
    CSTART_DECL _c_int00_noargs_noexit_mpu()
    {
       STACK_INIT();
       __mpu_init();
       if (_system_pre_init() != 0) _auto_init();
       main(0);
       abort();
    }
    
    
    

    I would appreciate help in understanding why it does this when I am going through the debugger, and what I should do.

  • Do you mean that it can't go to main() function when stack is placed in FRAM?
    Can you set a breakpoint at main() and free-run to test if it can run to main() function?
  • I tried using breakpoints, but it never reaches the one I set at main().

  • I think you were using a special "c-startup code" that "does not set up the stack, and does not startup main()"
  • Hi to all, I have been through the same issue Aaron posted in the first place.

    What is the problem behind the main() function not being reached with the stack is allocated in FRAM? Is it necessary to code the function _system_pre_init, whose by-default code is as follows:?

    int _system_pre_init(void)
    {
    return 1;
    }

    In my case, the execution freezes in the call: if (_system_pre_init() != 0) _auto_init(); which calls _system_pre_init() and I don't know why...
  • Bump!

    Can we continue this discussion, I am having some very similar issues, and I am sure others will in the future as the FRAM series becomes more widely adopted.  I have a program which runs completely in FRAM on a MSP4305859. 

    Problem:
    The program has no issues until the code size is increased beyond some threshold.  Once larger than certain threshold, when running the debugger, it can not reach the Main entry point. 

    Environment:
    The IPE is disabled via GUI project properties selection, the MPU is set to manaul settings, with every option selected (read/write/execute).  I see similar results with the MPU completely disabled when the code size is small enough for things to run properly.

    Cmd file:
    /****************************************************************************/
    /* 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 = 0x4000
        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
    }

    /****************************************************************************/
    /* Specify the sections allocation into memory                              */
    /****************************************************************************/

    SECTIONS
    {
        GROUP(RW_IPE)
        {
            GROUP(READ_WRITE_MEMORY)
            {
               .TI.persistent : {}              /* For #pragma persistent            */
               .cio           : {}              /* C I/O Buffer                      */
               .sysmem        : {}              /* Dynamic memory allocation area    */
            } PALIGN(0x0400), RUN_START(fram_rw_start)

            GROUP(IPENCAPSULATED_MEMORY)
            {
               .ipestruct     : {}              /* IPE Data structure                */
               .ipe           : {}              /* IPE                               */
               .ipe_const     : {}              /* IPE Protected constants           */
               .ipe:_isr      : {}              /* IPE ISRs                          */
               .ipe_vars      : type = NOINIT{} /* IPE variables                     */
            } PALIGN(0x0400), RUN_START(fram_ipe_start) RUN_END(fram_ipe_end) RUN_END(fram_rx_start)
        } > 0x4400

        .cinit            : {}  > FRAM         /* Initialization tables             */
        .pinit            : {}  > FRAM         /* C++ Constructor tables            */
        .binit            : {}  > FRAM         /* Boot-time Initialization tables   */
        .init_array       : {}  > FRAM         /* C++ Constructor tables            */
        .mspabi.exidx     : {}  > FRAM         /* C++ Constructor tables            */
        .mspabi.extab     : {}  > FRAM         /* C++ Constructor tables            */
    #ifndef __LARGE_DATA_MODEL__
        .const            : {} > FRAM           /* Constant data                     */
    #else
        //.const            : {} >> FRAM | FRAM2  /* Constant data                     */
        .const            : {} >> FRAM /* Constant data                     */
    #endif

        .text:_isr        : {}  > FRAM          /* Code ISRs                         */
    #ifndef __LARGE_DATA_MODEL__
        .text             : {} > FRAM          /* Code                              */
    #else
        //.text             : {} >> FRAM2 | FRAM  /* Code                              */
        .text             : {} >> FRAM /* Code                              */
    #endif
    #ifdef __TI_COMPILER_VERSION__
      #if __TI_COMPILER_VERSION__ >= 15009000
        #ifndef __LARGE_DATA_MODEL__
       // .TI.ramfunc : {} load=FRAM, run=RAM, table(BINIT)
        #else
        .TI.ramfunc : {} load= FRAM, run= FRAM, table(BINIT)
        #endif
      #endif
    #endif

        .jtagsignature : {} > JTAGSIGNATURE     /* JTAG Signature                    */
        .bslsignature  : {} > BSLSIGNATURE      /* BSL Signature                     */

        GROUP(SIGNATURE_SHAREDMEMORY)
        {
            .ipesignature  : {}                 /* IPE Signature                     */
            .jtagpassword  : {}                 /* JTAG Password                     */
        } > IPESIGNATURE

        //.bss        : {} > RAM                  /* Global & static vars              */
        //.data       : {} > RAM                  /* Global & static vars              */
        //.TI.noinit  : {} > RAM                  /* For #pragma noinit                */
        //.stack      : {} > RAM (HIGH)           /* Software system stack             */
        .bss        : {} > FRAM                /* Global & static vars              */
        .data       : {} > FRAM                /* Global & static vars              */
        .TI.noinit  : {} > FRAM                /* For #pragma noinit                */
        .stack      : {} > FRAM (HIGH)              /* Software system stack             */

        .infoA     : {} > INFOA              /* MSP430 INFO FRAM  Memory segments */
        .infoB     : {} > INFOB
        .infoC     : {} > INFOC
        .infoD     : {} > INFOD

        /* MSP430 Interrupt vectors          */
        .int00       : {}               > INT00
        .int01       : {}               > INT01
        .int02       : {}               > INT02
        .int03       : {}               > INT03
        .int04       : {}               > INT04
        .int05       : {}               > INT05
        .int06       : {}               > INT06
        .int07       : {}               > INT07
        .int08       : {}               > INT08
        .int09       : {}               > INT09
        .int10       : {}               > INT10
        .int11       : {}               > INT11
        .int12       : {}               > INT12
        .int13       : {}               > INT13
        .int14       : {}               > INT14
        .int15       : {}               > INT15
        .int16       : {}               > INT16
        .int17       : {}               > INT17
        .int18       : {}               > INT18
        .int19       : {}               > INT19
        .int20       : {}               > INT20
        .int21       : {}               > INT21
        .int22       : {}               > INT22
        .int23       : {}               > INT23
        .int24       : {}               > INT24
        .int25       : {}               > INT25
        .int26       : {}               > INT26
        .int27       : {}               > INT27
        .int28       : {}               > INT28
        .int29       : {}               > INT29
        .int30       : {}               > INT30
        RTC          : { * ( .int31 ) } > INT31 type = VECT_INIT
        PORT4        : { * ( .int32 ) } > INT32 type = VECT_INIT
        PORT3        : { * ( .int33 ) } > INT33 type = VECT_INIT
        TIMER3_A1    : { * ( .int34 ) } > INT34 type = VECT_INIT
        TIMER3_A0    : { * ( .int35 ) } > INT35 type = VECT_INIT
        PORT2        : { * ( .int36 ) } > INT36 type = VECT_INIT
        TIMER2_A1    : { * ( .int37 ) } > INT37 type = VECT_INIT
        TIMER2_A0    : { * ( .int38 ) } > INT38 type = VECT_INIT
        PORT1        : { * ( .int39 ) } > INT39 type = VECT_INIT
        TIMER1_A1    : { * ( .int40 ) } > INT40 type = VECT_INIT
        TIMER1_A0    : { * ( .int41 ) } > INT41 type = VECT_INIT
        DMA          : { * ( .int42 ) } > INT42 type = VECT_INIT
        USCI_A1      : { * ( .int43 ) } > INT43 type = VECT_INIT
        TIMER0_A1    : { * ( .int44 ) } > INT44 type = VECT_INIT
        TIMER0_A0    : { * ( .int45 ) } > INT45 type = VECT_INIT
        ADC12        : { * ( .int46 ) } > INT46 type = VECT_INIT
        USCI_B0      : { * ( .int47 ) } > INT47 type = VECT_INIT
        USCI_A0      : { * ( .int48 ) } > INT48 type = VECT_INIT
        WDT          : { * ( .int49 ) } > INT49 type = VECT_INIT
        TIMER0_B1    : { * ( .int50 ) } > INT50 type = VECT_INIT
        TIMER0_B0    : { * ( .int51 ) } > INT51 type = VECT_INIT
        COMP_E       : { * ( .int52 ) } > INT52 type = VECT_INIT
        UNMI         : { * ( .int53 ) } > INT53 type = VECT_INIT
        SYSNMI       : { * ( .int54 ) } > INT54 type = VECT_INIT
        .reset       : {}               > RESET  /* MSP430 Reset vector         */
    }

    /****************************************************************************/
    /* MPU/IPE Specific memory segment definitons                               */
    /****************************************************************************/

    #ifdef _IPE_ENABLE
       #define IPE_MPUIPLOCK 0x0080
       #define IPE_MPUIPENA 0x0040
       #define IPE_MPUIPPUC 0x0020

       // Evaluate settings for the control setting of IP Encapsulation
       #if defined(_IPE_ASSERTPUC1)
            #if defined(_IPE_LOCK ) && (_IPE_ASSERTPUC1 == 0x08))
             fram_ipe_enable_value = (IPE_MPUIPENA | IPE_MPUIPPUC |IPE_MPUIPLOCK);
            #elif defined(_IPE_LOCK )
             fram_ipe_enable_value = (IPE_MPUIPENA | IPE_MPUIPLOCK);
          #elif (_IPE_ASSERTPUC1 == 0x08)
             fram_ipe_enable_value = (IPE_MPUIPENA | IPE_MPUIPPUC);
          #else
             fram_ipe_enable_value = (IPE_MPUIPENA);
          #endif
       #else
          #if defined(_IPE_LOCK )
             fram_ipe_enable_value = (IPE_MPUIPENA | IPE_MPUIPLOCK);
          #else
             fram_ipe_enable_value = (IPE_MPUIPENA);
          #endif
       #endif

       // Segment definitions
       #ifdef _IPE_MANUAL                  // For custom sizes selected in the GUI
          fram_ipe_border1 = (_IPE_SEGB1>>4);
          fram_ipe_border2 = (_IPE_SEGB2>>4);
       #else                           // Automated sizes generated by the Linker
          fram_ipe_border2 = fram_ipe_end >> 4;
          fram_ipe_border1 = fram_ipe_start >> 4;
       #endif

       fram_ipe_settings_struct_address = Ipe_settingsStruct >> 4;
       fram_ipe_checksum = ~((fram_ipe_enable_value & fram_ipe_border2 & fram_ipe_border1) | (fram_ipe_enable_value & ~fram_ipe_border2 & ~fram_ipe_border1) | (~fram_ipe_enable_value & fram_ipe_border2 & ~fram_ipe_border1) | (~fram_ipe_enable_value & ~fram_ipe_border2 & fram_ipe_border1));
    #endif

    #ifdef _MPU_ENABLE
       #define MPUPW (0xA500)    /* MPU Access Password */
       #define MPUENA (0x0001)   /* MPU Enable */
       #define MPULOCK (0x0002)  /* MPU Lock */
       #define MPUSEGIE (0x0010) /* MPU Enable NMI on Segment violation */

       __mpu_enable = 1;
       // Segment definitions
       #ifdef _MPU_MANUAL // For custom sizes selected in the GUI
          mpu_segment_border1 = _MPU_SEGB1 >> 4;
          mpu_segment_border2 = _MPU_SEGB2 >> 4;
          mpu_sam_value = (_MPU_SAM0 << 12) | (_MPU_SAM3 << 8) | (_MPU_SAM2 << 4) | _MPU_SAM1;
       #else // Automated sizes generated by Linker
          #ifdef _IPE_ENABLE //if IPE is used in project too
             //seg1 = any read + write persistent variables
             //seg2 = ipe = read + write + execute access
             //seg3 = code, read + execute only
             mpu_segment_border1 = fram_ipe_start >> 4;
             mpu_segment_border2 = fram_rx_start >> 4;
             mpu_sam_value = 0x1573; // Info R, Seg3 RX, Seg2 RWX, Seg1 RW
          #else
             mpu_segment_border1 = fram_rx_start >> 4;
             mpu_segment_border2 = fram_rx_start >> 4;
             mpu_sam_value = 0x1513; // Info R, Seg3 RX, Seg2 R, Seg1 RW
          #endif
       #endif
       #ifdef _MPU_LOCK
          #ifdef _MPU_ENABLE_NMI
             mpu_ctl0_value = MPUPW | MPUENA | MPULOCK | MPUSEGIE;
          #else
             mpu_ctl0_value = MPUPW | MPUENA | MPULOCK;
          #endif
       #else
          #ifdef _MPU_ENABLE_NMI
             mpu_ctl0_value = MPUPW | MPUENA | MPUSEGIE;
          #else
             mpu_ctl0_value = MPUPW | MPUENA;
          #endif
       #endif
    #endif

    /****************************************************************************/
    /* Include peripherals memory map                                           */
    /****************************************************************************/

    -l msp430fr5859.cmd


    Linker Flag List:

    -vmspx --data_model=restricted -O0 --opt_for_speed=1 --use_hw_mpy=F5 --advice:hw_config="all" --define=__MSP430FR5859__
     --define=_MPU_ENABLE --define=_MPU_MANUAL --define=_MPU_ENABLE_NMI --define=_MPU_SEGB1=0x4800
    --define=_MPU_SEGB2=0x4C00 --define=_MPU_SAM1=15 --define=_MPU_SAM2=15 --define=_MPU_SAM3=15 --define=_MPU_SAM0=15
    --undefine=_INLINE -g --printf_support=minimal --diag_warning=225 --diag_wrap=off --display_error_number --ramfunc=on
    --silicon_errata=CPU21 --silicon_errata=CPU22 --silicon_errata=CPU40 -z -m"Nema11_Stepper_Controller.map" --heap_size=256
    --stack_size=256 --cinit_hold_wdt=on -i"C:/ti/ccsv7/ccs_base/msp430/include" -i"C:/ti/ccsv7/ccs_base/msp430/lib/5xx_6xx_FRxx"
    -i"C:/ti/ccsv7/ccs_base/msp430/lib/FR59xx" -i"C:/ti/ccsv7/tools/compiler/ti-cgt-msp430_16.9.1.LTS/lib"
    -i"C:/ti/ccsv7/tools/compiler/ti-cgt-msp430_16.9.1.LTS/include" --priority --reread_libs --define=_MPU_ENABLE
    --define=_MPU_MANUAL --define=_MPU_ENABLE_NMI --define=_MPU_SEGB1=0x4800 --define=_MPU_SEGB2=0x4C00 --define=_MPU_SAM1=15
    --define=_MPU_SAM2=15 --define=_MPU_SAM3=15 --define=_MPU_SAM0=15 --diag_wrap=off --display_error_number --warn_sections
    --xml_link_info="Nema11_Stepper_Controller_linkInfo.xml" --use_hw_mpy=F5 --rom_model

    Compiler Flag List:

    -vmspx --data_model=restricted -O0 --opt_for_speed=1 --use_hw_mpy=F5
    --include_path="C:/ti/ccsv7/ccs_base/msp430/include"
    --include_path="C:/X/PROJECTS/SPAWAR/A00425/SOFTWARE/FIRMWARE/NEMA11_STEPPER_MC/Nema11_Stepper_Controller"
    --include_path="C:/ti/ccsv7/tools/compiler/ti-cgt-msp430_16.9.1.LTS/include" --advice:hw_config="all"
    --define=__MSP430FR5859__ --define=_MPU_ENABLE --define=_MPU_MANUAL --define=_MPU_SEGB1=0x4800
    --define=_MPU_SEGB2=0x4C00 --define=_MPU_SAM1=15 --define=_MPU_SAM2=15 --define=_MPU_SAM3=15
    --define=_MPU_SAM0=15 --undefine=_INLINE -g --printf_support=minimal --diag_warning=225 --diag_wrap=off
    --display_error_number --ramfunc=on --silicon_errata=CPU21 --silicon_errata=CPU22 --silicon_errata=CPU40

    Here is the memory allocation when code size is small enough for everything to work, IE, run the debugger, and I can reach the Main entry point, code runs properly.

    Here expanded:

    Here entering Main just fine when debugging...

    Now, when i increase code size, things start to get weird...  Here is the memory allocation with code size slightly larger, and now NOT functioning properly....

    When running the debugger, the Main point is not reached and it sits here...

    So clicking on TI MSP430..(Running) and then "pause" to find the debugger stuck here...

    Also included below are the various points it appears the program traveled before getting stuck

    Now, I have read that you should overload system_pre_init() with WDHOLD, and i tried this, but this causes even worse behavior.  For example, in the case of the working size code, I add this function to my main file, and do nothing inside of it except return 1, and the code that was working, no longer works.  I also attempt to return 0, with similar results.  So if you see below, instead of adding a custom system_pre_init() function, which is not helping, i add a hold watch dog line to boot_special.c ...

    However, once running, probing the Watchdog register via REGISTERS, it does not seem like the bit is set, so any help is greatly appreciated.


    Thanks

**Attention** This is a public forum