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.

TMS320F28379D: Function Pointer Overwritten Before Reaching Main

Part Number: TMS320F28379D
Other Parts Discussed in Thread: C2000WARE

Referencing this forum post:

https://e2e.ti.com/support/microcontrollers/c2000/f/c2000-microcontrollers-forum/998430/tms320f28379d-debugging-itrap-interrupt_illegaloperatorhandler

While I was able to find that the ITRAP I was getting was because a function pointer was being overwritten, thus an invalid function call took place, I wasn't able to figure out why the function pointer was being overwritten in memory. In fact, I don't believe anything in my code is overwriting this function pointer. The issue I'm finding is that, say I assign a void pointer to the function pointer so it would be something like functPointer = (void*)0. Ideally after compile time the function pointer should read 0x00000000:

However, the first time I press the debug button and FLASH code onto CPU1 and CPU2 the function pointer value changes before I reach main(). Note that I have a single debug configuration that is set to program both cores one after the other. It will build code for each core then erase FLASH and load code onto each core:

0x0608015A is not a valid void function pointer so an ITRAP (illegal instruction ISR) is triggered. What would cause this function pointer to be overwritten prior to main.c during boot? Is something in Boot ROM going rogue and overwriting other memory regions?

To try to debug this further, I tried disabling Auto Run on program load/restart to step through Boot ROM and see if something changes the function pointer value:

