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.

[参考译文] TMS320F280025C:在不同的应用程序代码之间正确切换

Guru**** 2408100 points


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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1217077/tms320f280025c-properly-switch-between-different-application-code

器件型号:TMS320F280025C
主题中讨论的其他器件:ash

您好、Gurus

我正在使用 I2C 协议进行固件升级、现在我想在升级后运行新代码。

我想知道在两个不同的单独 CCS 工程之间切换以进行固件升级的正确方法。

假设 我有两个 CCS 项目:

" MAIN_App "包含代码选择逻辑、I2C 升级内核和位于闪存地址0x81000处的旧应用程序代码。

" New_App 的新应用程序、它仅使闪存地址0x88000处的 LED 闪烁。

Flash section15 0x8F000用于类似 EEPROM 的存储、以存储一些固件信息数据。

* F280025C 只有一组闪存、0x80000至0x800FFFFF

软件复位后(使用 SYSCTL_resetDevice ()),XRS 引脚将拉低45us,无法引导至新的应用。

那么、我找到了相关文章: TMS320F28388D:器件在固件升级后无法启动。 - C2000微控制器论坛- C2000 ︎ 微控制器- TI E2E 支持论坛

但它只提到闪存 API 问题,我想不是我的情况。

因为即使我 使用 CCS 编译 New_App、并在第8-15节中上传、以确保在升级传输期间不会出现闪存问题、

我尝试在 Main_App 中使用我的代码选择逻辑跳转到新代码、其行为与以下操作相同:

CH1:XRS CH2:GPIO5

代码选择逻辑 I BUILD 用于读回闪存地址0x8F0000并检查闪存存储体是否已修改。

我使用简单 asm ("  LB 0x88000")来 完成这项工作。

这是中的代码 MAIN_App

const uint32_t fw_branch_addr   = 0x08F000;     // FW status flash address


void main(void)
{
#ifdef mov2ram
    memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (size_t)&RamfuncsLoadSize);
    memcpy(&IQfuncsRunStart, &IQfuncsLoadStart, (size_t)&IQfuncsLoadSize);
    InitFlash();
    InitFlashAPI();
#endif

    DeviceInit();               // Initialize device, including CPUTimer
    PeripheralInit();           // Initialize MCU peripheral

    App_branch();               // If new firmware installed, jump to new firmware

    VarInit();                  // Initialize variables
    Init_I2C();                 // Initialize I2C protocol and GPIO
    Init_SPI();                 // Initialize SPI protocol and GPIO

    while(1)
    {
            switch (system_status){
            case(NORMAL):                   // Normal operation
                // Do some normal thing
                break;

            case(UPGRADING):                // Upgrade operation
                // Do some upgrade thing
                break;

            case(ERROR):                    // System error operation
                break;

            case(REBOOT):                   // Software reset the device
                DELAY_US(1000);
                SysCtl_resetDevice();
                break;
    }
}

// @brief   branch to 0x88000 if firmware status is MODIFIED

void App_branch(void){
    if(check_fw_branch() == MODIFIED)
        asm("  LB 0x088000");
}

/* @brief   check firmware status from flash to determine entry point
 * @param   none
 * @return  FIRMWARE_STATUS  MODIFIED: told Appbranch() jump to updated firmware (0x088000)
 *          FIRMWARE_STATUS  ORIGINAL: told Appbranch() not jump
 */
uint16_t check_fw_branch(void){
    uint16_t fw_branch = ORIGINAL;
    uint16_t flash_data;
    flash_data = *((uint16_t*)fw_branch_addr);
    if(flash_data != fw_branch)
        return MODIFIED;
    else
        return ORIGINAL;
}

接收全部内容 New_App  软件包中、系统将进入重新启动情况并执行软件重置。

但在这之后、它无法进入 New_App 正确配置。

的 cmd 文件的命令文件 MAIN_App

