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.

TMS320F280025: Flash擦除时DSP异常进入ESTOP0

Part Number: TMS320F280025

开发二次Bootloader功能,程序在擦除Flash的时候可能会出现崩溃的情况。

项目的cmd文件如下:

MEMORY
{
   
   BOOT_RSVD		   : origin = 0x00000002, length = 0x00000126
   RAMM0           	: origin = 0x00000128, length = 0x000002D8
   RAMM1             : origin = 0x00000400, length = 0x000003F8     /* on-chip RAM block M1 */
// RAMM1_RSVD       : origin = 0x000007F8, length = 0x00000008 /* Reserve and do not use for code as per the errata advisory "Memory: Prefetching Beyond Valid Memory" */

/* RAMLS4           : origin = 0x0000A000, length = 0x00000800
   RAMLS5           : origin = 0x0000A800, length = 0x00000800
   RAMLS6           : origin = 0x0000B000, length = 0x00000800
   RAMLS7           : origin = 0x0000B800, length = 0x00000800
   RAMGS0           : origin = 0x0000C000, length = 0x000007F8
   RAMGS0_RSVD      : origin = 0x0000C7F8, length = 0x00000008 // Reserve and do not use for code as per the errata advisory "Memory: Prefetching Beyond Valid Memory"
   */

   /* Combining all the LS RAMs and GS0 RAM */
   RAML_Data     	   : origin = 0x0000A000, length = 0x00001400
   RAML_Prog         : origin = 0x0000B400, length = 0x00001400




   BOOTROM           : origin = 0x003F0000, length = 0x00008000
   BOOTROM_EXT       : origin = 0x003F8000, length = 0x00007FC0
   RESET             : origin = 0x003FFFC0, length = 0x00000002
   /* Flash sectors */
   BEGIN_BOOT        : origin = 0x080000, length = 0x000008 //,fill = 0xFFFF/* codestart         */
   BOOT_STARTFLAG    : origin = 0x080008, length = 0x000010	//,fill = 0xFFFF/* bootloader flag   */
   BOOT_VERSION      : origin = 0x080018, length = 0x000008	//,fill = 0xFFFF/* bootloader version*/
   BOOT_FLASH        : origin = 0x080020, length = 0x001FD0	//,fill = 0xFFFF/* bootloader code   */
   BOOT_DATETIME     : origin = 0x081FF0, length = 0x000008	//,fill = 0xFFFF/* bootloader finish flag   */
   BOOT_FINISHFLAG   : origin = 0x081FF8, length = 0x000008	//,fill = 0xFFFF/* bootloader finish flag   */

   APP1_BEGIN        : origin = 0x082000, length = 0x000008 ,fill = 0xFFFF/* codestart         */
   APP1_STARTFLAG    : origin = 0x082008, length = 0x000010	,fill = 0xFFFF/* app1 flag   */
   APP1_VERSION      : origin = 0x082018, length = 0x000008	,fill = 0xFFFF/* app1 version*/
   APP1_FLASH        : origin = 0x082020, length = 0x006FD0	,fill = 0xFFFF/* app1 code */
   APP1_DATETIME     : origin = 0x088FF0, length = 0x000008	,fill = 0xFFFF/* app1 code */
   APP1_FINISHFLAG   : origin = 0x088FF8, length = 0x000008	,fill = 0xFFFF/* app1 finish flag   */

   APP2_BEGIN        : origin = 0x089000, length = 0x000008 //,fill = 0xFFFF/* codestart         */
   APP2_STARTFLAG    : origin = 0x089008, length = 0x000010	//,fill = 0xFFFF/* app2 flag   */
   APP2_VERSION      : origin = 0x089018, length = 0x000008	//,fill = 0xFFFF/* app2 version*/
   APP2_FLASH        : origin = 0x089020, length = 0x006FD0	//,fill = 0xFFFF/* app2 code */
   APP2_DATETIME     : origin = 0x08FFF0, length = 0x000008	//,fill = 0xFFFF/* app1 code */
   APP2_FINISHFLAG   : origin = 0x08FFF8, length = 0x000008	//,fill = 0xFFFF/* app2 finish flag   */
//  FLASH_BANK1_RSVD : origin = 0x0008FFF0, length = 0x00000010 /* Reserve and do not use for code as per the errata advisory "Memory: Prefetching Beyond Valid Memory" */   
}

