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.

F28377Sf Flash_api烧写程序问题

本人刚接触dsp不久,需要弄一个F28377S的在线升级程序,根据例程和别人的帖子,弄了一个USB模拟UART升级的BootLoader。

BootLoader的功能是使用USB模拟UART与上位机通信,判断是否要升级,若升级就接收hex文件写入指定分区,否则跳转地址启动用户app。

现在的情况是如果用户app是由ccs指定分区烧写的,则上电后BootLoader可以跳转到用户app。但是如果用户app是由BootLoader烧写进去的,就没法跳转,只会不停重启BootLoader。

用户app是由ccs编译自动生成的hex文件,配置如下

BootLoader烧写进去后,通过ccs的Memory Browser查看指定分区的数据,发现和用ccs烧写进去的一样,然而就是没法跳转过去,下面是部分烧写代码和跳转代码,希望有人可以帮帮我。

//**************************************
//             CallFlashAPI
//**************************************

//the flash buffer and data length
uint8_t recBuffer[64];
#pragma DATA_SECTION(pbuffer , "BufferDataSection");
uint16_t pbuffer[31];
volatile uint16 DataLen;
uint16 offset = 0;

#define ENTRYADDR 0x88000
#pragma CODE_SECTION(Example_CallFlashAPI, "ramfuncs");
void Example_CallFlashAPI(void)
{
    uint32 u32Index = 0;
    uint16 i = 0;
    uint16 pbufferLen = 0;
    Fapi_StatusType oReturnCheck;
    volatile Fapi_FlashStatusType oFlashStatus;
    Fapi_FlashStatusWordType oFlashStatusWord;

    DINT;
    DataLen = (uint16)buffer[1];
    EALLOW;
    for(i=2; i<=DataLen; i += 2, pbufferLen++)
        pbuffer[pbufferLen] = (recBuffer[i+1] << 8) | recBuffer[i];
    //
    //Give pump ownership to FMC0
    //
    PUMPREQUEST = 0x5A5A0002;
    //
    // Erase Sector C
    //
    if(!EraseStatus)
    {



        EALLOW;
        Flash0EccRegs.ECC_ENABLE.bit.ENABLE = 0xA;
        EDIS;

        //
        // This function is required to initialize the Flash API based on System
        // frequency before any other Flash API operation can be performed
        // Note that the FMC0 register base address is passed as the parameter
        //
        oReturnCheck = Fapi_initializeAPI(F021_CPU0_W0_BASE_ADDRESS, 194);

        if(oReturnCheck != Fapi_Status_Success)
        {
            //
            // Check Flash API documentation for possible errors
            //
            Example_Error(oReturnCheck);
        }

        //
        // Fapi_setActiveFlashBank function sets the Flash bank0 and FMC0 for
        // further Flash operations to be performed on the bank0.
        // Note that the parameter passed is Fapi_FlashBank0 since FMC0 register
        // base address is passed to Fapi_initializeAPI()
        //
        oReturnCheck = Fapi_setActiveFlashBank(Fapi_FlashBank0);
        if(oReturnCheck != Fapi_Status_Success)
        {
            //
            // Check Flash API documentation for possible errors
            //
            Example_Error(oReturnCheck);
        }

        oReturnCheck = Fapi_issueAsyncCommandWithAddress(Fapi_EraseSector,
                                                (uint32 *)ENTRYADDR);
        //
        // Wait until FSM is done with erase sector operation
        //
        while(Fapi_checkFsmForReady() != Fapi_Status_FsmReady);

        //
        // Verify that SectorL is erased.  The Erase step itself does a
        // verify as it goes.  This verify is a 2nd verification that can be done.
        //
        oReturnCheck = Fapi_doBlankCheck((uint32 *)ENTRYADDR,
                                         Bzero_16KSector_u32length,
                                         &oFlashStatusWord);

        if(oReturnCheck != Fapi_Status_Success)
        {
            //
            // Check Flash API documentation for possible errors
            // If Erase command fails, use Fapi_getFsmStatus() function to get the
            // FMSTAT register contents to see if any of the EV bit, ESUSP bit,
            // CSTAT bit or VOLTSTAT bit is set (Refer to API documentation for
            // more details)
            //
            Example_Error(oReturnCheck);
        }
    }

    EraseStatus++;

    //
    // A data buffer of max 8 words can be supplied to the program function.
    // Each word is programmed until the whole buffer is programmed or a
    // problem is found. However to program a buffer that has more than 8
    // words, program function can be called in a loop to program 8 words for
    // each loop iteration until the whole buffer is programmed
    //

    //
    // Example: Program 0xFF bytes in Flash Sector C along with auto-
    // generated ECC
    //

    //
    // In this case just fill a buffer with data to program into the flash.
    //


    for(i=0, u32Index = ENTRYADDR + offset;
        (u32Index < (ENTRYADDR + offset + pbufferLen)) &&
        (oReturnCheck == Fapi_Status_Success); i+= 1, u32Index+= 1)
    {

        oReturnCheck = Fapi_issueProgrammingCommand((uint32 *)u32Index,pbuffer + i,
                                                    1,0,0,
                                                    Fapi_DataOnly);

        while(Fapi_checkFsmForReady() == Fapi_Status_FsmBusy);

        if(oReturnCheck != Fapi_Status_Success)
        {
            //
            // Check Flash API documentation for possible errors
            //
            Example_Error(oReturnCheck);
        }

        //
        // Read FMSTAT register contents to know the status of FSM after
        // program command for any debug
        //
        oFlashStatus = Fapi_getFsmStatus();

        //
        // Verify the values programmed.  The Program step itself does a verify
        // as it goes.  This verify is a 2nd verification that can be done.
        //
        //oReturnCheck = Fapi_doVerify((uint32 *)u32Index,4,Buffer32+(i/2),
        //                             &oFlashStatusWord);

        if(oReturnCheck != Fapi_Status_Success)
        {
            //
            // Check Flash API documentation for possible errors
            //
            Example_Error(oReturnCheck);
        }
    }


    //PUMPREQUEST = 0x5A5A0000;
    offset += pbufferLen;
    // Leave control over flash pump
    ReleaseFlashPump();
    EDIS;
    EINT;
}
//*********************
//    jump to app
//*********************
static void (*APPEntry)(void);

