Other Parts Discussed in Thread: ASH
Hi, Gurus
I'm working on firmware upgrade using I2C protocol, now I want to run new code after upgrade progress.
I want to know the proper method to switch between two different individual CCS project for firmware upgrade.
Assume I have two CCS projects:
"Main_App" contain code selection logic, I2C upgrade kernel and old application code located at flash address 0x81000.
"New_App" for new application which only blink LED located at flash address 0x88000.
Flash section15 0x8F000 is for EEPROM-liked storage for some firmware information data.
* F280025C only has one bank of flash, 0x80000 to 0x8FFFFF
After software reset (using SysCtl_resetDevice()), the XRS pin geting low for 45uS, and can not boot to the new application.
So I found the related post: TMS320F28388D: Device fails to boot up after firmware upgrade. - C2000 microcontrollers forum - C2000︎ microcontrollers - TI E2E support forums
But it only mention its the flashAPI issue,I think it's not my case.
Because even I build the New_App using CCS, and uploaded it in section8-15 to ensure there is not flash problem during my upgrade transmission,
I try to jump to new code using my code selection logic in Main_App, it has the same behavior as below:
CH1: XRS CH2: GPIO5
The code selection logic I build is to read the flash address 0x8F0000 back and check is the flash bank has been modified.
I use simple asm(" LB 0x88000") to do the job.
Here is the code in 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; }
When received all New_App package, the system go into REBOOT case and do the software reset.
But after that, it can not go into New_App properly.
For cmd file of 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. //=========================================================================== */
For cmd file of 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. //=========================================================================== */
Also, I try to reverse the role between Main_App and New_App:
I first program the Main_App at 0x81000 and program New_App at 0x88000 using CCS, then after specific condition (such as counter = 0),
and run asm(" LB 0x80000") to jump to Main_App, and it works fine, the device can run all Main_App function.
I remember I asked about the implemention of new entry point setup: TMS320F280025C: Live Firmware Upgrade without using OTP memory - C2000 microcontrollers forum - C2000︎ microcontrollers - TI E2E support forums
But I'm not sure is that only work when there is one project in the flash menory.
I survay the forum and find f28002x_codestartbranch.asm and boot28.c plays important role when device is booting, but not really understanding the mechanism and where to modify.
Conclusion, the question is:
1. How to switch the different, independent application in one flash bank but different address?
2. What is the detailed device boot sequence for firmware developmenting view?
Thanks for the support!
Best Reguards.