其中bootloader程序占据sector0~sector1

app1占据sector2~sector8

app2占据sector9~sector15

bootloader运行后检查app2是否有有效的程序代码:如果有则擦除app1区域,并将app2代码拷贝至app1区,然后擦除app2区域,最后跳转至app1运行;如果app2没有有效代码,则跳转至app1运行

CCS项目采用TI ROM提供的FlashAPI代码,项目中包含的库文件为:FlashAPI_F28002x_FPU32_ROM_EABI.lib

操作flash的关键代码如下:

//before using any FlashAPI ,Initalize it first
void    Upgrade_Initialize_FlashAPI()
{
    if(isFlashAPI_Initialized)  return;

    Fapi_StatusType oReturnCheck;

    oReturnCheck = Fapi_initializeAPI(F021_CPU0_BASE_ADDRESS, DEVICE_SYSCLK_FREQ/1000000U);
    if(oReturnCheck != Fapi_Status_Success) return;

    oReturnCheck = Fapi_setActiveFlashBank(Fapi_FlashBank0);
    if(oReturnCheck != Fapi_Status_Success) return;

    isFlashAPI_Initialized = true;
}
//Erase single sector at address 
#pragma CODE_SECTION(EraseSingleSector, ".TI.ramfunc");
Fapi_StatusType EraseSingleSector(Uint32 u32StartAddress)
{
    Fapi_StatusType  oReturnCheck;
    Fapi_FlashStatusWordType oFlashStatusWord;

    oReturnCheck = Fapi_issueAsyncCommandWithAddress(Fapi_EraseSector,(Uint32 *)u32StartAddress);
    //wait uintil FSM is done with erase sector operation
    while (Fapi_checkFsmForReady() != Fapi_Status_FsmReady)
    {
        ServiceDog();
    }
    if(oReturnCheck != Fapi_Status_Success) return oReturnCheck;

    //verify the sector is erased
    oReturnCheck = Fapi_doBlankCheck((Uint32 *)u32StartAddress,Sector8KB_u32length,&oFlashStatusWord);

    return oReturnCheck;
}
//Program flash ,must reside in RAM
#pragma CODE_SECTION(Upgrade_ProgramFlash, ".TI.ramfunc");
Fapi_StatusType Upgrade_ProgramFlash(Uint32 u32StartAddress,uint16 *pu16DataBuffer,uint16 u16DataBufferSizeinWords)
{
    Fapi_StatusType  oReturnCheck;
    //Disable intterupt before programming
    DINT;
    oReturnCheck = Fapi_issueProgrammingCommand((Uint32*)u32StartAddress,pu16DataBuffer,u16DataBufferSizeinWords,0,0,Fapi_AutoEccGeneration);
    //wait uintil FSM is done with erase sector operation
    while (Fapi_checkFsmForReady() != Fapi_Status_FsmReady)
    {
        ServiceDog();
    }

//    Fapi_getFsmStatus();
    //Enable intterupt after programming
    EINT;
    return oReturnCheck;
}