MEMORY
{
   BOOT_RSVD		: origin = 0x00000002, length = 0x00000126
   RAMM0           	: origin = 0x00000128, length = 0x000002D8
   RAMM1            : origin = 0x00000400, length = 0x000003F8     /* on-chip RAM block M1 */

   RAMLS4567        : origin = 0x0000A000, length = 0x00002000
   RAMGS0           : origin = 0x0000C000, length = 0x00001000
   RESET            : origin = 0x003FFFC0, length = 0x00000002

   BOOTROM          : origin = 0x003F0000, length = 0x00008000
   BOOTROM_EXT      : origin = 0x003F8000, length = 0x00007FC0

#ifdef __TI_COMPILER_VERSION__
   #if __TI_COMPILER_VERSION__ >= 20012000
GROUP {      /* GROUP memory ranges for crc/checksum of entire flash */
   #endif
#endif

   BEGIN           	: origin = 0x080000, length = 0x000002	// default flash entry point
   /* Flash sectors */
   /* BANK 0 */
   FLASH_BANK0_SEC0  : origin = 0x080002, length = 0x000FFE	/* on-chip Flash */
   FLASH_BANK0_SEC1  : origin = 0x081000, length = 0x001000	/* on-chip Flash */
   FLASH_BANK0_SEC2  : origin = 0x082000, length = 0x001000	/* on-chip Flash */
   FLASH_BANK0_SEC3  : origin = 0x083000, length = 0x001000	/* on-chip Flash */
   FLASH_BANK0_SEC4  : origin = 0x084000, length = 0x001000	/* on-chip Flash */
   FLASH_BANK0_SEC5  : origin = 0x085000, length = 0x001000	/* on-chip Flash */
   FLASH_BANK0_SEC6  : origin = 0x086000, length = 0x001000	/* on-chip Flash */
   FLASH_BANK0_SEC7  : origin = 0x087000, length = 0x001000	/* on-chip Flash */
   FLASH_BANK0_SEC8  : origin = 0x088000, length = 0x001000	/* on-chip Flash */
   FLASH_BANK0_SEC9  : origin = 0x089000, length = 0x001000	/* on-chip Flash */
   FLASH_BANK0_SEC10 : origin = 0x08A000, length = 0x001000	/* on-chip Flash */
   FLASH_BANK0_SEC11 : origin = 0x08B000, length = 0x001000	/* on-chip Flash */
   FLASH_BANK0_SEC12 : origin = 0x08C000, length = 0x001000	/* on-chip Flash */
   FLASH_BANK0_SEC13 : origin = 0x08D000, length = 0x001000	/* on-chip Flash */
   FLASH_BANK0_SEC14 : origin = 0x08E000, length = 0x001000	/* on-chip Flash */
   FW_STATUS         : origin = 0x08F000, length = 0x000008 /* on-chip Flash */
   FW_NUMBER		 : origin = 0x08F008, length = 0x000008 /* on-chip Flash */
   DEVICE_NUMBER     : origin = 0x08F010, length = 0x000018 /* on-chip Flash */
   FLASH_DATA1		 : origin = 0x08F028, length = 0x000040 /* on-chip Flash */
   FLASH_BANK0_SEC15 : origin = 0x08F068, length = 0x000F88	/* on-chip Flash */

   FLASH_BANK0_SEC15_DO_NOT_USE     : origin = 0x08FFF0, length = 0x000010  /* Reserve and do not use for code as per the errata advisory "Memory: Prefetching Beyond Valid Memory" */

#ifdef __TI_COMPILER_VERSION__
  #if __TI_COMPILER_VERSION__ >= 20012000
}  crc(_table_name, algorithm=C28_CHECKSUM_16)
  #endif
#endif

}


