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.

TMS320F28069: Unlocking CMS does not work.

Part Number: TMS320F28069


Subject: TMS320F28069: Unlocking CMS does not work.

 

Hello team,

I tried to enter the Secure Mode, then to return from it back to Unsecure Mode. Entering the S.M. worked but
returning to U.M. failed, despite using the recommended procedure.
So, the device cannot be flashed by both debugger and our bootloader -- It seems lost.

The steps I carried out were:

 I mapped a constant array Uint16 CsmPwl[8] that carries the password to Adr. 3f7ff8:
  

Declaration:
#pragma DATA_SECTION(CsmPwl,"CsmPwlFile");

const struct CSM_PWL CsmPwl = {0x434C, 0x4F53, 0x4544, 0x2034, 0x2052, 0x4F4D, 0x414E, 0x5321};

Using MAP file and debugger, I verified that the password array was in correct location, and order of elements was correct.

I verified that all key registers were 0xFFFF on program start.
Verified that the key variable CsmRegs was mapped to the right address.

On start of the debugger (before calling the function which does unsecuring), the device was unsecure
despite the mentioned password had been programmed to flash.

A call to function DeviceUnsecure( ) is done immediately at beginning of main() after the declarations. (listings next page).

-- I just stepped through the declarations and stopped before DeviceUnsecure was called.
At that point, I manually set CSMSCR to 0x8000.
The device switched to secure immediately, as could be seen from the debugger's display.

Then I stopped debugging and rebooted the device without debugger (power off/on).
I expected the device to be unsecure now, as DeviceUnsecure is called as first action in program flow. See code listings below.

I found that the device was still secure despite that call, so that now no more access is possible as mentioned above.

So, what could have happened or went wrong? Are there mistakes in the manual?

 

 

 

 

 

void main( void )

{
    Uint16 u16_main_scratch = 0;
    volatile eEEP_RET eepState;
    int iwait;

    DeviceUnsecure ( );

    f32_gl_id_sollwert = 0.0;
    LedState.all = OFF;
    ...
    ...
}

--------------------------------------------------

Listing of DeviceUnsecure ( ):

...

#define PASSWORD_LENGTH 8

...

void DeviceUnsecure ( void )

{
   Uint16 i;
   Uint16 *pCell;
   volatile Uint16 tmp;

   pCell = (Uint16*) &CsmPwl;     // CsmPWL is global!

   for ( i = 0; i < PASSWORD_LENGTH; i++ ) tmp = *pCell++;

   EALLOW;
   CsmRegs.KEY0 = 0x434C;
   CsmRegs.KEY1 = 0x4F53;
   CsmRegs.KEY2 = 0x4544;
   CsmRegs.KEY3 = 0x2034;
   CsmRegs.KEY4 = 0x2052;
   CsmRegs.KEY5 = 0x4F4D;
   CsmRegs.KEY6 = 0x414E;
   CsmRegs.KEY7 = 0x5321;
   EDIS;
}

 

Declaration/Initialization of global CsmPwl:

const struct CSM_PWL CsmPwl = {0x434C, 0x4F53, 0x4544, 0x2034, 0x2052, 0x4F4D, 0x414E, 0x5321};

 

Best Regards,

