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.

CSM (Code Security Mode) problem

Other Parts Discussed in Thread: TMS320F28035

Hello,

I'm trying to protect my program using the CSM feature from TMS320F28035 MCU.

After program the flash memory using the on chip flash programmer I change the code security password and program the password.

Finally I lock the code security password.

Up to this point, all is ok but the problem is that my program isn't working and I can't reconnect with the target.

When I try to connect I get this error:

=======================================================

Error connecting to the target:
Error 0x80002280/-1250
Fatal Error during: Target Communication, OCS, Control,
Device driver: Lost USB connection to emulator.
You should ABORT and restart to re-establish the USB link.


I/O Port = 510

Board Name: F28035
Cpu Name: TMS320F2800_0

=======================================================

Could someone tell me why I can't connect with the MCU again?

  • Please change the boot mode to "wait", power off/on, and try to connect again. 

    If you are not in 'wait' mode then the code will begin executing and will cut the JTAG connection because you are accessing secure memory.

  • Hi Lori,

    Thank you for your post.

    I changed the boot mode to "wait" and worked (I succeed to connect to device).

    But I'm still with problem, that two boards that I programmed the CSM still aren't working... even if I unlock the CSM.

    I don't have any idea what can I do.

    How can I solve this?

  • Marcio said:
    But I'm still with problem, that two boards that I programmed the CSM still aren't working... even if I unlock the CSM.

    Can you provide more details on exactly how they are not working?

  • Hi lori,

    I have two functions that don't run, and both use interrupt, one is xint1 and
    other is adc (both run in RAM).

    I'm suspecting that is lacking something about interrupt configuration or to run these functions in RAM.

    When I unlock the CSM and enable to boot to flash (not wait mode) it work fine.

  • Hi Lori,

    Could you tell me if this is what is happening?

    I cut this from http://processors.wiki.ti.com/index.php/Code_Security_Module_FAQ_for_C2000

    Q: Code is running outside of the CSM protected area, and the CSM is locked. Can it branch to code within the CSM protected memory?

    No, you can branch into the secured memory and begin execution without any additional setup. Note: this is different then trying to read values out of the flash through data or program space - this will be blocked. For example, code running in M0 SRAM (unsecure) can branch to code within the Flash even if the CSM is locked. Code running out of M0 SRAM will not be able to read any value out of Flash if the CSM is locked.
  • Marcio,

    If the problem exists even if the CSM is unlocked, then I would focus on whether the flash project is setup correctly.  Did everything work from flash even before the CSM was programmed?

    Here are some tips for running code standalone vs from a debugger:

    http://processors.wiki.ti.com/index.php/C2000_Flash_Common_Issues/FAQs#Running_Code_Standalone

    -Lori

  • Lori,

    the program works fine in standalone (without debugger, turning off/on the board)...

    my doubt is if have some problem in program that run from RAM, it's because some routines aren't running from RAM.

    With the CSM disabled all software works fine. The problem is only when I enable the CSM, I could see that some routines aren't running, these routines are interrup like ADC an XINT.

  • Marcio said:

    Lori,

    the program works fine in standalone (without debugger, turning off/on the board)...

    my doubt is if have some problem in program that run from RAM, it's because some routines aren't running from RAM.

    With the CSM disabled all software works fine. The problem is only when I enable the CSM, I could see that some routines aren't running, these routines are interrup like ADC an XINT.

    Code can jump freely from secure to non-secure memory.  But what can not happen is code running from unsecure can not access data that is within secure memory.  Do you by chance have some code that is in non-secure memory trying to access data which is in secure memory?

    On the 28035 you can disable the ECSL (which is what keeps you from stepping through code when the password is protected) by using half of the password.  This would allow you to see if you get into the interrupt and step through the code (you wont' be able to see the code, but you can see the effect on registers).  This may give you a clue as to where things are going wrong.

    from www.ti.com/lit/SPRUGL8

    To allow emulation of secure code, while maintaining the CSM protection against secure memory reads, you must
    write the correct value into the lower 64 bits of the KEY register, which matches the value stored in the
    lower 64 bits of the password locations within the flash. Note that dummy reads of all 128 bits of the
    password in the flash must still be performed. If the lower 64 bits of the password locations are all ones
    (unprogrammed), then the KEY value does not need to match.

  • Hi Lori,

    Lori Heustess said:
    Code can jump freely from secure to non-secure memory.  But what can not happen is code running from unsecure can not access data that is within secure memory.  Do you by chance have some code that is in non-secure memory trying to access data which is in secure memory?

    I'm not sure if I'm accessing some secured memory position. I don't think so.

    I'm doing regular access at ADC interrup location as adc registers.

    my ".cmd" file is like this:


    ===============================================================================================================================
    MEMORY
    {
    PAGE 0 :
       /* BEGIN is used for the "boot to SARAM" bootloader mode   */

    /*   BEGIN       : origin = 0x000000, length = 0x000002*/

       FLASHAtoH   : origin = 0x3E8000, length = 0x00FF80     /* on-chip FLASA to FLASH */

       CSM_RSVD    : origin = 0x3F7F80, length = 0x000076     /* Part of FLASHA.  Program with all 0x0000 when CSM is in use. */
       BEGIN       : origin = 0x3F7FF6, length = 0x000002     /* Part of FLASHA.  Used for "boot to Flash" bootloader mode. */
       CSM_PWL_PROG: origin = 0x3F7FF8, length = 0x000008     /* Part of FLASHA.  CSM password locations in FLASHA */

       RESET       : origin = 0x3FFFC0, length = 0x000002
       IQTABLES    : origin = 0x3FE000, length = 0x000B50     /* IQ Math Tables in Boot ROM */
       IQTABLES2   : origin = 0x3FEB50, length = 0x00008C     /* IQ Math Tables in Boot ROM */
       IQTABLES3   : origin = 0x3FEBDC, length = 0x0000AA     /* IQ Math Tables in Boot ROM */

       BOOTROM     : origin = 0x3FF27C, length = 0x000D44
       RAMM1       : origin = 0x000250, length = 0x0005B0     /* on-chip RAM block M1 modifiquei origin = 0x000400, length = 0x000400*/


    PAGE 1 :

       BOOT_RSVD   : origin = 0x000002, length = 0x00004E     /* Part of M0, BOOT rom will use this for stack */
       RAMM0       : origin = 0x000050, length = 0x000200      /* on-chip RAM block M0 modifiquei 0x0003B0*/
       RAML0toL3   : origin = 0x008000, length = 0x0020C0     /* on-chip RAM block LO,L1,L2,L3 */

    }


    SECTIONS
    {
       /* Setup for "boot to SARAM" mode:
          The codestart section (found in DSP28_CodeStartBranch.asm)
          re-directs execution to the start of user code.  */
       codestart        : > BEGIN,     PAGE = 0
       ramfuncs         : LOAD = FLASHAtoH,
                          RUN = RAMM1,
                          LOAD_START(_RamfuncsLoadStart),
                          LOAD_END(_RamfuncsLoadEnd),
                          RUN_START(_RamfuncsRunStart),
                          PAGE = 0

       .text            : > FLASHAtoH, PAGE = 0
       .cinit           : > FLASHAtoH, PAGE = 0
       .pinit           : > FLASHAtoH, PAGE = 0

       csmpasswds       : > CSM_PWL_PROG PAGE = 0
       csm_rsvd         : > CSM_RSVD     PAGE = 0

       /* Initalized sections go in Flash */
       /* For SDFlash to program these, they must be allocated to page 0 */
       .switch          : > FLASHAtoH, PAGE = 0
       .econst          : > FLASHAtoH, PAGE = 0

       /* .reset is a standard section used by the compiler.  It contains the */
       /* the address of the start of _c_int00 for C Code.   /*
       /* When using the boot ROM this section and the CPU vector */
       /* table is not needed.  Thus the default type is set here to  */
       /* DSECT  */
       .reset           : > RESET,     PAGE = 0, TYPE = DSECT /* not used, */

       /* Allocate uninitalized data sections: */
       .stack           : > RAMM0,     PAGE = 1
       .ebss            : > RAML0toL3, PAGE = 1
       .esysmem         : > RAML0toL3, PAGE = 1

       IQmath           : > FLASHAtoH, PAGE = 0
       IQmathTables     : > IQTABLES,  PAGE = 0, TYPE = NOLOAD

      /* Uncomment the section below if calling the IQNexp() or IQexp()
          functions from the IQMath.lib library in order to utilize the
          relevant IQ Math table in Boot ROM (This saves space and Boot ROM
          is 1 wait-state). If this section is not uncommented, IQmathTables2
          will be loaded into other memory (SARAM, Flash, etc.) and will take
          up space, but 0 wait-state is possible.
       */
       /*
       IQmathTables2    : > IQTABLES2, PAGE = 0, TYPE = NOLOAD
       {

                  IQmath.lib<IQNexpTable.obj> (IQmathTablesRam)

       }
       */
       /* Uncomment the section below if calling the IQNasin() or IQasin()
          functions from the IQMath.lib library in order to utilize the
          relevant IQ Math table in Boot ROM (This saves space and Boot ROM
          is 1 wait-state). If this section is not uncommented, IQmathTables2
          will be loaded into other memory (SARAM, Flash, etc.) and will take
          up space, but 0 wait-state is possible.
       */
       /*
       IQmathTables3    : > IQTABLES3, PAGE = 0, TYPE = NOLOAD
       {

                  IQmath.lib<IQNasinTable.obj> (IQmathTablesRam)

       }
       */

    }
    ===============================================================================================================================


    And here are the functions that run from RAM:

    // Functions that will be run from RAM need to be assigned to
    // a different section.  This section will then be mapped using
    // the linker cmd file.
    #pragma CODE_SECTION(adc_isr, "ramfuncs");
    interrupt void adc_isr(void);
    #pragma CODE_SECTION(xint1_isr, "ramfuncs");
    interrupt void xint1_isr(void);
    #pragma CODE_SECTION(xint2_isr, "ramfuncs");
    interrupt void xint2_isr(void);
    #pragma CODE_SECTION(sciaRxFifoIsr, "ramfuncs");
    interrupt void sciaRxFifoIsr(void);

    Lori Heustess said:
    On the 28035 you can disable the ECSL (which is what keeps you from stepping through code when the password is protected) by using half of the password.  This would allow you to see if you get into the interrupt and step through the code (you wont' be able to see the code, but you can see the effect on registers).  This may give you a clue as to where things are going wrong.

    I do not understand how to disable the ECSL. Could you give me some more information in how to do? or some documentation?

    Whitch memory locations are secured? Could I read adc register as "AdcResult.ADCRESULT0" from RAM memory?

    Thanks.

  • Marcio said:
    ramfuncs         : LOAD = FLASHAtoH,
                          RUN = RAMM1,
                          LOAD_START(_RamfuncsLoadStart),
                          LOAD_END(_RamfuncsLoadEnd),
                          RUN_START(_RamfuncsRunStart),
                          PAGE = 0

    The ramfuncs section (where you have the ISRs assigned via the CODE_SECTION pragma) is executing from M1 which is not within secure memory. 

    If I look at the data sections, I see

    • stack is in M0 which is not within secure memory so it is ok
    • .ebss is in L0 which is secure.  If the ISR is trying to access global data, it will not be able to do so. 
    • .esysmem is for things like malloc (heap) I doubt you are doing this in the ISR

    Marcio said:
    I do not understand how to disable the ECSL. Could you give me some more information in how to do? or some documentation?

    The CSM is documented in this guide: www.ti.com/lit/SPRUGL8

    Basically instead of providing all of the password like you are doing to unlock the CSM, you only provide half of the password.  This will allow you to step through code and observe the behavior with the code security itself still in place.  It will now allow you to see the opcodes, but you can see if you go into the ISR.  From your memory map I suspect you are, but the ISR can not view global variables. 

    Marcio said:
    Could I read adc register as "AdcResult.ADCRESULT0" from RAM memory?

    Peripheral registers can be read from secure or unsecure memory.  The only exception is flash configuration registers which are considered secure.

    Marcio said:
    Whitch memory locations are secured? Could I read adc register as "AdcResult.ADCRESULT0" from RAM memory?

    The secure blocks are indicated in the memory map shown in the data manual www.ti.com/lit/SPRS584. Refer to section 3.2 memory maps.  The memory blocks with "secure zone" indicated are protected by the CSM module. 

  • Hi Lori,

    I was working exactly at this point before you wrote this reply.

    Anyway, now I took out all my doubts.

    I changed my .cmd file for this:

    ===========================================================================

    MEMORY
    {
    PAGE 0 :
       /* BEGIN is used for the "boot to SARAM" bootloader mode   */

    /*   BEGIN       : origin = 0x000000, length = 0x000002*/

       FLASHAtoH   : origin = 0x3E8000, length = 0x00FF80     /* on-chip FLASA to FLASH */

       CSM_RSVD    : origin = 0x3F7F80, length = 0x000076     /* Part of FLASHA.  Program with all 0x0000 when CSM is in use. */
       BEGIN       : origin = 0x3F7FF6, length = 0x000002     /* Part of FLASHA.  Used for "boot to Flash" bootloader mode. */
       CSM_PWL_PROG: origin = 0x3F7FF8, length = 0x000008     /* Part of FLASHA.  CSM password locations in FLASHA */

       RESET       : origin = 0x3FFFC0, length = 0x000002
       IQTABLES    : origin = 0x3FE000, length = 0x000B50     /* IQ Math Tables in Boot ROM */
       IQTABLES2   : origin = 0x3FEB50, length = 0x00008C     /* IQ Math Tables in Boot ROM */
       IQTABLES3   : origin = 0x3FEBDC, length = 0x0000AA     /* IQ Math Tables in Boot ROM */

       BOOTROM     : origin = 0x3FF27C, length = 0x000D44
       RAMM1       : origin = 0x000400, length = 0x000400     /* on-chip RAM block M1*/

       RAML0toL3   : origin = 0x008000, length = 0x0020C0     /* on-chip RAM block LO,L1,L2,L3 */

    PAGE 1 :

       BOOT_RSVD   : origin = 0x000002, length = 0x00004E     /* Part of M0, BOOT rom will use this for stack */
       RAMM0       : origin = 0x000050, length = 0x0003B0      /* on-chip RAM block M0*/

    }


    SECTIONS
    {
       /* Setup for "boot to SARAM" mode:
          The codestart section (found in DSP28_CodeStartBranch.asm)
          re-directs execution to the start of user code.  */
       codestart        : > BEGIN,     PAGE = 0
       ramfuncs         : LOAD = FLASHAtoH,
                          RUN = RAML0toL3,
                          LOAD_START(_RamfuncsLoadStart),
                          LOAD_END(_RamfuncsLoadEnd),
                          RUN_START(_RamfuncsRunStart),
                          PAGE = 0

       .text            : > FLASHAtoH, PAGE = 0
       .cinit           : > FLASHAtoH, PAGE = 0
       .pinit           : > FLASHAtoH, PAGE = 0

       csmpasswds       : > CSM_PWL_PROG PAGE = 0
       csm_rsvd         : > CSM_RSVD     PAGE = 0

       /* Initalized sections go in Flash */
       /* For SDFlash to program these, they must be allocated to page 0 */
       .switch          : > FLASHAtoH, PAGE = 0
       .econst          : > FLASHAtoH, PAGE = 0

       /* .reset is a standard section used by the compiler.  It contains the */
       /* the address of the start of _c_int00 for C Code.   /*
       /* When using the boot ROM this section and the CPU vector */
       /* table is not needed.  Thus the default type is set here to  */
       /* DSECT  */
       .reset           : > RESET,     PAGE = 0, TYPE = DSECT /* not used, */

       /* Allocate uninitalized data sections: */
       .stack           : > RAMM0,     PAGE = 1
       .ebss            : > RAML0toL3, PAGE = 0
       .esysmem         : > RAML0toL3, PAGE = 0

       IQmath           : > FLASHAtoH, PAGE = 0
       IQmathTables     : > IQTABLES,  PAGE = 0, TYPE = NOLOAD
    ===========================================================================

    Up to now, all is working great!

    Thanks for your attention.