SECTIONS
{
   codestart        : > BEGIN, ALIGN(8)
   .text            : >> FLASH_BANK0_SEC2 | FLASH_BANK0_SEC3 | FLASH_BANK0_SEC4,   ALIGN(8)
   .cinit           : > FLASH_BANK0_SEC1, ALIGN(8)//FLASH_BANK0_SEC1,  ALIGN(8)
   .switch          : > FLASH_BANK0_SEC1,  ALIGN(8)
   .reset           : > RESET,                  TYPE = DSECT /* not used, */

   .stack           : > RAMM0

   .init_array      : > FLASH_BANK0_SEC1, ALIGN(8)//FLASH_BANK0_SEC1,  ALIGN(8)
   .bss             : > RAMLS4567
   .bss:output      : > RAMLS4567
   .bss:cio         : > RAMGS0
   .const           : > FLASH_BANK0_SEC1,  ALIGN(8)
   .data            : > RAMLS4567
   .sysmem          : > RAMLS4567

    ramgs0 : > RAMGS0
	DataBufferSection :> RAMGS0, ALIGN(8)

    retain			: > FLASH_BANK0_SEC15,  ALIGN(8)	// storage const variables
	firmware_status : > FW_STATUS
	firmware_number : > FW_NUMBER
	device_number	: > DEVICE_NUMBER
	flash_data	 	: > FLASH_DATA1
    /*  Allocate IQ math areas: */
//   IQmath           : > RAMLS4567
   IQmath            : LOAD = FLASH_BANK0_SEC1,
   					   RUN = RAMGS0,
   					   LOAD_START(IQfuncsLoadStart),
   					   LOAD_END(_IQfuncsLoadEnd),
   					   LOAD_SIZE(IQfuncsLoadSize),
   					   RUN_START(IQfuncsRunStart),
   					   ALIGN(8)
   IQmathTables     : > RAMLS4567

  .TI.ramfunc      : LOAD = FLASH_BANK0_SEC1,
                  RUN = RAMGS0,
                  LOAD_START(RamfuncsLoadStart),
                  LOAD_SIZE(RamfuncsLoadSize),
                  LOAD_END(RamfuncsLoadEnd),
                  RUN_START(RamfuncsRunStart),
                  RUN_SIZE(RamfuncsRunSize),
                  RUN_END(RamfuncsRunEnd),
                  ALIGN(8)

   /* crc/checksum section configured as COPY section to avoid including in executable */
   .TI.memcrc          : type = COPY

}
/*
//===========================================================================
// End of file.
//===========================================================================
*/

的 cmd 文件的命令文件 New_App

MEMORY
{
   BOOT_RSVD		: origin = 0x00000002, length = 0x00000126
   RAMM0           	: origin = 0x00000128, length = 0x000002D8
   RAMM1            : origin = 0x00000400, length = 0x000003F8     /* on-chip RAM block M1 */
   RAMLS4567        : origin = 0x0000A000, length = 0x00002000
   RAMGS0           : origin = 0x0000C000, length = 0x00001000
   RESET            : origin = 0x003FFFC0, length = 0x00000002


   BOOTROM          : origin = 0x003F0000, length = 0x00008000
   BOOTROM_EXT      : origin = 0x003F8000, length = 0x00007FC0
   
#ifdef __TI_COMPILER_VERSION__
   #if __TI_COMPILER_VERSION__ >= 20012000
GROUP {      /* GROUP memory ranges for crc/checksum of entire flash */
   #endif
#endif   
   BEGIN           	: origin = 0x088000, length = 0x000002
   FLASH_BANK0_SEC0  : origin = 0x080000, length = 0x001000	/* on-chip Flash */
   FLASH_BANK0_SEC1  : origin = 0x081000, length = 0x001000	/* on-chip Flash */
   FLASH_BANK0_SEC2  : origin = 0x082000, length = 0x001000	/* on-chip Flash */
   FLASH_BANK0_SEC3  : origin = 0x083000, length = 0x001000	/* on-chip Flash */
   FLASH_BANK0_SEC4  : origin = 0x084000, length = 0x001000	/* on-chip Flash */
   FLASH_BANK0_SEC5  : origin = 0x085000, length = 0x001000	/* on-chip Flash */
   FLASH_BANK0_SEC6  : origin = 0x086000, length = 0x001000	/* on-chip Flash */
   FLASH_BANK0_SEC7  : origin = 0x087000, length = 0x001000	/* on-chip Flash */
   FLASH_BANK0_SEC8  : origin = 0x088002, length = 0x000FFE	/* on-chip Flash */
   FLASH_BANK0_SEC9  : origin = 0x089000, length = 0x001000	/* on-chip Flash */
   FLASH_BANK0_SEC10 : origin = 0x08A000, length = 0x001000	/* on-chip Flash */
   FLASH_BANK0_SEC11 : origin = 0x08B000, length = 0x001000	/* on-chip Flash */
   FLASH_BANK0_SEC12 : origin = 0x08C000, length = 0x001000	/* on-chip Flash */
   FLASH_BANK0_SEC13 : origin = 0x08D000, length = 0x001000	/* on-chip Flash */
   FLASH_BANK0_SEC14 : origin = 0x08E000, length = 0x001000	/* on-chip Flash */
   FLASH_BANK0_SEC15 : origin = 0x08F000, length = 0x000FF0	/* on-chip Flash */
   FLASH_BANK0_SEC15_DO_NOT_USE     : origin = 0x08FFF0, length = 0x000010  /* Reserve and do not use for code as per the errata advisory "Memory: Prefetching Beyond Valid Memory" */
#ifdef __TI_COMPILER_VERSION__
  #if __TI_COMPILER_VERSION__ >= 20012000
}  crc(_ccs_flash_checksum, algorithm=C28_CHECKSUM_16)
  #endif
#endif

}