//Erase sectors of boot 
bool    Upgrade_EraseSectorOfBoot()
{
    Upgrade_Initialize_FlashAPI();

    if(Fapi_Status_Success != EraseSingleSector(Bzero_Sector0_start)) return false;
    if(Fapi_Status_Success != EraseSingleSector(Bzero_Sector1_start)) return false;
    u16UpgradeFlag  = Upgrade_Flag_Boot;
    u32ProgramStartAddress  = Boot_StartAddress;
    u32ProgramEndAddress    = Boot_EndAddress; 
    u32ProgrammingAddress   = Boot_StartAddress;
    return true;
}
//Erase sectors of App1 
bool    Upgrade_EraseSectorOfApp1()
{
    DINT;
    Upgrade_Initialize_FlashAPI();
    
    if(Fapi_Status_Success != EraseSingleSector((Uint32)Bzero_Sector2_start)) return false;
    if(Fapi_Status_Success != EraseSingleSector((Uint32)Bzero_Sector3_start)) return false;
    if(Fapi_Status_Success != EraseSingleSector((Uint32)Bzero_Sector4_start)) return false;
    if(Fapi_Status_Success != EraseSingleSector((Uint32)Bzero_Sector5_start)) return false;
    if(Fapi_Status_Success != EraseSingleSector((Uint32)Bzero_Sector6_start)) return false;
    if(Fapi_Status_Success != EraseSingleSector((Uint32)Bzero_Sector7_start)) return false;
    if(Fapi_Status_Success != EraseSingleSector((Uint32)Bzero_Sector8_start)) return false;
    u16UpgradeFlag  = Upgrade_Flag_App1;
    u32ProgramStartAddress = App1_StartAddress;
    u32ProgramEndAddress    = App1_EndAddress;
    u32ProgrammingAddress   = App1_StartAddress;

    EINT;
    return true;
}
//Erase sectors of App2 
bool    Upgrade_EraseSectorOfApp2()
{
    DINT;
    Upgrade_Initialize_FlashAPI();
    
    if(Fapi_Status_Success != EraseSingleSector((Uint32)Bzero_Sector9_start)) return false;
    if(Fapi_Status_Success != EraseSingleSector((Uint32)Bzero_Sector10_start)) return false;
    if(Fapi_Status_Success != EraseSingleSector((Uint32)Bzero_Sector11_start)) return false;
    if(Fapi_Status_Success != EraseSingleSector((Uint32)Bzero_Sector12_start)) return false;
    if(Fapi_Status_Success != EraseSingleSector((Uint32)Bzero_Sector13_start)) return false;
    if(Fapi_Status_Success != EraseSingleSector((Uint32)Bzero_Sector14_start)) return false;
    if(Fapi_Status_Success != EraseSingleSector((Uint32)Bzero_Sector15_start)) return false;
    u16UpgradeFlag  = Upgrade_Flag_App2;
    u32ProgramStartAddress = App2_StartAddress;
    u32ProgramEndAddress    = App2_EndAddress;
    u32ProgrammingAddress   = App2_StartAddress;

    EINT;
    return true;
}
//if App2 has valid app code,erase app1 sectors,copy app2 data to app1 data
void    Upgrade_CheckUpgrade()
{
    Uint32 u32Address_Read;
    Uint32 u32Address_Write;

    if(IsApp2_Valid())
    {
        //clear app1 data code
        Upgrade_EraseSectorOfApp1();

        //copy app2 to app1
        u32Address_Read     = App2_StartAddress;
        u32Address_Write    = App1_StartAddress;
        while(u32Address_Read < App2_EndAddress)
        {
            Upgrade_ProgramFlash(u32Address_Write,(Uint16 *)u32Address_Read,8);
            u32Address_Read     += 8;
            u32Address_Write    += 8;
        }

        //clear app2 data code
        Upgrade_EraseSectorOfApp2();
    }
}

调用 Upgrade_EraseSectorOfApp2()函数,擦除Sector9后,在擦除sector10时程序进入ESTOP0

程序跟踪可以看到,调用的Fapi_issueAsynCommand 函数位于 0x3f8ec8

请问擦除后崩溃的原因可能是什么?

还有,如何将TI ROM中的FlashAPI代码放在RAM中执行?

  • 补充一下:

    擦除FLASH时,有时候擦除第2个Sector时崩溃,有时擦除第3个Sector时崩溃

    同样的代码,之前还有全部擦除成功的情况。

  • 还补充一下,当前测试出问题的工程是实际工程项目的代码加入了bootloader功能。

    如果用另外一个简单的测试App程序,则擦除过程没有问题。

    2个app工程所用到的擦除代码都是一模一样的,2个App代码均运行于App1区域