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.

MSP432 Maincode debugging with a Bootloader loaded

Hey Group,

To give a bit of a background to the problem, I have setup two projects, one as a bootloader and the other as the main code.

I am able to load the bootloader with the XDS200 debugger via CCS and have it jump to the right start point in main.

I am also able to load on the main code afterwards with the debugger and have it also jump to main, the jump is successful from Bootloader to Main code.

Now, in the instance where I have a change to main and wish to reload it, the debugger will load the firmware and complete successfully, but then proceed to constantly reset in the debug interface, as seen in the image below, switching between the two states and never returning.


I am erasing the main memory when downloading the bootloader, but only erasing and downloading when applying the Main code, these are set individually in either Project Properties->Debug->MSP432 Settings-> Erase Configurations

Can anyone see what is going wrong here? Obviously it is time consuming and troublesome to reload the bootloader every time I make a change to the main code.

  • Hi,

    It sounds like a linker file issue between the two projects. Ideally, the linker file for each project has allocated separate areas in the memory. Then, for the Erase Configurations in CCS, "Erase and download necessary segments only" should be selected, which should prevent the bootloader memory from being overwritten after changes were made to the main memory.

    Can you share the linker files and screenshots of your Erase Configuration settings for both projects?

    Regards,

    James

    MSP Customer Applications
  • Hey James,

    Attached are the linker files for both the bootloader and main code respectively.

    Bootloader:

    MEMORY
    {
        BOOT       (RX) : origin = 0x00000000, length = 0x00007FB0
        BOOTCRC    (RX) : origin = 0x00007FB0, length = 0x00000050
        MAIN       (RX) : origin = 0x00008000, length = 0x00037F80
        MAINCRC    (RX) : origin = 0x0003FF80, length = 0x00000050
        INFO       (RX) : origin = 0x00200000, length = 0x00004000
    #ifdef  __TI_COMPILER_VERSION__
    #if     __TI_COMPILER_VERSION__ >= 15009000
        ALIAS
        {
        SRAM_CODE  (RWX): origin = 0x01000000
        SRAM_DATA  (RW) : origin = 0x20000000
        } length = 0x00010000
    #else
        /* Hint: If the user wants to use ram functions, please observe that SRAM_CODE             */
        /* and SRAM_DATA memory areas are overlapping. You need to take measures to separate       */
        /* data from code in RAM. This is only valid for Compiler version earlier than 15.09.0.STS.*/ 
        SRAM_CODE  (RWX): origin = 0x01000000, length = 0x00010000
        SRAM_DATA  (RW) : origin = 0x20000000, length = 0x00010000
    #endif
    #endif
    }
    
    /* The following command line options are set as part of the CCS project.    */
    /* If you are building using the command line, or for some reason want to    */
    /* define them here, you can uncomment and modify these lines as needed.     */
    /* If you are using CCS for building, it is probably better to make any such */
    /* modifications in your CCS project and leave this file alone.              */
    /*                                                                           */
    /* A heap size of 1024 bytes is recommended when you plan to use printf()    */
    /* for debug output to the console window.                                   */
    /*                                                                           */
    /* --heap_size=1024                                                          */
    /* --stack_size=512                                                          */
    /* --library=rtsv7M4_T_le_eabi.lib                                           */
    
    /* Section allocation in memory */
    
    SECTIONS
    {
        .intvecs:   > 0x00000000
            crc_table(boot_crc, algorithm=CRC32_C)
        .text   :   > BOOT
            crc_table(boot_crc, algorithm=CRC32_C)
        .const  :   > BOOT
            crc_table(boot_crc, algorithm=CRC32_C)
        .cinit  :   > BOOT
        .pinit  :   > BOOT
        .init_array   :     > BOOT
        .binit        : {}  > BOOT
    
        .flashMailbox : > 0x00200000
    
        .vtable :   > 0x20000000
        .data   :   > SRAM_DATA
        .bss    :   > SRAM_DATA
        .sysmem :   > SRAM_DATA
        .stack  :   > SRAM_DATA (HIGH)
        .TI.crctab : > BOOTCRC
    
    #ifdef  __TI_COMPILER_VERSION__
    #if     __TI_COMPILER_VERSION__ >= 15009000
        .TI.ramfunc : {} load=BOOT, run=SRAM_CODE, table(BINIT)
    #endif
    #endif

    Maincode

    MEMORY
    {
        BOOT       (RX) : origin = 0x00000000, length = 0x00007F80
        BOOTCRC    (RX) : origin = 0x00007F80, length = 0x00000080
        MAIN       (RX) : origin = 0x00008000, length = 0x00037F80
        MAINCRC    (RX) : origin = 0x0003FF80, length = 0x00000080
        INFO       (RX) : origin = 0x00200000, length = 0x00004000
    #ifdef  __TI_COMPILER_VERSION__
    #if     __TI_COMPILER_VERSION__ >= 15009000
        ALIAS
        {
        SRAM_CODE  (RWX): origin = 0x01000000
        SRAM_DATA  (RW) : origin = 0x20000000
        } length = 0x00010000
    #else
        /* Hint: If the user wants to use ram functions, please observe that SRAM_CODE             */
        /* and SRAM_DATA memory areas are overlapping. You need to take measures to separate       */
        /* data from code in RAM. This is only valid for Compiler version earlier than 15.09.0.STS.*/
        SRAM_CODE  (RWX): origin = 0x01000000, length = 0x00010000
        SRAM_DATA  (RW) : origin = 0x20000000, length = 0x00010000
    #endif
    #endif
    }
    
    /* The following command line options are set as part of the CCS project.    */
    /* If you are building using the command line, or for some reason want to    */
    /* define them here, you can uncomment and modify these lines as needed.     */
    /* If you are using CCS for building, it is probably better to make any such */
    /* modifications in your CCS project and leave this file alone.              */
    /*                                                                           */
    /* A heap size of 1024 bytes is recommended when you plan to use printf()    */
    /* for debug output to the console window.                                   */
    /*                                                                           */
    /* --heap_size=1024                                                          */
    /* --stack_size=512                                                          */
    /* --library=rtsv7M4_T_le_eabi.lib                                           */
    
    /* Section allocation in memory */
    
    SECTIONS
    {
        .intvecs  :   > 0x00008000
            crc_table(main_crc, algorithm=CRC32_C)
        .text  :   > MAIN
            crc_table(main_crc, algorithm=CRC32_C)
        .const  :   > MAIN
            crc_table(main_crc, algorithm=CRC32_C)
        .cinit  :   > MAIN
        .pinit  :   > MAIN
    
        .init_array   :     > MAIN
        .binit        : {}  > MAIN
    
        .flashMailbox : > 0x00200000
    
        .vtable :   > 0x20000000
        .data   :   > SRAM_DATA
        .bss    :   > SRAM_DATA
        .sysmem :   > SRAM_DATA
        .stack  :   > SRAM_DATA (HIGH)
        .TI.crctab : > MAINCRC
    
    #ifdef  __TI_COMPILER_VERSION__
    #if     __TI_COMPILER_VERSION__ >= 15009000
        .TI.ramfunc : {} load=MAIN, run=SRAM_CODE, table(BINIT)
    #endif
    #endif

    Bootloader Erase Configuration

    Main Code Erase Configuration

  • Thanks for sharing these. Could you try making the memory locations independent for each project (as shown below)?

    Bootloader Project Linker File

    MEMORY
    {
        BOOT       (RX) : origin = 0x00000000, length = 0x00007FB0
        BOOTCRC    (RX) : origin = 0x00007FB0, length = 0x00000050
        INFO       (RX) : origin = 0x00200000, length = 0x00004000
    #ifdef  __TI_COMPILER_VERSION__
    #if     __TI_COMPILER_VERSION__ >= 15009000
        ALIAS
        {
        SRAM_CODE  (RWX): origin = 0x01000000
        SRAM_DATA  (RW) : origin = 0x20000000
        } length = 0x00010000
    #else
        /* Hint: If the user wants to use ram functions, please observe that SRAM_CODE             */
        /* and SRAM_DATA memory areas are overlapping. You need to take measures to separate       */
        /* data from code in RAM. This is only valid for Compiler version earlier than 15.09.0.STS.*/ 
        SRAM_CODE  (RWX): origin = 0x01000000, length = 0x00010000
        SRAM_DATA  (RW) : origin = 0x20000000, length = 0x00010000
    #endif
    #endif
    }

    Main Project Linker File

    MEMORY
    {
        MAIN       (RX) : origin = 0x00008000, length = 0x00037F80
        MAINCRC    (RX) : origin = 0x0003FF80, length = 0x00000080
        INFO       (RX) : origin = 0x00200000, length = 0x00004000
    #ifdef  __TI_COMPILER_VERSION__
    #if     __TI_COMPILER_VERSION__ >= 15009000
        ALIAS
        {
        SRAM_CODE  (RWX): origin = 0x01000000
        SRAM_DATA  (RW) : origin = 0x20000000
        } length = 0x00010000
    #else
        /* Hint: If the user wants to use ram functions, please observe that SRAM_CODE             */
        /* and SRAM_DATA memory areas are overlapping. You need to take measures to separate       */
        /* data from code in RAM. This is only valid for Compiler version earlier than 15.09.0.STS.*/
        SRAM_CODE  (RWX): origin = 0x01000000, length = 0x00010000
        SRAM_DATA  (RW) : origin = 0x20000000, length = 0x00010000
    #endif
    #endif
    }

    Also, could you change your Erase Configuration to "Erase and download necessary segments only" for both projects? Please let me know if this resolves the issue. If not, we'll dig deeper.

    You may be able to compare the binaries for each project and see if there is some memory overlap occurring.

    Regards,

    James

    MSP Customer Applications

     

  • This thread has some related discussion that you may find helpful.

    Regards,

    James

    MSP Customer Applications

  • Thanks James for the suggestions, removing the additional linker information for bootloader and maincode unfortunately did not yield any different results however.

    After some further examination of the BIN and the Internal Flash of the MSP432, it appears as if the debugger does not completely erase the correct sectors of internal flash. We can follow the code from the Internal Flash with the BIN, however after a certain point in memory, it then looks like the data was XOR'd and no longer is identical. We tried turning on verbose debugger output, whereby it display it has done an erase, but does not list which sectors, so unfortunately its our best hypothesis at what is happening. 

    Is it possible that when the option "Erase and Download necessary segments only", the debugger only downloads the code that is different to what is currently in the internal flash and therefore does not erase the internal flash before writing?

    Just to be specific, we are also using an XDS200 as our debugger. 

  • Thanks for the detailed feedback. After looking at Section 8.2.4 Flash Erase in the Technical Reference Manual (TRM), I remembered that the smallest amount of flash that can be erased in both Main and Info memory regions is one sector, 4KB. Looking at the length of your address locations, I suspect that this is what's causing the issue. Since Boot and Main regions are next to each other, when the Main code gets changed, portions of the Boot code in that shared sector would get erased.

    Thus, a possible workaround would be to use memory lengths equal to 0x1000h (4KB) multiples. In this scenario, no segments would be shared between Boot and Main regions, which would allow either region to be erased without affecting the other. Try updating your linker files accordingly. Let's keep the sections separate in the linker files for the unique projects, and also keep using the "Erase and download necessary segments only" for both projects.

    Let me know if this works.

    Another alternative would be to put the Boot code in Info memory. This way, you could make sure that changes to your Main code don't affect the Boot code in Info memory by choosing "Erase main memory only" in CCS. However, since the MSP432 only has 16KB Info memory and you need 32KB, this wouldn't work.

    Regards,

    James

    MSP Customer Applications
  • I hear what youre saying James, we initially designed the sectors so that the start of each section would be on a 0x1000h increment, but also assumed it would be a bit more intelligent, in determining which sectors needed to be erased. Regardless, I implemented the changes you suggested and gave each section at least 4KB.


    For the MainCode:

    MEMORY
    {
    MAIN (RX) : origin = 0x0000A000, length = 0x00035000
    MAINCRC (RX) : origin = 0x0003F000, length = 0x00001000
    INFO (RX) : origin = 0x00200000, length = 0x00004000
    #ifdef __TI_COMPILER_VERSION__
    #if __TI_COMPILER_VERSION__ >= 15009000
    ALIAS
    {
    SRAM_CODE (RWX): origin = 0x01000000
    SRAM_DATA (RW) : origin = 0x20000000
    } length = 0x00010000
    #else
    /* Hint: If the user wants to use ram functions, please observe that SRAM_CODE */
    /* and SRAM_DATA memory areas are overlapping. You need to take measures to separate */
    /* data from code in RAM. This is only valid for Compiler version earlier than 15.09.0.STS.*/
    SRAM_CODE (RWX): origin = 0x01000000, length = 0x00010000
    SRAM_DATA (RW) : origin = 0x20000000, length = 0x00010000
    #endif
    #endif
    }

    /* The following command line options are set as part of the CCS project. */
    /* If you are building using the command line, or for some reason want to */
    /* define them here, you can uncomment and modify these lines as needed. */
    /* If you are using CCS for building, it is probably better to make any such */
    /* modifications in your CCS project and leave this file alone. */
    /* */
    /* A heap size of 1024 bytes is recommended when you plan to use printf() */
    /* for debug output to the console window. */
    /* */
    /* --heap_size=1024 */
    /* --stack_size=512 */
    /* --library=rtsv7M4_T_le_eabi.lib */

    /* Section allocation in memory */

    SECTIONS
    {
    .intvecs : > 0x0000A000
    crc_table(main_crc, algorithm=CRC32_C)
    .text : > MAIN
    crc_table(main_crc, algorithm=CRC32_C)
    .const : > MAIN
    crc_table(main_crc, algorithm=CRC32_C)
    .cinit : > MAIN
    .pinit : > MAIN

    .init_array : > MAIN
    .binit : {} > MAIN

    .flashMailbox : > 0x00200000

    .vtable : > 0x20000000
    .data : > SRAM_DATA
    .bss : > SRAM_DATA
    .sysmem : > SRAM_DATA
    .stack : > SRAM_DATA (HIGH)
    .TI.crctab : > MAINCRC

    #ifdef __TI_COMPILER_VERSION__
    #if __TI_COMPILER_VERSION__ >= 15009000
    .TI.ramfunc : {} load=MAIN, run=SRAM_CODE, table(BINIT)
    #endif
    #endif

    For the Bootloader:
    MEMORY
    {
    BOOT (RX) : origin = 0x00000000, length = 0x00008000
    BOOTCRC (RX) : origin = 0x00009000, length = 0x00001000
    INFO (RX) : origin = 0x00200000, length = 0x00004000
    #ifdef __TI_COMPILER_VERSION__
    #if __TI_COMPILER_VERSION__ >= 15009000
    ALIAS
    {
    SRAM_CODE (RWX): origin = 0x01000000
    SRAM_DATA (RW) : origin = 0x20000000
    } length = 0x00010000
    #else
    /* Hint: If the user wants to use ram functions, please observe that SRAM_CODE */
    /* and SRAM_DATA memory areas are overlapping. You need to take measures to separate */
    /* data from code in RAM. This is only valid for Compiler version earlier than 15.09.0.STS.*/
    SRAM_CODE (RWX): origin = 0x01000000, length = 0x00010000
    SRAM_DATA (RW) : origin = 0x20000000, length = 0x00010000
    #endif
    #endif
    }

    /* The following command line options are set as part of the CCS project. */
    /* If you are building using the command line, or for some reason want to */
    /* define them here, you can uncomment and modify these lines as needed. */
    /* If you are using CCS for building, it is probably better to make any such */
    /* modifications in your CCS project and leave this file alone. */
    /* */
    /* A heap size of 1024 bytes is recommended when you plan to use printf() */
    /* for debug output to the console window. */
    /* */
    /* --heap_size=1024 */
    /* --stack_size=512 */
    /* --library=rtsv7M4_T_le_eabi.lib */

    /* Section allocation in memory */

    SECTIONS
    {
    .intvecs: > 0x00000000
    crc_table(boot_crc, algorithm=CRC32_C)
    .text : > BOOT
    crc_table(boot_crc, algorithm=CRC32_C)
    .const : > BOOT
    crc_table(boot_crc, algorithm=CRC32_C)
    .cinit : > BOOT
    .pinit : > BOOT
    .init_array : > BOOT
    .binit : {} > BOOT

    .flashMailbox : > 0x00200000

    .vtable : > 0x20000000
    .data : > SRAM_DATA
    .bss : > SRAM_DATA
    .sysmem : > SRAM_DATA
    .stack : > SRAM_DATA (HIGH)
    .TI.crctab : > BOOTCRC

    #ifdef __TI_COMPILER_VERSION__
    #if __TI_COMPILER_VERSION__ >= 15009000
    .TI.ramfunc : {} load=BOOT, run=SRAM_CODE, table(BINIT)
    #endif
    #endif
    }
    Unfortunately the micro is still resetting. And once again looking at the BINs of both onboard Flash and the BIN, there are differences, again, as if the sectors were not erased.

    Attached is a small project, which demonstrates the fault we are having, whereby the sectors are not being erased correctly and the data is being written over the top.

    TestFlashErase.zip

  • Thanks for trying my recommendations and for providing the project.

    For my setup, I'm using CCS v6.1.3 and the red MSP432 Rev2.0 LaunchPad (with on-board debugger, which shouldn't matter). After importing and debugging the code from your project, I noticed that the large "largeArray_u64_arr" array was getting stored in RAM, not flash. When I added "0x55555555" to the front of the array, the RAM changed accordingly, and I was able to execute the printf() function both times.

    Now, I made some changes to your project and also created another project to simulate your Bootloader project. Here is a summary of those changes:

    • Main Code project (TestFlashErase project)
      • Added "const" qualifier to the declaration of the array (verified that array was placed in flash, not RAM)
      • Added the following line of code before the declaration of the array to specify its location in flash
        /*******************************************/
        /*                  Defines                */
        /*******************************************/
        
        /*******************************************/
        /*                 Globals                 */
        /*******************************************/
        #pragma LOCATION(largeArray_u64_arr, 0x2000)
        const uint32_t largeArray_u64_arr[] =
      • Modified the linker file to specify that MAIN memory started at 0x00000000 with length 0x00014000.
      • For the debug settings, I chose "Erase main memory only" for the Erase Method, and no other settings were changed.
      • Verified that the array started at 0x2000 in flash (see screenshot below).

    • Bootloader Code project (tempProject project)
      • Based on Blink LED code example (no changes to C file)
      • Modified the linker file to change default MAIN to BOOT memory started at 0x00014000 with length 0x00004000. NOTE that I also changed .intvecs to 0x00014000 in SECTIONS.
      • For the debug settings, I chose "Erase and download necessary segments only" for the Erase Method and also unchecked "On a program load or restart" option under "Auto Run Options".
      • As shown below, the array in MAIN memory hasn't changed after programming the BOOT section to flash.

    In my implementation, I flashed main code first, then bootloader code. For yours, it sounds like you want to program the bootloader code first, then make changes to the main code sections. You would just reverse my projects to accomplish this, but hopefully it demonstrates that it can be done.

    I've attached both projects, so please give them a try and let me know what you see. This should hopefully resolve your issue. I changed both projects to output a TI TXT file to easily review and compare the binary with the flash memory. I'd recommend you continue aligning the code sections in the linker files to 4KB (multiples of 0x1000h) as discussed earlier. Please let me know if you have any questions.

    3806.TestFlashErase.zip

    tempProject.zip

    Regards,

    James

    MSP Customer Applications

  • Did the recommendations above solve the issue?

    Regards,

    James

    MSP Customer Applications
  • I was actually running CCS 6.1.2 with the build I was working on. 

    Installed 6.1.3 and we're in business. 

    It appears the debugger is now correctly erasing all the sectors as required (6.1.2 was only performing a single sector erase). It is now working as we would have hoped, and can leave our bootloader un-altered on the target and just rebuild and debug the main code, with erase only necessary sectors selected. 

    I just wanted to complete some testing on this topic before prematurely announcing it had worked :) 

  • Excellent! I'm happy to hear that it worked for you. I'll go ahead and close the thread.

    Regards,

    James

    MSP Customer Applications

**Attention** This is a public forum