SECTIONS
{
   codestart        : > BEGIN, ALIGN(8)
   .text            : >> FLASH_BANK0_SEC9 | FLASH_BANK0_SEC10 | FLASH_BANK0_SEC11,   ALIGN(8)
   .cinit           : > FLASH_BANK0_SEC8,  ALIGN(8)
   .switch          : > FLASH_BANK0_SEC8,  ALIGN(8)
   .reset           : > RESET,                  TYPE = DSECT /* not used, */

   .stack           : > RAMM1

   .init_array      : > FLASH_BANK0_SEC8,  ALIGN(8)
   .bss             : > RAMLS4567
   .bss:output      : > RAMLS4567
   .bss:cio         : > RAMGS0
   .const           : > FLASH_BANK0_SEC8,  ALIGN(8)
   .data            : > RAMLS4567
   .sysmem          : > RAMLS4567

    ramgs0 : > RAMGS0

    /*  Allocate IQ math areas: */
//   IQmath           : > RAMLS4567
   IQmath            : LOAD = FLASH_BANK0_SEC8,
   					   RUN = RAMGS0,
   					   LOAD_START(IQfuncsLoadStart),
   					   LOAD_END(_IQfuncsLoadEnd),
   					   LOAD_SIZE(IQfuncsLoadSize),
   					   RUN_START(IQfuncsRunStart),
   					   ALIGN(8)
   IQmathTables     : > RAMLS4567

  .TI.ramfunc      : LOAD = FLASH_BANK0_SEC8,
                  RUN = RAMGS0,
                  LOAD_START(RamfuncsLoadStart),
                  LOAD_SIZE(RamfuncsLoadSize),
                  LOAD_END(RamfuncsLoadEnd),
                  RUN_START(RamfuncsRunStart),
                  RUN_SIZE(RamfuncsRunSize),
                  RUN_END(RamfuncsRunEnd),
                  ALIGN(8)

   /* crc/checksum section configured as COPY section to avoid including in executable */
   .TI.memcrc          : type = COPY

}
/*
//===========================================================================
// End of file.
//===========================================================================
*/

此外、我尝试颠倒之间的角色 MAIN_App New_App

我首先对进行编程 MAIN_App 位于0x81000处并编程 New_App 在0x88000处使用 CCS、然后在特定条件之后(例如、COUNTER = 0)、

并运行 asm ("  LB 0x80000")以跳转到 Main_App、  它工作正常、器件可以运行所有功能 MAIN_App 停止。

我记得我问到了有关实施新入口点设置的问题: TMS320F280025C:不使用 OTP 存储器即可进行实时固件升级- C2000微控制器论坛- C2000 ︎ 微控制器- TI E2E 支持论坛

但我不确定只有在闪存菜单中有一个项目时才起作用。

我访问 论坛后发现  f28002x_codestartbranch.asm boot28.c 在器件启动时发挥着重要作用、但我并不真正了解该机制和修改位置。

结论、问题是:

1.如何在一个闪存存储体中切换不同的独立应用程序,但地址不同?

