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:CPU 能否跳转到闪存 OTP 区域以寻址和执行程序?

Guru**** 2390755 points
Other Parts Discussed in Thread: HALCOGEN, UNIFLASH

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1499707/tms570lc4357-can-the-cpu-jump-to-the-flash-otp-area-to-address-and-execute-the-program

器件型号:TMS570LC4357
Thread 中讨论的其他器件:HALCOGENUNIFLASH

工具/软件:

尊敬的 TI 团队

由于 MCU 只能从闪存的地址0引导、因此我在地址0写入汇编代码、它可以直接到达其他区域以执行新代码。

我在闪存的 bank0 OTP 区域中烧录了一个新程序、并成功烧录。

然后、我从地址0跳转到组0 OTP 区域(0xF0000010)。

但什么都没有发生。 程序未执行。

闪存存储体0 OTP 区域是否具有执行权限、并且 CPU 可以从该区域寻址并执行?

我们希望将程序放置在闪存 OTP 区域中、因为它足够安全。

此事件比较紧急,请尽快回复,谢谢!

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Sam、

    在 HALCoGen 上、默认情况下、此区域配置为"无执行":

    您可以尝试为此区域配置执行权限吗?

    --
    此致、
    Jagadish。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 gundavarapu:

    非常感谢您的快速答复!

    我已经尝试直接关闭 MPU、是否可以通过这样操作来取消 MPU 保护?

    Tere 是我的链接文件(之后我还在 bank1的 OTP 区域烧录了一个程序):

    /*----------------------------------------------------------------------------*/
    /* 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 */
    /*----------------------------------------------------------------------------*/

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    抱歉、拼写错误、实际上:

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

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我现在打开了 MPU、然后还提供了如下所示的执行权限。

    然后我再次将程序烧录到 bank7、链接文件如下所示。

    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 */
    }

    下面显示了 JUMP 指令。

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

    执行代码会直接导致 undefEntry 异常。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    你好 gundavarapu ,我知道这不是很有礼貌,但我确实有一点紧迫性,我的身边解决这个问题,我能麻烦你迅速回复吗? 您能快速回复吗?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Sam、

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

    您在哪里调用此函数?

    您是否使用任何引导加载程序?

    实际上、在该器件上、代码执行始终从0x00000000开始? 因此、应该有一些来自地址0x00000000的代码来调用闪存存储体7中的代码0xF0200000。 我的意思是、在 bank-7中调用代码需要某种引导加载程序。 因此需要引导加载程序。

    请参考以下 UART 引导加载程序代码:

    (+)[常见问题解答] TMS570LC4357:在 TMS570LC4357上执行 UART 引导加载程序的分步程序-基于 Arm 的微控制器论坛-基于 Arm 的微控制器- TI E2E 支持论坛

    尝试像我在上述示例中给出的那样创建两个工程、并将应用程序保留在0xF0200000而非0x20020处。

    --
    此致、
    Jagadish。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    对不起,也许我不是很好。你是对的,程序必须加载在地址0开始。

    请注意、我现在正在尝试使用组7、但最终是对组0 OTP 区域中的程序进行实验。

    1. 第一程序(0地址)

    开启bank7的执行权限 μ s

    main函数 μ s

    /* 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 程序(bank7地址)

    对于该程序、我通过 uniflash 将.bin 文件烧录到位置0xF0200000。

    有关链接文件的内容、请参阅我之前的回复。

    3、 刻录0地址程序没有擦除内存7、调试结果如下所示。

    您能帮助我分析导致这种情况的原因吗?

    如果 bank7实验通过、我将测试 OTP 区域中的应用程序是否正常工作。

    期待您的答复,谢谢。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    这是一个星期。 您能帮我解决这个问题吗?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Sam、

    请尝试以下两个代码以在闪存的 bank7中执行代码。

    e2e.ti.com/.../8422.LED_5F00_Blinky_5F00_Project_5F00_at0x20020_5F00_Launchpad_5F00_LC4357.zip

    e2e.ti.com/.../2146.UART_5F00_Bootloader_5F00_LC4357_5F00_New.zip

    在这里、我修改了 LED 闪烁应用文件链接器文件以将应用存储在 bank7中。

    按照 CCS 中的以下步骤在 bank7中运行应用。

    1.首先导入并构建应用工程。

    2.构建应用项目后、使用以下选项将其加载到闪存中:

    现在浏览项目:

    点击 OK 将项目加载到闪存中。

    3.使用上述过程加载应用程序后、现在确保为引导加载程序项目的擦除选项配置"Necessary Sectors Only"。

    这很重要、因为我们不应擦除已编程的应用程序、对吧?

    4.执行该操作后、现在可以直接调试引导加载程序工程。

    5.在这里、我修改了引导加载程序以调用0xF0200000中存在的应用。

    因此、一旦运行此引导加载程序、它将直接调用应用程序并执行它。

    6.您可以看到 PC 值;它显示在第7组中正在执行。

    此外、我观察到 LED 闪烁时没有出现任何问题。

    --
    此致、
    Jagadish。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、gundavarapu
    我试图使用你的例行程序,发现这是我的 LED 灯程序的问题,我的第一个程序可以跳到您的8422.LED_LEDat0x20020_Launchpad_LC4357.zip 程序,但我比较了我的 Blinky_Project_灯程序,它似乎没有与你的区别,你能帮助! 可以帮帮我吗?
    我将在下面附上我的代码。

     1.跳转程序

    e2e.ti.com/.../Customer_5F00_OTP_5F00_Write_5F00_Test_5F00_LC4357_5F00_B.rar

    2. LED 程序

    e2e.ti.com/.../TMS_5F00_51_5F00_LED3_5F00_FLASH7.rar

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我发现区别在哪里、在8422.LED_A Blinky_Project_at0x20020_Launchpad_LC4357.zip 工程的 hl_sys_startup.c 文件中、您注释了图中所示的内容、为什么这么做请?

    如果我要编写自己的程序,而不是简单的 LED 程序,这是否是一个问题?

    事实上,正是这些导致我的跳跃到一个 prefetchEntry 异常。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    它也是有趣的注意,LED 灯程序是在 bank0或 bank1,没有必要注释出成功跳到 LED 程序。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    有道理的是、将 LED 程序放置在闪存 BANK0的 OTP 区域后、CPU 也可以跳转到 OTP 区域来执行它、对吗?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Sam、

    如果我要编写自己的程序、而不是一个简单的 LED 程序、这是否是一个问题?

    对于您自己的程序也不是问题、实际上、应用程序不需要这些初始化、因为所有这些初始化都将直接发生在引导加载程序本身中。 因此、最好避免在应用程序中进行这些初始化。

    将 LED 程序放置在 BANK0闪存的 OTP 区域后、CPU 也可以跳转到 OTP 区域进行执行、对吧?

    是的、它也可以在 OTP 部分中执行程序。 唯一需要确保引导加载程序中 OTP 区域部分的跳转地址。

    --
    此致、
    Jagadish。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    由于 OTP 区域的大小为4KB、如果您要将程序刻录到闪存 BANK0的 OTP 区域、则需要修整工程、以下是我的已修整工程的结构(将程序刻录到库7以进行测试):

    功能实现全部包含在 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 */
    
    }

    链接的文件如下所示:

    跳转程序还使用 Customer_OTP___LW_AT__LC4357_B.rar Write_Test_

    通过 uniflash 将您自己的程序刻录到0xF0200000。

    结果是它进入了 DataEntry 异常、某个地方是否有问题?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    注释掉上述内容会导致相同的 DataEntry 异常。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    调试后、我发现上述所有三项陈述都提出了例外。

     1. CRC32校验和函数

    /************** 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.跳转操作

    3.返回

    导致这种情况的原因是什么、是否有办法解决?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    经过实际的广泛测试后、我们发现关闭 MPU 是不可行的、需要打开 MPU 并且必须存在_mpuInit_才能使跳转正常工作、并且问题现已成功解决。 谢谢你的帮助,它真的帮了我很多,你真的很棒。

    感谢您的支持!

    祝生活愉快。