Goetz

  • The below is my understanding of the issue:

    • You secured the device with passwords.
    • You verified that the passwords were written to the correct locations.
    • After cycling power, you are now unable to connect to the device using CCS.

    Is the above correct? 

    If so, this is because the ECSL is tripping the debugger connection. Please use the wait boot mode, establish connection with the device and then unsecure the device. This has been discussed numerous times on the e2e forum before. Please do a Google search with "site:e2e.ti.com wait AND boot" for helpful links

  • Hello,

    The problem is slightly different:

    Your first 2 statements are correct.

    • I loaded the program to the device, using the debugger (stopped at beginning of main()).
    • I checked whether everything was o.k. with password storage etc. It was.
    • Then I manually set bit FORCESEC in CSMSCR to 1. The processor reacted immediately as could be seen
      in the debugger.
    • I did not continue executing code but at this point terminated the debugger.
    • Then, I restarted the device without debugger.
    •  DeviceUnsecure ( ) is the first action the program takes (after initializing 1 variable).
      So, the processor should unlock itself on program startup (please have a look to the code snippets from main() and
      DeviceUnsecure ( ) in my yesterday posting).
    • But the processor does not unlock. Obviously, it is still secured even after executing DeviceUnsecure ( ).
    • As a consequence, it is no longer accessible by the debugger and cannot be flashed again (no matter if by debugger or
      bootloader).

    So, I'm asking myself what's wrong here. As for me, I cannot judge about if ECSL is involved...

    By the way: What actually means "trip" in this context?. This term is frequently used but never explained in the documentation.
                           I know "trip" only as a synonym for "journey" and friends... ;-)

  • Hello again,

    here is a supplement to my reply I sent before -- in order to avoid misunderstandings.

    • Our device is configured to branch directly (via 0x0x3F7FF6) to our self-developed bootloader
      which in turn branches directly to the application code... This bootloader was meant in my reply.
    • We never used emulation for debugging (so I'm not at all familiar with the topic ECSL).

    Best regards,

    Goetz

  • Then I manually set bit FORCESEC in CSMSCR to 1. The processor reacted immediately as could be seen in the debugger.

    By "reacted" I presume you mean ECSL kicking in and tripping the JTAG connection, as evidenced by an error message in the CCS window. Anyway, at this point your device is secured by passwords.

    I did not continue executing code but at this point terminated the debugger.

    You mean you disconnected?

    Then, I restarted the device without debugger.

    Do you mean you restarted without the JTAG cable or with the JTAG cable but without invoking CCS?

    DeviceUnsecure ( ) is the first action the program takes (after initializing 1 variable). So, the processor should unlock itself on program startup (please have a look to the code snippets from main() and DeviceUnsecure ( ) in my yesterday posting).

    While the processor is executing the Unsecure function, is the JTAG connector connected?

    But the processor does not unlock. Obviously, it is still secured even after executing DeviceUnsecure ( ).

    Say you have an infinite loop right after the Unsecure function. What happens if you attempt to connect to the device via CCS after the Unsecure operation?

    As a consequence, it is no longer accessible by the debugger and cannot be flashed again (no matter if by debugger or bootloader).

    As mentioned before, the ECSL will not allow debugger connection on a secured device if secure areas like flash is accessed by default. This is the reason we have the Wait mode in boot-ROM. You need to change your boot mode to Wait, establish CCS connection and *then* erase the flash.

    So, I'm asking myself what's wrong here. As for me, I cannot judge about if ECSL is involved...

    ECSL will be involved on a secure device that is configured to boot to flash (which is the case in your setup)

    By the way: What actually means "trip" in this context?. This term is frequently used but never explained in the documentation.

    "Trip" means the connection between the debug probe and the device will be broken, so that CCS will not be able to communicate with the device anymore. Something akin to a circuit-breaker tripping. i.e. breaking the connection.

    We never used emulation for debugging (so I'm not at all familiar with the topic ECSL).

    Sorry I don't understand. The word "emulation" is a misnomer as nothing is being "emulated". We are replacing the word "emulator" with "debug probe" in all TI docs. You do use CCS for debugging, correct?

  • By "reacted" I presume you mean ECSL kicking in and tripping the JTAG connection, as evidenced by an error message in the CCS window. Anyway, at this point your device is secured by passwords.

    ==> "Reacted" means that e.g. all displayed variables in the "Expressions"- and "Variable"- windows changed to zero. ===> They could not be read anymore.

    You mean you disconnected?

    ==> I terminated the debugger, then disconnected the probe.

    Then, I restarted the device without debugger.

    Do you mean you restarted without the JTAG cable or with the JTAG cable but without invoking CCS?

    ==> Yes.

    While the processor is executing the Unsecure function, is the JTAG connector connected?

    ==> No, the device started "as is".

    Say you have an infinite loop right after the Unsecure function. What happens if you attempt to connect to the device via CCS after the Unsecure operation?

    ==> The loop is not immediately after the Unsecure() call. But after executing some "linear" code after the call (e.g. initializations), a main loop is reached which can be seen from some CAN output. At this state, I reconnected the debug probe and started the CCS debugger.

    As mentioned before, the ECSL will not allow debugger connection on a secured device if secure areas like flash is accessed by default. This is the reason we have the Wait mode in boot-ROM. You need to change your boot mode to Wait, establish CCS connection and *then* erase the flash.

    ==> I did so. By external circuitry, GPIO37 is kept high while GPIO34 is pulled low. OTP is unused. If I understood you right, this configuration should enable the debugger accessing the target. In fact, it does not. The debugger reports error 1135, then terminates after the message box is closed.

    "Trip" means the connection between the debug probe and the device will be broken, so that CCS will not be able to communicate with the device anymore. Something akin to a circuit-breaker tripping. i.e. breaking the connection.

    ==> O.k. ;-)

    Sorry I don't understand. The word "emulation" is a misnomer as nothing is being "emulated". We are replacing the word "emulator" with "debug probe" in all TI docs. You do use CCS for debugging, correct?

    ==> Ok, copied. ;-)

     

    Annotation: As an experiment, I changed the configuration in the properties/Debug/Flash settings dialog before trying to start the debugger:
    I changed the code security key<x> entries so that they reflected the hardcoded password. Then I tried again to start the debugger with the target device in "wait" state.

    Surprisingly, the debugger managed to clear the flash sectors that were configured to be cleared, then began to write code to the flash. But this stopped at an uncertain state with a "Nonzero" error message. On later attempts, this behavior could not be reproduced. So I reconfigured the key entries back to 0xFFFF.

    So, the current state is:

    - The firmware (on flash sectors H,G and F) that hardcoded the password has been erased. As the debugger was configured to erase just sectors H through C, I think the password is still in place.
    - Our bootloader (sector A. B is reserved) is still on board.
    - The target keeps inaccessible to the debugger even when in "wait" state.

     

  • My (updated) understanding of your current situation:

    You have a secured device that you power-up without the JTAG connector connected. This device powers up, executes the unsecure function and some initialization and ends in a loop. At this point, device should be unsecure. However, when you connect the JTAG connector, invoke CCS and attempt to connect to the device, you are unable to do so and CCS returns an error. I wonder if there could be some error in your unsecure function. 

    You put the device in Wait boot mode and power it up. Now when you connect the JTAG connector, invoke CCS and attempt to connect to the device, you are unable to do so and CCS returns an error. This is strange. Even if the device is secure, Wait boot mode should let you connect to CCS. That is the very purpose of that mode.

  • My (updated) understanding of your current situation:

    You have a secured device that you power-up without the JTAG connector connected. This device powers up, executes the unsecure function and some initialization and ends in a loop. At this point, device should be unsecure. However, when you connect the JTAG connector, invoke CCS and attempt to connect to the device, you are unable to do so and CCS returns an error.

    ==> Yes. absolutely correct.

    I wonder if there could be some error in your unsecure function. 

    ==> Here is the unsecure function as used in my software. In addition, I cite the declarations involved:

    ---------------------------- THE FUNCTION: ---------------------------------------

    void DeviceUnsecure ( void )
    {
        Uint16 i;
        Uint16 *pCell;
        volatile Uint16 tmp;

        pCell = (Uint16*) &CsmPwl;     // I checked the address of CsmPwl in a non-locking SW version: It's correct: 0x3F7FF8

        for ( i = 0; i < PASSWORD_LENGTH; i++ ) tmp = *pCell++;

        EALLOW;
        CsmRegs.KEY0 = 0x434C;    // Address of CsmRegs: also correct: 0xAE0
        CsmRegs.KEY1 = 0x4F53;
        CsmRegs.KEY2 = 0x4544;
        CsmRegs.KEY3 = 0x2034;
        CsmRegs.KEY4 = 0x2052;
        CsmRegs.KEY5 = 0x4F4D;
        CsmRegs.KEY6 = 0x414E;
        CsmRegs.KEY7 = 0x5321;
        EDIS;

    }

    -------------------------- THE DECLARATIONS  -------------------------------

    Password declaration:

    const struct CSM_PWL CsmPwl = {0x434C, 0x4F53, 0x4544, 0x2034, 0x2052, 0x4F4D, 0x414E, 0x5321};

    Struct declarations of key registers:

    struct  CSM_REGS {
       Uint16           KEY0;    // KEY reg bits 15-0
       Uint16           KEY1;    // KEY reg bits 31-16
       Uint16           KEY2;    // KEY reg bits 47-32
       Uint16           KEY3;    // KEY reg bits 63-48
       Uint16           KEY4;    // KEY reg bits 79-64
       Uint16           KEY5;    // KEY reg bits 95-80
       Uint16           KEY6;    // KEY reg bits 111-96
       Uint16           KEY7;    // KEY reg bits 127-112
       Uint16           rsvd1;   // Reserved
       Uint16           rsvd2;   // Reserved
       Uint16           rsvd3;   // Reserved
       Uint16           rsvd4;   // Reserved
       Uint16           rsvd5;   // Reserved
       Uint16           rsvd6;   // Reserved
       Uint16           rsvd7;   // Reserved
       union CSMSCR_REG CSMSCR;  // CSM Status & Control register
    };

    Declaration of the password struct:

    struct  CSM_PWL {
       Uint16   PSWD0;  // PSWD bits 15-0
       Uint16   PSWD1;  // PSWD bits 31-16
       Uint16   PSWD2;  // PSWD bits 47-32
       Uint16   PSWD3;  // PSWD bits 63-48
       Uint16   PSWD4;  // PSWD bits 79-64
       Uint16   PSWD5;  // PSWD bits 95-80
       Uint16   PSWD6;  // PSWD bits 111-96
       Uint16   PSWD7;  // PSWD bits 127-112
    };

    You put the device in Wait boot mode and power it up. Now when you connect the JTAG connector, invoke CCS and attempt to connect to the device, you are unable to do so and CCS returns an error.

    ==> Yes, this is correct, too. I re-checked the states of
    (GPIO37 - GPIO34 - /TRST)  by measurement: ==> (HI - LOW - HI). OTP confimed as unused.

    Using the hexfile, I checked correct population of areas 0x3F7F80 .. 0x3F7FF7 => 0x0000
                                                             0x3F7FF8 .. 0x3F7FFF => 0xFFFF
                                                             0x000AE0 .. 0x000AE7 => 0x0000

    This is strange. Even if the device is secure, Wait boot mode should let you connect to CCS. That is the very purpose of that mode.

    ===> Hmmmm... The last thing I can try is to use (and possibly sacrifice) another board.. I'll tell
    you what resulted...

    Thanks so far...

    BR Goetz

  •  

    SORRY: CORRECTION to my just-sent posting:


    ======================================
    /TRST  wasn't measured HI but LOW !!!
    ======================================


    BR Goetz

  •  

    SORRY once more: CORRECTION  #2 to my 2nd last posting:


    ======================================
    On the board in question, the area 0x3F7FF8 .. 0x3F7FFF was loaded with the password, words in correct order.

    This had been checked by means of the hexfile.
    ======================================


    BR Goetz

  • Could you please "simplify" your passwords like this?

    1111

    FFFF

    FFFF

    FFFF

    FFFF

    FFFF

    FFFF

    1111

    This is to just make it "symmetrical", so the order in which you perform operations wouldn’t matter. 

    /TRST wasn't measured HI but LOW !!!

    -TRST should be low for normal operation. i.e. without the JTAG connector connected (and CCS controlling the device) 

    On the board in question, the area 0x3F7FF8 .. 0x3F7FFF was loaded with the password, words in correct order. This had been checked by means of the hexfile.

    OK. Did you verify the addresses in flash as well?

  • Hello from Ubstadt

    -TRST should be low for normal operation. i.e. without the JTAG connector connected (and CCS controlling the device) 

    On the board in question, the area 0x3F7FF8 .. 0x3F7FFF was loaded with the password, words in correct order. This had been checked by means of the hexfile.

    OK. Did you verify the addresses in flash as well?

    ==> This can be done only by reading the hexfile (which we use to generate in parallel)
    since no access by debugger is possible if once the device is locked. Thus, I cannot check
    the addresses directly.

    ---

    As for hexfile generation:
    What I wonder about is that an additional hexfile (*.m10) is generated, containing just
    the line with the password:

    (Blanks inserted for readability):

    S00600004844521B
    S3 15 003F7FF8 434C 4F53 4544 2034 2052 4F4D 414E 5321 15
    S705003D80003D

    whereas in the "regular" hexfile this line is

    S3 15 003F7FF8 FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF 44

    But anyway, since the debugger uses the *.out file for flashing the device, the above should be meaningless.

    By the way: Is it possible to integrate the line that contains the password in the "regular" hexfile, so that
    only one hexfile must be loaded when loading by hexfile is desired?

    --------------------------

    After all, we decided not to use a password (at least preliminarily) because on every
    failed attempt we lose an entire board...

    BR Goetz

  • Once you program your code in flash, you should be able to examine the contents of the password locations without disconnecting the debugger. 

    I do find it strange that you can’t connect in wait mode, though. Could you try the SCI mode? 

    Is this your own board or a TI board like Launchpad/Controlcard?

  • Once you program your code in flash, you should be able to examine the contents of the password locations without disconnecting the debugger. 

    Frankly, we hesitate to try this again: Every failed attempt will result in a board being lost...
    So, we try to approach the problem from the "wait mode" side. Moreover, this has the advantage that
    it excludes erronenous software as a reason of the malfunction...

    I do find it strange that you can’t connect in wait mode, though. Could you try the SCI mode? 

    What we did is pulling GPIO37: high, GPIO34: Low; /TRST: Low as long as JTAG is not connected.
    We verified this by measuring the pins directly: Everything correct. Subsequently, we connected the JTAG and
    tried to start CCS Debugger. CCS reported Error 1135: No connection possible.

    ==> Is there anything else we have to consider?? Are there known side effects that might occur depending on the state of other pins?

    Is this your own board or a TI board like Launchpad/Controlcard?

    No, it is a proprietary board.

     

  • Hi,

    What we did is pulling GPIO37: high, GPIO34: Low; /TRST: Low as long as JTAG is not connected.
    We verified this by measuring the pins directly: Everything correct. Subsequently, we connected the JTAG and
    tried to start CCS Debugger. CCS reported Error 1135: No connection possible.

    ==> Is there anything else we have to consider?? Are there known side effects that might occur depending on the state of other pins?

    That should put device in "Wait" mode. Can you try running the "Test Connection" via target configuration file. Double click on target configuration file and then click on "Test Connection". This is to check that there is no issue with JTAG signals on board.

    Regards,

    Vivek Singh