2.固件开发的详细器件启动顺序是什么?

感谢您的支持!

最好的酒店

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

    尊敬的春林:

    感谢您的提问。 下面是可能需要考虑的一些因素:

    1) 1)这听起来类似于 BANK0_LDFU 配置、在存在新固件升级时、将检查存储体位置的修订值以查看其是否已更改。 我建议在此处查看相关文档 、了解在 C2000 MCU 上进行带有器件复位的实时固件更新(修订版 A)(TI.com)

    2)固件开发的详细设备启动顺序通常可以在 C2000微控制器的串行闪存编程中找到(修订版 E)( TI.com ) 。 您还可以查看此前发布的 LDFU 指南、了解此器件的固件更新是如何发生的。 flash_kernel_ex3_ldfu.c 的文本文件详细说明了在检查修订版本以进行分支时会发生什么。

    此致、

    查理

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

    您好、Charles

    感谢您的快速回复。

     再次演示 LDFU 示例(fash_kernel_ex3_ldfu.c)、以及 在 C2000 MCU 上进行带有器件复位的实时固件更新(修订版 A)(TI.com)

    我有一些问题需要澄清:

    1.为什么 Device_init()会运行两次?

    在演示项目中、bankSelect 函数(第994行)对器件进行两次初始化、首先是在开始时、这是合理的、因为它需要完成才能使 MCU 正常工作、对于接收到的 SCI 消息或其他东西。

    但是、当 B0_KEY 值与 KEY 值(行1207)不匹配时、它第二次初始化器件时、为什么这样? 这与 PLL 或其他外设是否相关?

    2.位于0x8EFF0的项目与位于0x08003B 的项目是否完全不同?

    由于我使用的 F280025C 只有一个组闪存、因此如果我构建两个不同的工程、即使我将 code_start 设置到不同的地址、该器件也应该在内置 bootROM 中选择闪存引导后从0x80000开始。

    我注意到在演示代码中 bankSelect () 被设置为强制位于0x80000处, 0x80000处的数据会与两个不同的项目冲突吗? 或者不同项目应该在0x80000处具有相同的代码

    我的 情况可能与加载新固件 Fom SCI 的演示项目略有不同、但我只能使用闪存引导启动程序。  

    我使用由 C2000Hex 实用程序生成的 intel-hex 格式的.hex 文件、然后使用 Linux 通过 I2C 将数据包传输到我的器件。

    正如我所知、该文件包含的是写入器件闪存中的固件的准确内容、因此我可以 在编程到闪存中后轻松执行数据。

    感谢您的支持、

    最好的酒店

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

    尊敬的春林:

    快速回答您的问题:

    1)第一个 device_init()用于实现闪存内核到 RAM 的复制。 即使没有新的固件更新、器件也能做好准备、以备不时之需。 BANK_SELECT 函数用作 主要器件逻辑、因此在器件复位时、该函数将始终检查固件更新、并需要初始化器件。 第二个 device_init()是检查每个可能的组是否具有修订值。 对于 F280025C 情况、只有一个存储体。

    2) 2)是的、0x8EFF0是备用闪存入口点之一、因此例如、如果复位时的器件不需要更新、它将分支到用户应用程序代码所在的位置。 本例中选择了0x8EFF0、因为它是设计的入口点、但您也可以选择另一个入口点、例如0x84000、需要对其进行配置。 LDFU 应用手册中的图3-1显示了组选择逻辑、SCI 内核和闪存 API 将占据 Bank0的顶部空间。 添加到组中的不同用户应用程序应避免使用与组选择逻辑/SCI 内核/闪存 API 相同的闪存区域。 在本例中、可用空间从0x82000开始。

    此致、

    查理

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

    感谢您的回复、

    它是演示文件的 cleare 答案。

    我发现演示项目的属性将链接器的入口点设置 为 bankSelect (properties>CCS build>C2000 linker>Symbol Management>--entrypoint)

    我参考 TMS320C28x 汇编语言工具 v22.6.0.LTS 用户指南(修订版 Y)(TI.com) pp.190、入口点部分、其中表示我可以  为入口点分配四个值之一。

    Question:

    1.我想了解更多关于如何设置入口点和固件更新 senario 的信息,

    另外还有  flash_kernel_ex3_codestartbranch.asm 的详细说明、该说明在应用手册中没有提到、但在整个分支中起着重要作用。

    2. 针对原始问题"固件开发的详细器件启动顺序是什么视图?" 我的意思是一般项目启动顺序、而不是出于固件升级的目的、是否有任何文档参考?

    感谢您的支持、

    最好的酒店

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

    尊敬的春林:

    将您的问题转给 LDFU 专家以了解更多详细信息。 将能够在明天尽快作出响应。

    谢谢。

    查理

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

    Jun-Lin、

    我阅读了您的要求和问题、并了解您正在尝试实施的方案。

    我使用的是 Main_App 和 New_App 是独立的项目,每个项目都有自己的 main()。 是这样吗?

    如果是、则这些工程中的每个工程都应包含 codestartbranch.asm。 因为它包含 CODE_START (映射到 codestart 段)、CODE_START 段是退出引导 ROM 代码后执行的第一个代码。 因此、如果您处于闪存引导模式、默认的闪存入口点(0x80000)是您希望映射 codestart 的位置。 这就是你所做的(查看你的 main_app 的链接器.cmd 文件)。 从这里调用 cint00 (编译器的 RTS 库提供的 C 初始化例程),它调用 main ()。 同样,当您从 main_app 分支到 New_app 时,入口点是 New_app (0x88000)的 codestart,因此您也需要这个项目的 codestartbranch,这样它就可以运行 cint00并调用 New_app 的 main ()。

    需要考虑的另一点是、在 Main_app 和 New_app 之间、RAM 内存重叠。 如果存在重叠、那么从 Main_app 转至 New_app 时、你可能会丢失一些针对 Main_app 的 RAM 内存环境。 然后、从 New_app 切换回 Main_app 可能无法按预期运行。 不确定这是您正在做的还是需要做的。

    针对您的特定问题:

    "收到全部  New_App  软件包中、系统将进入重新启动情况并执行软件重置。

    但在这之后、它无法进入  New_App  正确"。

    请调试并检查所有存储器位置、例如0x8F000等是否具有所需的值。 使用不带 GEL 文件的目标配置文件连接到目标(以使其不会重置器件)、然后加载工程符号(您希望执行的工程的符号)并检查执行位置。

    谢谢。

    SIRA

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

    谢谢你的答复,我清楚地知道了引导顺序,并解决了问题.

    在本例中、我只需要分支应用程序并进行器件复位、因此可以忽略 RAM 的重叠问题、谢谢提醒!

    虽然我没有使用您提到的调试技术、但我对进行了修改 APP_BRANCH  按如下所示运行、并执行我需要的操作。

    以下是为需要帮助的其他用户提供的代码:

    // You need declare _c_int00 in C enviorement reference 
    // TMS320C28x Assembly Language Tools v21.6.0.LTS pp.242
    extern void _c_int00        (void);     // _c_int00 is defined in compiler's run-time library, declare here for App_branch usage
    
    void main(void){
    ...
    }
    
    /* @brief   branch to 0x88000 if branch_direction is not 0
     * @param   none
     * @return  none
     */
    #pragma CODE_SECTION(App_branch, "codestart");
    void App_branch(void){
        uint16_t branch_direction = 0;
    
        DeviceInit();               // Initialize device, including CPUTimer
    
        // branch_direction branch App to where
        branch_direction = HWREG((uint32_t)fw_branch_addr);
    
        if(branch_direction != 0)
            asm("   LB 0x88000");
        else
            _c_int00();
    }

    要执行该操作、您需要将链接器入口点设置为 APP_BRANCH ,然后将链接器命令文件修改为 put APP_BRANCH 至0x80000、以便器件在复位后执行该操作。

    一开始我想知道如何从 C 语言环境返回到汇编代码、我尝试使用 LCR 但不起作用。

    然后我尝试只需简单的调用_c_int00就可以完成该作业、然后进行正常初始化并执行 MAIN_App

     

    再次感谢您的帮助、 查理 SIRA.

    最好的酒店