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.

TMS570LC4357: Can the CPU jump to the FLASH OTP area to address and execute the program?

Part Number: TMS570LC4357
Other Parts Discussed in Thread: HALCOGEN, UNIFLASH

Tool/software:

Dear Ti Team

Since the MCU can only boot from address 0 of the FLASH, I wrote assembly at address 0, which can b directly to other areas to execute new code.

I burned a new program in the bank0 OTP area of the flash and it burned successfully.

Then I jump from address 0 to bank 0 OTP area (0xF0000010).

But nothing happened. The program wasn't executed.

Does the FLASH BANK 0 OTP area have execution privileges and can the CPU address and execute from that area?

We want to put the program in the FLASH OTP area because it is secure enough.

This incident is rather urgent, please reply as soon as possible, thank you!

  • Hi Sam,

    On HALCoGen by default this area is configured for No Execution:

    Can you try by configuring Execution permission for this area?

    --
    Thanks & regards,
    Jagadish.

  • HI gundavarapu,

    Thank you very much for your prompt reply!

    I have tried to turn off the MPU directly, can I cancel the MPU protection by doing this?

    Tere is my link file(After that I also burned a program in the OTP area of bank1):

    /*----------------------------------------------------------------------------*/
    /* sys_link.cmd                                                               */
    /*                                                                            */
    /* 
    * Copyright (C) 2009-2018 Texas Instruments Incorporated - 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.
    *
    */
    
    /*                                                                            */
    /*----------------------------------------------------------------------------*/
    /* USER CODE BEGIN (0) */
    /* USER CODE END */
    
    
    /*----------------------------------------------------------------------------*/
    /* Linker Settings                                                            */
    
    --retain="*(.intvecs)"
    
    /* USER CODE BEGIN (1) */
    /* USER CODE END */
    
    /*----------------------------------------------------------------------------*/
    /* Memory Map                                                                 */
    
    MEMORY
    {
    /* USER CODE BEGIN (2) */
    /* USER CODE END */
        VECTORS (X)  : origin=0xF0002020 length=0x00000040
        FLASH0  (RX) : origin=0x00000000 length=(0x00200000-0x00000000)
        FLASH1  (RX) : origin=0x00200000 length=(0x00400000 - 0x00200000)
        FLASH0_OTP	(RX) : origin=0xF0000000 length=(0xF0001FFF - 0xF0000000)
        FLASH1_OTP	(RX) : origin=0xF0002060 length=(0xF0003FFF - 0xF0002060)
        STACKS  (RW) : origin=0x08000000 length=0x00001500
        RAM     (RW) : origin=0x08001500 length=0x0007eb00
    
    /* USER CODE BEGIN (3) */
    /* USER CODE END */
    }
    
    /* USER CODE BEGIN (4) */
    /* USER CODE END */
    
    
    /*----------------------------------------------------------------------------*/
    /* Section Configuration                                                      */
    
    SECTIONS
    {
    /* USER CODE BEGIN (5) */
    /* USER CODE END */
        .intvecs : {} > VECTORS
        .text   align(32) : {} > FLASH0_OTP //| FLASH1
        .const  align(32) : {} > FLASH0_OTP //| FLASH1
        .cinit  align(32) : {} > FLASH0_OTP //| FLASH1
        .pinit  align(32) : {} > FLASH0_OTP //| FLASH1
        .bss     : {} > RAM
        .data    : {} > RAM
        .sysmem  : {} > RAM
    	
    
    /* USER CODE BEGIN (6) */
    /* USER CODE END */
    }
    
    /* USER CODE BEGIN (7) */
    /* USER CODE END */
    
    
    /*----------------------------------------------------------------------------*/
    /* Misc                                                                       */
    
    /* USER CODE BEGIN (8) */
    /* USER CODE END */
    /*----------------------------------------------------------------------------*/

  • Sorry, misspelled, actually:

    .text align(32) : {} > FLASH1_OTP //| FLASH1
    .const align(32) : {} > FLASH1_OTP //| FLASH1
    .cinit align(32) : {} > FLASH1_OTP //| FLASH1
    .pinit align(32) : {} > FLASH1_OTP //| FLASH1

  • I've now turned on MPU and then also given execute permission as shown below.

    Then I burned the program to bank7 again and the link file is shown below.

    MEMORY
    {
    /* USER CODE BEGIN (2) */
    /* USER CODE END */
        VECTORS (X)  : origin=0xF0200000 length=0x00000020
        FLASH0  (RX) : origin=0x00000000 length=(0x00200000 - 0x00000000)
        FLASH1  (RX) : origin=0x00200000 length=0x00200000
        EEPROM  (RX) : origin=0xF0200020 length=(0xF0220000 - 0xF0200020)
        STACKS  (RW) : origin=0x08000000 length=0x00001500
        RAM     (RW) : origin=0x08001500 length=0x0007EB00
    
    /* USER CODE BEGIN (3) */
    /* USER CODE END */
    }
    
    /* USER CODE BEGIN (4) */
    /* USER CODE END */
    
    
    /*----------------------------------------------------------------------------*/
    /* Section Configuration                                                      */
    
    SECTIONS
    {
    /* USER CODE BEGIN (5) */
    /* USER CODE END */
        .intvecs : {} > VECTORS
        .text   align(32) : {} > EEPROM//FLASH0 | FLASH1
        .const  align(32) : {} > EEPROM//FLASH0 | FLASH1
        .cinit  align(32) : {} > EEPROM//FLASH0 | FLASH1
        .pinit  align(32) : {} > EEPROM//FLASH0 | FLASH1
        .bss     : {} > RAM
        .data    : {} > RAM
        .sysmem  : {} > RAM
    	
    
    /* USER CODE BEGIN (6) */
    /* USER CODE END */
    }

    The jump instruction is shown below.

    ((void (*)(void))0xF0200000U)();

    Execution of the code leads directly to the undefEntry exception.

  • Hello gundavarapu, I know it's not very polite, but I do have a bit of urgency on my side to solve this problem, can I trouble you to reply quickly? Can you please reply quickly?

  • Hi Sam,

    ((void (*)(void))0xF0200000U)();

    Where are you calling this function?

    Are you using any bootloader?

    Actually, on this device the code execution always begins at 0x00000000 right? so there should be some code from address 0x00000000 to call out the code in flash bank-7 that is 0xF0200000. I mean some kind of bootloader is required to call out the code in the bank-7. So, a bootloader is required.

    Please take below UART bootloader code as reference:

    (+) [FAQ] TMS570LC4357: Step by step procedure to execute UART Bootloader on TMS570LC4357 - Arm-based microcontrollers forum - Arm-based microcontrollers - TI E2E support forums

    Try to create two projects like i given in the above example, and keep the application at 0xF0200000 instead of 0x20020.

    --
    Thanks & regards,
    Jagadish.

  • Sorry, maybe I didn't it well.You are correct, the program must be loaded at address 0 to start.

    Note that I'm experimenting with bank 7 now, but ultimately it's to experiment with programs in the bank 0 OTP region.

    1. first program(0 address)

    1.1 开启bank7的执行权限

    1.2 main函数

    /* USER CODE BEGIN (0) */
    #include "Types.h"
    #include "F021.h"
    #include "HL_reg_flash.h"
    #include "sci_common.h"
    #include "HL_sci.h"
    #include "HL_reg_sci.h"
    #include "HL_gio.h"
    #include "HL_reg_gio.h"
    /* USER CODE END */
    
    /* Include Files */
    
    #include "HL_sys_common.h"
    
    /* USER CODE BEGIN (1) */
    #define SYS_CLK_FREQ            150
    #define OTP_ADDR 0xF0002020U
    #define BANK7_ADDR 0xF0200000U
    
    Fapi_StatusType Fapi_serviceWatchdogTimer(void);
    
    uint8_t DataBuffer[4] = {0x55,0x66,0x77,0x88};
    uint8_t ReadBuffer1[48] = {0};
    uint8_t ReadBuffer2[4] = {0};
    
    Fapi_StatusType Return_Status;
    uint32_t i = 0;
    uint8_t OtpBuffer[48] = {0};
    /* USER CODE END */
    
    /** @fn void main(void)
    *   @brief Application main function
    *   @note This function is empty by default.
    *
    *   This function is called after startup.
    *   The user can use this function to implement the application.
    */
    
    /* USER CODE BEGIN (2) */
    /* USER CODE END */
    
    int main(void)
    {
    /* USER CODE BEGIN (3) */
        sciInit();
        gioInit();
        gioSetDirection(gioPORTB, 0xFFFFFFFF);
    
        if ((Fapi_initializeFlashBanks((uint32_t)SYS_CLK_FREQ)) == Fapi_Status_Success){
                Fapi_setActiveFlashBank(Fapi_FlashBank7);                       /*Activate the Bank-7 for write*/
                Fapi_enableEepromBankSectors(0xFFFFFFFF,0);                             /*Enabling All 32 sectors in Bank-7 for programming*/
    //            Fapi_enableBanksForOtpWrite(0x01);
    
               while( FAPI_CHECK_FSM_READY_BUSY != Fapi_Status_FsmReady );
        }
    
        Fapi_doMarginReadByByte((uint8_t*)BANK7_ADDR,ReadBuffer1,48,Fapi_NormalRead);
        while( FAPI_CHECK_FSM_READY_BUSY == Fapi_Status_FsmBusy );
        while(FAPI_GET_FSM_STATUS != Fapi_Status_Success);
        for(i = 0; i < 48; i++){
            UART_txByte(sciREG1, ReadBuffer1[i]);
        }
        //UART_putString(sciREG1, "/r/n");
    //
    //    Return_Status = Fapi_issueProgrammingCommand((uint32_t*)0xF0000010,DataBuffer,4,0,0,Fapi_AutoEccGeneration);    /*Programming data to 8th sector*/
    //    while( FAPI_CHECK_FSM_READY_BUSY == Fapi_Status_FsmBusy );
    //    while(FAPI_GET_FSM_STATUS != Fapi_Status_Success);
    //
    //    Fapi_doMarginReadByByte((uint8_t*)0xF0000010,ReadBuffer2,4,Fapi_NormalRead);
    //    while( FAPI_CHECK_FSM_READY_BUSY == Fapi_Status_FsmBusy );
    //    while(FAPI_GET_FSM_STATUS != Fapi_Status_Success);
    
    //    UART_putChar(sciREG1, "hello");
    //    Flash_ReadBlock(OTP_ADDR, OtpBuffer, 48);
    //    for(i = 0; i < 48; i++){
    //        UART_txByte(sciREG1, OtpBuffer[i]);
    //    }
        ((void (*)(void))0xF0200000U)();
        while(1){
            gioToggleBit(gioPORTB, 6);
            for(i = 0; i < 10000000; i++);
        }
    /* USER CODE END */
    
        return 0;
    }
    
    
    /* USER CODE BEGIN (4) */
    Fapi_StatusType Fapi_serviceWatchdogTimer(void)
    {
        ;
    }
    /* USER CODE END */

    2. led program(bank7 address)

    For this program I burned the .bin file to location 0xF0200000 via uniflash.

    See my previous reply for the contents of the linked file.

    3. The burn 0 address program did not erase bank7 and the debug result is shown below.

    Can you help me analyze what problem is causing this?

    If the bank7 experiment passes, I will test if the app program in the OTP area works.

    Looking forward to your reply, thanks.

  • It's been a week. Can you help me with the problem?

  • Hi Sam,

    Please try below two codes to execute the code in bank7 of the flash.

    8422.LED_Blinky_Project_at0x20020_Launchpad_LC4357.zip

    2146.UART_Bootloader_LC4357_New.zip

    Here i modified LED blinky application file linker file to store application in bank7.

    Follow below steps in CCS to run the application in bank7.

    1. First import and build the application project.

    2. Once you build the application project now load it into the flash using below option:

    Now browse project:

    click on OK to load the project into the flash.

    3. Once you load the application using above process, now make sure to configure "Necessary sectors only" for erase options of bootloader project.

    This is important because, we should not erase the already programmed application, right?

    4. Once you did that now you can directly debug the bootloader project.

    5. Here i modified bootloader to call the application present in the 0xF0200000.

    So, once you run this bootloader it will call the application directly and will execute it.

    6. You can see the PC value; it is showing that execution is happening in bank 7.

    And also, i observed LED blinking without any issues.

    --
    Thanks & regards,
    Jagadish.

  • Hello, gundavarapu
    I tried to use your routine and found that it is the problem of my LED light program, my first program can jump to your 8422.LED_Blinky_Project_at0x20020_Launchpad_LC4357.zip program, but I compared my LED light program, it seems that there is no difference with yours, can you please help! Can you help me?
    I will attach my code below.

    1. jump program

    Customer_OTP_Write_Test_LC4357_B.rar

    2. led program

    TMS_51_LED3_FLASH7.rar

  • I found where the difference is, in the HL_sys_startup.c file in the 8422.LED_Blinky_Project_at0x20020_Launchpad_LC4357.zip project, you commented out something as shown in the picture, why did you do that please?

    If I were to write my own program, not a simple LED program, would this be a problem?

    In fact it's these that cause my jumps to go to a prefetchEntry exception.

  • It is also interesting to note that the LED light program is in bank0 or bank1, and there is no need to comment these out to successfully jump to the LED program.

  • It makes sense that after placing the LED program in the OTP area of FLASH BANK0, the CPU can also jump to the OTP area to execute it, right?

  • Hi Sam,

    If I were to write my own program, not a simple LED program, would this be a problem?

    Not a problem for your own program as well, actually these initializations are not required for application because all these initializations will happen in bootloader itself right. So, it would be better to avoid these initializations in application.

    It makes sense that after placing the LED program in the OTP area of FLASH BANK0, the CPU can also jump to the OTP area to execute it, right?

    Yes, it can execute the program in OTP section also. The only thing is to make sure the jump address to the OTP area section in bootloader.

    --
    Thanks & regards,
    Jagadish.

  • Because the OTP area is 4KB in size, if you want to burn the program into the FLASH BANK0 OTP area, you need to trim the project, and the following is the structure of my trimmed project(Burn to BANK 7 for testing):

    Functional implementation is all in HL_sys_startup.c

    void _c_int00(void)
    {
    /* USER CODE BEGIN (5) */
    
    /* USER CODE END */
    
        /* Initialize Core Registers to avoid CCM Error */
        _coreInitRegisters_();
    
        /* Initialize Stack Pointers */
        _coreInitStackPointer_();
    
        _disable_IRQ_interrupt_();
        
        __asm(" DSB");
        __asm(" ISB");
    
    
        /* Reset handler: the following instructions read from the system exception status register
         * to identify the cause of the CPU reset.
         */
    #if 1
        
        if (Flash_ReadU32Array(WORK_PARM, WorkParamBuffer, 48)) {
    
        }else{
            readWorkParmFail();
        }
    
        
        TriModularRedundancy();
    
        boot_order[0] = WorkParamBufferResult[0];
        boot_order[1] = WorkParamBufferResult[1];
        boot_order[2] = WorkParamBufferResult[2];
        boot_order[3] = WorkParamBufferResult[3];
    
    //    ((void (*)(void))WorkParamBufferResult[12])();
    
        Bootloader_CRC_Check();
    
    #endif
    
    
    /* USER CODE BEGIN (28) */
    /* USER CODE END */
    
    }

    The linked files are listed below:

    The jump program also uses Customer_OTP_Write_Test_LC4357_B.rar

    Burn your own program to 0xF0200000 via uniflash.

    The result is that it goes into a dataEntry exception, is there a problem somewhere?

  • Commenting out the above results in the same dataEntry exception.

  • After debugging, I found that all three of the above statements raise exceptions.

    1. crc32 checksum function

    /************** Arun Tried Sw Code -4 (CRC32 for TMS570) ***************************/
    uint32_t SwCRC32(uint32_t crc, const unsigned char *buf, int len)
    {
        static uint32_t table[256];
        static int have_table = 0;
        uint32_t rem;
        uint8_t octet;
        int i, j;
        const unsigned char *p, *q;
    
        /* This check is not thread safe; there is no mutex. */
        if (have_table == 0) {
            /* Calculate CRC table. */
            for (i = 0; i < 256; i++)
            {
                rem = i;  /* remainder from polynomial division */
                for (j = 0; j < 8; j++)
                {
                    if (rem & 1)
                    {
                        rem >>= 1;
                        rem ^= 0xedb88320;
                    } else
                        rem >>= 1;
                }
                table[i] = rem;
            }
            have_table = 1;
        }
    
        crc = ~crc;
        q = buf + len;
        for (p = buf; p < q; p++) {
            octet = *p;  /* Cast to unsigned octet. */
            crc = (crc >> 8) ^ table[(crc & 0xff) ^ octet];
    //        crc = (crc >> 8) ^ table[(crc ^ octet)& 0xff];    //Arun modified
        }
        return ~crc;
    }

    2. jump action

    3. return

    What causes this and is there a way to fix it?

  • After actual extensive testing, it was found that turning off the MPU was not feasible, and that the MPU needed to be turned on and _mpuInit_ had to be present for the jump to work properly, and the problem has now been successfully resolved. Thank you very much for your help, it really helped me a lot, you are really awesome.

    Thank you for your support!

    Have a nice life.