APPEntry = (void (*)(void))(ENTRYADDR);

ESTOP0;

(*APPEntry)();

  • 可能也就CCS多了一个校验 你仔细对比一下 数据
  • 用ccs烧写用户app进去后,再用ccs的memory browser直接从flash里面提取那一块分区的数据出来,再次写入,还是无法跳转,目前也找不到ccs的校验。请问还有其他的可能性吗?
  • 还有一个问题Fapi_AutoEccGeneration模式烧写的原理是怎样的?为什么每四个十六位只能写入一个?
  • 22. How can I calculate ECC to program?

    Answer. When using Flash API in the application to program Flash, you can pass “Fapi_AutoECCGeneration” as the programming mode parameter for the program function. When this mode is used, API calculates ECC for the user-provided address (aligned on a 64-bit memory boundary) and the corresponding 64-bit data. API programs the calculated ECC along with the main array data when using this mode. If not for a program operation, user application can also calculate ECC using the Fapi_calculateEcc() function provided in the Flash API library. Note that this function uses the SECDED hardware logic in the FMC to calculate the ECC. Note that this function needs a left-shifted (by 1 bit position) address when used for C28x in F28M35x, F28M36x, F2837xD, F2837xS and F2807x devices. For the rest of the devices, API takes care of left-shifting the address before calculating the ECC.

    processors.wiki.ti.com/.../Flash_FAQ
  • 啊!!!还是不会用,oReturnCheck = Fapi_issueProgrammingCommand((uint32 *)u32Index,pbuffer + i,
    8,0,1,
    Fapi_AutoEccGeneration);
    这个函数,一写就错误。
  • 问题已解决:

            第一,由于使用DataOnly的方式写入的,所以BootLoader的main函数里面需要关掉ECC校验,跳转程序也需要在关闭ECC后再调用。即

                                

    EALLOW;
    
    Flash0EccRegs.ECC_ENABLE.bit.ENABLE = 0x0;
    
    EDIS;

            第二,如果想用Fapi_AutoEccGeneration的方式写入,则每次需要写入64位数据,因为每产生一个ECC校验需要校验64位数据,同时,F2837X中flash的16位为一个字的,所以需要写入4个字,即

                                 

         for(i=0, u32Index = ENTRYADDR + targetAddr;
            (u32Index < (ENTRYADDR + targetAddr + pbufferLen)) &&
            (oReturnCheck == Fapi_Status_Success); i += 4, u32Index += 4)
        {
            oReturnCheck = Fapi_issueProgrammingCommand((uint32 *)u32Index,pbuffer + i,
                                                        4,0,0,
                                                        Fapi_AutoEccGeneration);

             总结完毕。