However, the function pointer remains a void pointer throughout Boot ROM and never gets overwritten (i.e. I can't replicate the function pointer being overwritten with auto run on program load or restart disabled). As soon as I enable Auto Run to main on program load or restart and try flashing again, the problem re-surfaces...boggles my mind. 

Here's another wrinkle. If I am already in an active debug session, I can't replicate the issue after the first time I load the code onto both cores in FLASH. If I try a CPU reset/restart, the function pointer goes back to a normal value of 0x00000000. This problem seems to only occur on the first time I start a new debug session and FLASH code onto both cores. I have to stop the current debug session and re-start the debug session and FLASH code again onto both cores in order to see the problem again.

Could it be some weird issue with emulator debugger mode or boot ROM or linker CMD files not setup correctly? There is an errata out there for "Memory: Prefetching Beyond Valid Memory" so I'll have to investigate whether we are using M1 GS11 or GS15 as specified in errata SPRZ413L. Double checked the linker files and they specifically do not allow the endings of the invalid memory regions to be used as per the errata so it doesn't seem like the linker files are the issue. Although I do merge RAMLS0 and RAMLS1 to make RAMLS0_1 for TI ramfuncs on CPU1 (CPU2 only needs RAMLS0), not sure if this affects anything.

EDIT 5/12/2021: cleaned up & simplified the question

  • Hi Nigel,

    Can you clarify which board you are using to run your code? Is it a custom board or one of our standard C2000 EVMs? Can you provide a screenshot of the target config you are using when you start your debug session? Have you made any modifications to the GEL script that runs when the debug session is started?

    Note that I have a single debug configuration that is set to program both cores one after the other. It will build code for each core then erase FLASH and load code onto each core:

    Can you clarify this statement? Did you create your own build configuration?

  • Custom board with TMS320F28379D ZWTS rev C chip. Here's the .ccxml screenshot:

    No modifications to the GEL script that I am aware of.

    What I meant by the debug configuration is I created a debug configuration using this process:

    1) Right-click the CPU1 project > Debug As > Debug Configurations...

    2) Right-click "Code Composer Studio - Device Debugging" > New Configuration

    3) In the debug window next to "Name" put the name of the CPU1 project  > Apply

    Main Tab

    4) Next to "Target Configuration" press "File System..." or "Workspace..."> navigate to the .ccxml file > OK

    5) In the main window select whichever cores I plan to load code onto (in our case just C28xx_CPU1 and C28xx_CPU2, no CLA) > Apply

    Program Tab:

    6) Select CPU1 from the "Device" dropdown

    7) Next to "Project" press "Workspace..." > select the project that contains the source code to be loaded onto CPU1

    8) Repeat the previous two steps for CPU2

    9) Apply and Close


    With the debug configuration setup, this is what I do to load the code onto the cores:

    1) Connect the ARM JTAG to the board via on-board header and to the computer via USB

    2) Power ON the board

    3) Right-click on the CPU1 project > Build Configurations > Set Active > select FLASH build configuration (several linker and compiler settings have been set for this configuration to include driverlib, predefined symbols, FLASH.cmd, etc.). Some files become greyed out and are excluded from build (e.g. RAM .cmd files).

    4) Repeat previous step for CPU2 project

    5) Do a clean build of both CPU1 and CPU2

    6) Select CPU1 project > click the bug icon to build & load code to the board and start a debug session (if the debug configuration is properly configured then it will automatically build CPU1, then build CPU2, then erase and load flash for CPU1, then erase and load flash for CPU2)

    7) Select CPU1 debug probe > press the "Resume" button and the board should now be running the code on CPU1

    8) Repeat previous step for CPU2 debug probe

  • Nigel,

    Thanks for providing the additional details, this is helpful. Re-reading some of your debug findings it would be good to focus on the flash and boot procedure of your code.

    However, the first time I press the debug button and FLASH code onto CPU1 and CPU2 the function pointer value changes before I reach main().
    Here's another wrinkle. If I am already in an active debug session, I can't replicate the issue after the first time I load the code onto both cores in FLASH. If I try a CPU reset/restart, the function pointer goes back to a normal value of 0x00000000. This problem seems to only occur on the first time I start a new debug session and FLASH code onto both cores. I have to stop the current debug session and re-start the debug session and FLASH code again onto both cores in order to see the problem again.

    As you are already likely aware, a lot of different things happen before you reach main() in your code. The workshop material below gives a pretty good overview of you want to find out more. I recommend section on Reset and Interrupts in the workshop manual.

    https://training.ti.com/c2000-f2837xd-microcontroller-workshop?context=1137755-1139641-1137781 

    A couple of debug tips I can offer:

    - What is the address of the function pointer that is getting corrupted? You can try to set a hardware watchpoint to see if you can catch the moment the address for that function pointer is getting written to. The article below describes how to setup hardware watchpoints. 

    https://software-dl.ti.com/ccs/esd/documents/ccs_breakpoint_watchpoint_c2000.html 

    - Have you reviewed the command files for CPU1 and CPU2 to make sure they are not interfering with each other?

    - What are the boot mode options you are using for CPU1 and CPU2?

  • What is the address of the function pointer that is getting corrupted?

    From the screenshot above the function pointer address is 0x0000C654.

    You can try to set a hardware watchpoint to see if you can catch the moment the address for that function pointer is getting written to.

    I've attempted to set a hardware watchpoint for 0x0000C654 (write) with auto run to main() disabled, but the only time it gets triggered is when cinit clears the value to zero as it should, and the rest of the code operates normally. When I attempt to use the watchpoint with auto run to main() enabled, same thing, everything is normal. It seems I can't physically observe it, something else it happening when I auto run to main() without a watchpoint in emulator/debug mode flashing code the first time.

    Have you reviewed the command files for CPU1 and CPU2 to make sure they are not interfering with each other?

    Yes, no conflicts as far as I am aware of, these were pulled from the latest C2000Ware_3_04_00_00 and modified to be used with our project. I can't seem to upload the .cmd files as an attachment so I've pasted the code here:

    // 2837xD_FLASH_lnk_cpu1.cmd
    MEMORY
    {
    PAGE 0 :  /* Program Memory */
              /* Memory (RAM/FLASH) blocks can be moved to PAGE1 for data allocation */
              /* BEGIN is used for the "boot to Flash" bootloader mode   */
    
       BEGIN           	: origin = 0x080000, length = 0x000002
       RAMM0           	: origin = 0x000123, length = 0x0002DD
       RAMD0           	: origin = 0x00B000, length = 0x000800
    
       // For .TI.ramfunc (see note below)
       RAMLS0_1         : origin = 0x008000, length = 0x001000
    //   RAMLS0          	: origin = 0x008000, length = 0x000800
    //   RAMLS1          	: origin = 0x008800, length = 0x000800
    
       RAMLS2      		: origin = 0x009000, length = 0x000800
       RAMLS3      		: origin = 0x009800, length = 0x000800
       RAMLS4      		: origin = 0x00A000, length = 0x000800
    //   RAMGS14          : origin = 0x01A000, length = 0x001000 // RESERVED FOR CPU2     /* Only Available on F28379D, F28377D, F28375D devices. Remove line on other devices. */
    //   RAMGS15          : origin = 0x01B000, length = 0x000FF8 // RESERVED FOR CPU2     /* Only Available on F28379D, F28377D, F28375D devices. Remove line on other devices. */
    
    //   RAMGS15_RSVD     : origin = 0x01BFF8, length = 0x000008    /* Reserve and do not use for code as per the errata advisory "Memory: Prefetching Beyond Valid Memory" */
    
       RESET           	: origin = 0x3FFFC0, length = 0x000002
    
       /* Flash sectors */
       FLASHA           : origin = 0x080002, length = 0x001FFE	/* on-chip Flash */
       FLASHB           : origin = 0x082000, length = 0x002000	/* on-chip Flash */
       FLASHC           : origin = 0x084000, length = 0x002000	/* on-chip Flash */
       FLASHD           : origin = 0x086000, length = 0x002000	/* on-chip Flash */
       FLASHE           : origin = 0x088000, length = 0x008000	/* on-chip Flash */
       FLASHF           : origin = 0x090000, length = 0x008000	/* on-chip Flash */
       FLASHG           : origin = 0x098000, length = 0x008000	/* on-chip Flash */
       FLASHH           : origin = 0x0A0000, length = 0x008000	/* on-chip Flash */
       FLASHI           : origin = 0x0A8000, length = 0x008000	/* on-chip Flash */
       FLASHJ           : origin = 0x0B0000, length = 0x008000	/* on-chip Flash */
       FLASHK           : origin = 0x0B8000, length = 0x002000	/* on-chip Flash */
       FLASHL           : origin = 0x0BA000, length = 0x002000	/* on-chip Flash */
       FLASHM           : origin = 0x0BC000, length = 0x002000	/* on-chip Flash */
       FLASHN           : origin = 0x0BE000, length = 0x001FF0	/* on-chip Flash */
    
    //   FLASHN_RSVD     : origin = 0x0BFFF0, length = 0x000010    /* Reserve and do not use for code as per the errata advisory "Memory: Prefetching Beyond Valid Memory" */
    
    PAGE 1 : /* Data Memory */
             /* Memory (RAM/FLASH) blocks can be moved to PAGE0 for program allocation */
    
       BOOT_RSVD       : origin = 0x000002, length = 0x000121     /* Part of M0, BOOT rom will use this for stack */
       RAMM1           : origin = 0x000400, length = 0x0003F8     /* on-chip RAM block M1 */
    //   RAMM1_RSVD      : origin = 0x0007F8, length = 0x000008     /* Reserve and do not use for code as per the errata advisory "Memory: Prefetching Beyond Valid Memory" */
       RAMD1           : origin = 0x00B800, length = 0x000800
    
       RAMLS5      : origin = 0x00A800, length = 0x000800
    
       RAMGS0      : origin = 0x00C000, length = 0x001000
       RAMGS1      : origin = 0x00D000, length = 0x001000
       RAMGS2      : origin = 0x00E000, length = 0x001000
       RAMGS3      : origin = 0x00F000, length = 0x001000
       RAMGS4      : origin = 0x010000, length = 0x001000
       RAMGS5      : origin = 0x011000, length = 0x001000
       RAMGS6      : origin = 0x012000, length = 0x001000
       RAMGS7      : origin = 0x013000, length = 0x001000
    //   RAMGS8      : origin = 0x014000, length = 0x001000 // RESERVED FOR CPU2
    //   RAMGS9      : origin = 0x015000, length = 0x001000 // RESERVED FOR CPU2
    //   RAMGS10     : origin = 0x016000, length = 0x001000 // RESERVED FOR CPU2
    
    //   RAMGS11     : origin = 0x017000, length = 0x000FF8   /* Uncomment for F28374D, F28376D devices */
    
    //   RAMGS11_RSVD : origin = 0x017FF8, length = 0x000008    /* Reserve and do not use for code as per the errata advisory "Memory: Prefetching Beyond Valid Memory" */
    
    //   RAMGS11     : origin = 0x017000, length = 0x001000 // RESERVED FOR CPU2     /* Only Available on F28379D, F28377D, F28375D devices. Remove line on other devices. */
    //   RAMGS12     : origin = 0x018000, length = 0x001000 // RESERVED FOR CPU2     /* Only Available on F28379D, F28377D, F28375D devices. Remove line on other devices. */
    //   RAMGS13     : origin = 0x019000, length = 0x001000 // RESERVED FOR CPU2     /* Only Available on F28379D, F28377D, F28375D devices. Remove line on other devices. */
    
    /* Only needed for examples:
       CPU2TOCPU1RAM   : origin = 0x03F800, length = 0x000400
       CPU1TOCPU2RAM   : origin = 0x03FC00, length = 0x000400
    */
    }
    
    SECTIONS
    {
       /* Allocate program areas: */
       .cinit              : > FLASHB      PAGE = 0, ALIGN(8)
       .text               : >> FLASHB | FLASHC | FLASHD | FLASHE      PAGE = 0, ALIGN(8)
       codestart           : > BEGIN       PAGE = 0, ALIGN(8)
       /* Allocate uninitalized data sections: */
       .stack              : > RAMD1       PAGE = 1
       .switch             : > FLASHB      PAGE = 0, ALIGN(8)
       .reset              : > RESET,      PAGE = 0, TYPE = DSECT /* not used, */
    
    #if defined(__TI_EABI__)
       .init_array         : > FLASHB,       PAGE = 0,       ALIGN(8)
       .bss                : > RAMLS5,       PAGE = 1
       .bss:output         : > RAMLS3,       PAGE = 0
       .bss:cio            : > RAMLS5,       PAGE = 1
       .data               : > RAMLS5,       PAGE = 1
       .sysmem             : > RAMLS5,       PAGE = 1
       /* Initalized sections go in Flash */
       .const              : > FLASHF,       PAGE = 0,       ALIGN(8)
    #else
       .pinit              : > FLASHB,       PAGE = 0,       ALIGN(8)
       .ebss               : >> RAMLS5 | RAMGS0 | RAMGS1,    PAGE = 1
       .esysmem            : > RAMLS5,       PAGE = 1
       .cio                : > RAMLS5,       PAGE = 1
       /* Initalized sections go in Flash */
       .econst             : >> FLASHF      PAGE = 0, ALIGN(8)
    #endif
    
    /* Only needed for SDFM module:
    
       Filter_RegsFile     : > RAMGS0,	   PAGE = 1
    
       Only needed for examples:
    
       SHARERAMGS0		: > RAMGS0,		PAGE = 1
       SHARERAMGS1		: > RAMGS1,		PAGE = 1
       ramgs0           : > RAMGS0,     PAGE = 1
       ramgs1           : > RAMGS1,     PAGE = 1
    */
    
    // NOTE: if you have trouble fitting .TI.ramfunc in RAMLS0, see this forum post:
    // https://e2e.ti.com/support/microcontrollers/c2000/f/171/t/691117
    #ifdef __TI_COMPILER_VERSION__
        #if __TI_COMPILER_VERSION__ >= 15009000
            #if defined(__TI_EABI__)
                .TI.ramfunc : {} LOAD = FLASHD,
                                     RUN = RAMLS0_1,
                                     LOAD_START(RamfuncsLoadStart),
                                     LOAD_SIZE(RamfuncsLoadSize),
                                     LOAD_END(RamfuncsLoadEnd),
                                     RUN_START(RamfuncsRunStart),
                                     RUN_SIZE(RamfuncsRunSize),
                                     RUN_END(RamfuncsRunEnd),
                                     PAGE = 0, ALIGN(8)
            #else
                .TI.ramfunc : {} LOAD = FLASHD,
                                 RUN = RAMLS0_1,
                                 LOAD_START(_RamfuncsLoadStart),
                                 LOAD_SIZE(_RamfuncsLoadSize),
                                 LOAD_END(_RamfuncsLoadEnd),
                                 RUN_START(_RamfuncsRunStart),
                                 RUN_SIZE(_RamfuncsRunSize),
                                 RUN_END(_RamfuncsRunEnd),
                                 PAGE = 0, ALIGN(8)
            #endif
        #else
       ramfuncs            : LOAD = FLASHD,
                             RUN = RAMLS0_1,
                             LOAD_START(_RamfuncsLoadStart),
                             LOAD_SIZE(_RamfuncsLoadSize),
                             LOAD_END(_RamfuncsLoadEnd),
                             RUN_START(_RamfuncsRunStart),
                             RUN_SIZE(_RamfuncsRunSize),
                             RUN_END(_RamfuncsRunEnd),
                             PAGE = 0, ALIGN(8)
        #endif
    
    #endif
    
    /* The following section definitions are required when using the IPC API Drivers
    
        GROUP : > CPU1TOCPU2RAM, PAGE = 1
        {
            PUTBUFFER
            PUTWRITEIDX
            GETREADIDX
        }
    
        GROUP : > CPU2TOCPU1RAM, PAGE = 1
        {
            GETBUFFER :    TYPE = DSECT
            GETWRITEIDX :  TYPE = DSECT
            PUTREADIDX :   TYPE = DSECT
        }
    */
    
    }
    
    /*
    //===========================================================================
    // End of file.
    //===========================================================================
    */

    // 2837xD_FLASH_lnk_cpu2.cmd
    
    MEMORY
    {
    PAGE 0 :
       /* BEGIN is used for the "boot to SARAM" bootloader mode   */
    
       BEGIN           	: origin = 0x080000, length = 0x000002
       RAMM0           	: origin = 0x0000A2, length = 0x00035E
       RAMD0           	: origin = 0x00B000, length = 0x000800
       RAMLS0          	: origin = 0x008000, length = 0x000800
       RAMLS1          	: origin = 0x008800, length = 0x000800
       RAMLS2      		: origin = 0x009000, length = 0x000800
       RAMLS3      		: origin = 0x009800, length = 0x000800
       RAMLS4      		: origin = 0x00A000, length = 0x000800
       RAMGS14          : origin = 0x01A000, length = 0x001000     /* Only Available on F28379D, F28377D, F28375D devices. Remove line on other devices. */
       RAMGS15          : origin = 0x01B000, length = 0x000FF8     /* Only Available on F28379D, F28377D, F28375D devices. Remove line on other devices. */
    
    //   RAMGS15_RSVD     : origin = 0x01BFF8, length = 0x000008    /* Reserve and do not use for code as per the errata advisory "Memory: Prefetching Beyond Valid Memory" */
    
       RESET       		: origin = 0x3FFFC0, length = 0x000002
    
       /* Flash sectors */
       FLASHA           : origin = 0x080002, length = 0x001FFE	/* on-chip Flash */
       FLASHB           : origin = 0x082000, length = 0x002000	/* on-chip Flash */
       FLASHC           : origin = 0x084000, length = 0x002000	/* on-chip Flash */
       FLASHD           : origin = 0x086000, length = 0x002000	/* on-chip Flash */
       FLASHE           : origin = 0x088000, length = 0x008000	/* on-chip Flash */
       FLASHF           : origin = 0x090000, length = 0x008000	/* on-chip Flash */
       FLASHG           : origin = 0x098000, length = 0x008000	/* on-chip Flash */
       FLASHH           : origin = 0x0A0000, length = 0x008000	/* on-chip Flash */
       FLASHI           : origin = 0x0A8000, length = 0x008000	/* on-chip Flash */
       FLASHJ           : origin = 0x0B0000, length = 0x008000	/* on-chip Flash */
       FLASHK           : origin = 0x0B8000, length = 0x002000	/* on-chip Flash */
       FLASHL           : origin = 0x0BA000, length = 0x002000	/* on-chip Flash */
       FLASHM           : origin = 0x0BC000, length = 0x002000	/* on-chip Flash */
       FLASHN           : origin = 0x0BE000, length = 0x001FF0	/* on-chip Flash */
    
    //   FLASHN_RSVD     : origin = 0x0BFFF0, length = 0x000010    /* Reserve and do not use for code as per the errata advisory "Memory: Prefetching Beyond Valid Memory" */
    
    PAGE 1 :
    
       BOOT_RSVD       : origin = 0x000002, length = 0x0000A0     /* Part of M0, BOOT rom will use this for stack */
       RAMM1           : origin = 0x000400, length = 0x0003F8     /* on-chip RAM block M1 */
    //   RAMM1_RSVD      : origin = 0x0007F8, length = 0x000008     /* Reserve and do not use for code as per the errata advisory "Memory: Prefetching Beyond Valid Memory" */
       RAMD1           : origin = 0x00B800, length = 0x000800
    
       RAMLS5          : origin = 0x00A800, length = 0x000800
    
       RAMGS8          : origin = 0x014000, length = 0x001000
       RAMGS9          : origin = 0x015000, length = 0x001000
       RAMGS10         : origin = 0x016000, length = 0x001000
       RAMGS11         : origin = 0x017000, length = 0x001000     /* Only Available on F28379D, F28377D, F28375D devices. Remove line on other devices. */
       RAMGS12         : origin = 0x018000, length = 0x001000     /* Only Available on F28379D, F28377D, F28375D devices. Remove line on other devices. */
       RAMGS13         : origin = 0x019000, length = 0x001000     /* Only Available on F28379D, F28377D, F28375D devices. Remove line on other devices. */
    
    /* Only needed for examples:
       CPU2TOCPU1RAM   : origin = 0x03F800, length = 0x000400
       CPU1TOCPU2RAM   : origin = 0x03FC00, length = 0x000400
    */
    }
    
    //
    // NOTE: avoid using global shared RAM (RAMGSx) for CPU2 sections, instead
    // use local memory (M0/M1/D0/D1 or LSx RAMs), as noted by Vivek Singh:
    // https://e2e.ti.com/support/microcontrollers/c2000/f/171/p/493493/1791385
    //
    SECTIONS
    {
       /* Allocate program areas: */
       .cinit              : > FLASHB      PAGE = 0, ALIGN(8)
       .text               : >> FLASHA | FLASHB | FLASHC | FLASHD      PAGE = 0, ALIGN(8)
       codestart           : > BEGIN       PAGE = 0, ALIGN(8)
    
       /* Allocate uninitalized data sections: */
       .stack              : > RAMD1        PAGE = 1
    
       /* Initalized sections go in Flash */
       .switch             : > FLASHB      PAGE = 0, ALIGN(8)
       .reset           : > RESET,     PAGE = 0, TYPE = DSECT /* not used, */
       
    #if defined(__TI_EABI__)
       .init_array         : > FLASHB,       PAGE = 0,       ALIGN(8)
       .bss                : > RAMLS5,       PAGE = 1
       .bss:output         : > RAMLS3,       PAGE = 0
       .bss:cio            : > RAMLS5,       PAGE = 1
       .data               : > RAMLS5,       PAGE = 1
       .sysmem             : > RAMLS5,       PAGE = 1
       /* Initalized sections go in Flash */
       .const              : > FLASHF,       PAGE = 0,       ALIGN(8)
    #else
       .pinit              : > FLASHB,       PAGE = 0,       ALIGN(8)
       .ebss               : >> RAMLS1 | RAMLS2 | RAMLS3,      PAGE = 0
       .esysmem            : > RAMLS5,       PAGE = 1
       .cio                : > RAMLS5,       PAGE = 1
       /* Initalized sections go in Flash */
       .econst             : >> FLASHF       PAGE = 0, ALIGN(8)
    #endif
    
    // Only needed for examples:
    
    //   SHARERAMGS0		: > RAMGS0,		PAGE = 1
    //   SHARERAMGS1		: > RAMGS1,		PAGE = 1
    
    // NOTE: if you have trouble fitting .TI.ramfunc in RAMLS0, see this forum post:
    // https://e2e.ti.com/support/microcontrollers/c2000/f/171/t/691117
    #ifdef __TI_COMPILER_VERSION__
        #if __TI_COMPILER_VERSION__ >= 15009000
            #if defined(__TI_EABI__)
                .TI.ramfunc : {} LOAD = FLASHE,
                                     RUN = RAMLS0,
                                     LOAD_START(RamfuncsLoadStart),
                                     LOAD_SIZE(RamfuncsLoadSize),
                                     LOAD_END(RamfuncsLoadEnd),
                                     RUN_START(RamfuncsRunStart),
                                     RUN_SIZE(RamfuncsRunSize),
                                     RUN_END(RamfuncsRunEnd),
                                     PAGE = 0, ALIGN(8)
            #else
                .TI.ramfunc : {} LOAD = FLASHE,
                                 RUN = RAMLS0,
                                 LOAD_START(_RamfuncsLoadStart),
                                 LOAD_SIZE(_RamfuncsLoadSize),
                                 LOAD_END(_RamfuncsLoadEnd),
                                 RUN_START(_RamfuncsRunStart),
                                 RUN_SIZE(_RamfuncsRunSize),
                                 RUN_END(_RamfuncsRunEnd),
                                 PAGE = 0, ALIGN(8)
            #endif
        #else
       ramfuncs            : LOAD = FLASHE,
                             RUN = RAMLS0,
                             LOAD_START(_RamfuncsLoadStart),
                             LOAD_SIZE(_RamfuncsLoadSize),
                             LOAD_END(_RamfuncsLoadEnd),
                             RUN_START(_RamfuncsRunStart),
                             RUN_SIZE(_RamfuncsRunSize),
                             RUN_END(_RamfuncsRunEnd),
                             PAGE = 0, ALIGN(8)
        #endif
    #endif
    
    /* The following section definitions are required when using the IPC API Drivers
        GROUP : > CPU2TOCPU1RAM, PAGE = 1
        {
            PUTBUFFER
            PUTWRITEIDX
            GETREADIDX
        }
    
        GROUP : > CPU1TOCPU2RAM, PAGE = 1
        {
            GETBUFFER :    TYPE = DSECT
            GETWRITEIDX :  TYPE = DSECT
            PUTREADIDX :   TYPE = DSECT
        }
    */
    }
    
    /*
    //===========================================================================
    // End of file.
    //===========================================================================
    */
    

    What are the boot mode options you are using for CPU1 and CPU2?

    Good point, we actually have an existing issue where the boot pins are floating, but in the next circuit card revision we will have them pulled up to get boot to FLASH boot mode at all times rather than some unknown state. We've encountered issues with it in the past, perhaps the floating boot mode pins might cause some unexpected behavior with memory regions being overwritten.

  • Nigel,

    That's really odd that you can only replicate the issue when watchpoint is disabled and auto run is enabled. I'll see if I can get our CCS team to comment on this difference in behavior. 

    Have you tried moving the section that contains your function pointer to another memory location? Just to see if the problem persists?

    Regarding the boot mode, note that there are a couple of GEL helper functions which help you override the pin boot mode selection during debug. See the "EMU Boot Mode Select" functions in the f28377d_cpuX.gel file. These GEL files should already be loaded as part of your target config. 

    7.9.5. Adding GEL Files to a Target Configuration — Code Composer Studio 9.1.0 documentation

    Location of gel files:

    <ccs_install>\ccs\ccs_base\emulation\gel

    To access the GEL file in CCS use: Tools -> GEL Files

  • That's really odd that you can only replicate the issue when watchpoint is disabled and auto run is enabled. I'll see if I can get our CCS team to comment on this difference in behavior. 

    That is indeed odd. All the auto-run feature does is after the program is loaded (or restarted), a breakpoint is set at the beginning of main (or whatever label that is specified) and then the target is run. When the program hits the breakpoint at main, the target is halted and the breakpoint is automatically removed. This is similar to the "Run to Line" behavior. I'm not sure how it could be messing with the function pointer.

    Nigel - If you disable the auto-start but then manually replicate what it does (restart, set a breakpoint at beginning of main, then run the target), are you still able to replicate the issue? 

  • Hi Nigel,

    I don't think this is issue with CCS break point or watchpoint. In my opinion what is happening in this case is the pointer is getting overwritten by flash programming tool which uses GSx RAM to load the FLASH API code/data to program the flash. When you have autorun enable, after loading code in one of the core, CPU will start running while code will get loaded on other core which create a race condition and can cause such issues. So you should avoid doing this. You should load code into Ist core and then load code into 2nd core. If you want to try the way you are doing right now, then it's better to disable the autorun option.

    Regards,

    Vivek Singh

  • Nigel - If you disable the auto-start but then manually replicate what it does (restart, set a breakpoint at beginning of main, then run the target), are you still able to replicate the issue? 

    Unfortunately not. Vivek's conclusion seems reasonable enough. I guess we will have to not use the auto run option. This would be a good bug to fix in the flash programming tool so multi-core programming doesn't encounter these race conditions.