主题中讨论的其他器件: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.固件开发的详细器件启动顺序是什么?
感谢您的支持!
最好的酒店