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.
工具/软件:
尊敬的 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 程序
我发现区别在哪里、在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_才能使跳转正常工作、并且问题现已成功解决。 谢谢你的帮助,它真的帮了我很多,你真的很棒。
感谢您的支持!
祝生活愉快。