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:闪存 API Fapi_doVerify 返回 Fapi_Error_FAIL

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1030612/tms320f280025c-flash-api-fapi_doverify-returns-fapi_error_fail

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

您好!

我正在处理 f28002的引导加载程序、遇到了这个问题。 我的问题与在 https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/985970/tms320f280025c-flash-api-fapi_doverify-problem 上发布的问题类似

我修改了 flashapi 示例、但核心部分与示例相同。 一切似乎都正常、我甚至可以看到在调试模式下写入闪存的十六进制数据(数据正确)、但 当涉及到 Fapi_doVerify 时、Fapi_Error_FAIL 会失败 、 oFlashStatusWord 将返回以下内容

我正在使用 Fapi_AutoEccGeneration 并在调试模式下进行此操作。

请告诉我如何解决这个问题、我使用过280049的引导加载程序、使用了类似的代码、Dint 遇到了这个错误。

此致、

Harsha Dsouza

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

    Harsha、

    仅为清楚起见:您是否说您能够在内存窗口中看到正确的数据、但验证是否失败?

    如果是、您是否进行了检查以确保您通过验证的地址、长度和数据正确无误?

    谢谢、此致、
    Vamsi

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

    您好、Vamsi、

    是的、我能够在存储器窗口中看到正确的数据、但验证功能失败。

    我已经验证了 Fapi_doVerify ((((uint32 *) u32Index、4、Buffer32+(I/2)、&oFlashStatusWord)的参数

     u32Index 指向正确的位置、缓冲区的指针也是正确的。

    此致、

    Harsha

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

    Harsha、

    1) 1)您是否按照 C2000Ware 的闪存 API 示例中所示在链接器 cmd 文件中的32位边界上对齐数据缓冲器?

    2) 2)您是否注意到长度必须以32位字长传递?

    谢谢、此致、
    Vamsi

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

    您好、Vamsi、

    1)对于对齐、我使用了 align (8)  

    部分

    codestart:>开始,align (8)
    .text:>> flash_BANK0_SEC0 | flash_BANK0_SEC1 | flash_BANK0_sec2 | flash_BANK0_SEC3 | flash_BANK0_SEC4 | flash_BANK0_SEC5、align (8)
    .cinit:> flash_BANK0_SEC4,align (8)
    .switch:> FLASH_BANK0_SEC0,ALIGN (8)
    .reset:> reset,type = DSECT /* not used,*/

    .stack:> RAMM1

    init_array:> flash_BANK0_SEC0,align (8)
    .bss:> RAMLS4567
    .bss:输出:> RAMLS4567
    .bss:CIO :>RAMGS0
    .const:>> FLASH_BANK0_SEC1 | FLASH_BANK0_SEC2 | FLASH_BANK0_SEC3、ALIGN (8)
    .data:> RAMLS4567
    .sysmem:> RAMLS4567

    RAMS0:> RAMGS0

    /*分配 IQ 数学区域:*/
    IQMath :> RAMLS4567
    IQmathTables :> RAMLS4567

    .TI.ramfunc:load = flash_BANK0_SEC0,
    运行= RAMGS0、
    Load_start (RamfuncsLoadStart)、
    load_size (RamfuncsLoadSize)、
    Load_End (RamfuncsLoadEnd)、
    RUN_START (RamfuncsRunStart)、
    run_size (RamfuncsRunSize)、
    RUN_END (RamfuncsRunEnd)、
    对齐(8)

    //自定义段
    .App_CodeStart:> FLASH_BANK0_SEC6,ALIGN (8)//应用程序代码的起始地址
    .AppCode_CRCTable :> FLASH_APP_CRC // CRC 表位置

    2) 2)  example_ProgramUsingAutoECC 函数中的注释提到了这一点  

    "//请记住主阵列闪存编程必须与对齐
    // 64位地址边界和每个64位字只能被编程
    //每个写入/擦除周期一次。 这意味着数据缓冲区的长度
    //(Fapi_issueProgrammingCommand()函数的第3个参数)传递
    //编程功能只能是4或8。”

    那么、您能不能用"长度必须以32位长度传递"来说明您的看法?

    此致、

    Harsha

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

    Harsha、

    1)对齐(8)应该良好。  但是、我要问的是示例中用于数据的数据段的对齐。  它也在128位边界上对齐。  请参阅以下内容、摘自 \C2000Ware_3_04_00_00\device_support\f28002x\common\cmd\28002x_flash_api_lnk.cmd。  您是否处理过此问题?

    2) 2)我将讨论您传递给验证函数的长度参数。  示例:如果要验证8个16位字、则需要将长度传递为4 (4 x 32位)。   

    闪存 API 指南以及闪存 API 常见问题解答 中对此进行了说明:e2e.ti.com/.../faq-faq-on-flash-api-usage-for-c2000-devices

    谢谢、此致、

    Vamsi

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

    您好、Vamsi、

    1)在我的链接器文件中,我以前没有 DataBufferSection:>RAMGS0,ALIGN(8),但我现在添加了它,所以一切都像示例代码一样都是 ALIGN(8)

    另一个问题是  DataBufferSection 有什么作用?

    2)我 在一个周期内将16个16位字(或8个32位字)传递给 Fapi_issueProgrammingCommand 函数、这就是为什么长度为8、而我将4作为长度传递给 Fapi_doVerify、这意味着4个32位字?

    这是函数;

    Fapi_StatusType Flash_Programming(uint16_t *buffer, uint32_t bank_selected_address, uint16_t data_length )
    {
        uint32_t u32Index = 0;
        uint16_t i = 0;
        Fapi_StatusType  oReturnCheck;
        Fapi_FlashStatusType  oFlashStatus;
        Fapi_FlashStatusWordType  oFlashStatusWord;
    
        // A data buffer of max 8 16-bit 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.
        //
        // Remember that the main array flash programming must be aligned to
        // 64-bit address boundaries and each 64 bit word may only be programmed
        // once per write/erase cycle.  Meaning the length of the data buffer
        // (3rd parameter for Fapi_issueProgrammingCommand() function) passed
        // to the program function can only be either 4 or 8.
        //
        // Program data in Flash using "AutoEccGeneration" option.
        // When AutoEccGeneration opton is used, Flash API calculates ECC for the given
        // 64-bit data and programs it along with the 64-bit main array data.
        // Note that any unprovided data with in a 64-bit data slice
        // will be assumed as 1s for calculating ECC and will be programmed.
        //
        // Note that data buffer (Buffer) is aligned on 64-bit boundary for verify reasons.
        //
        // Monitor ECC address for Bank0 Sector6 while programming with AutoEcc mode.
        //
        // In this example, 0xFF+1 bytes are programmed in Flash Bank0 Sector6
        // along with auto-generated ECC.
    
        //
        // Fill a buffer with data to program into the flash.
        //
        int j = 0;
        for(i=0; i <= data_length/2; i++)
        {
            Buffer[i] = (*(buffer+j+1) & 0xFF)|(*(buffer+j+0) << 8);
            j = j + 2;
        }
    
        for(i=0, u32Index = bank_selected_address;
           (u32Index < (bank_selected_address + (data_length/2)));
           i+= 8, u32Index+= 8)
        {
            oReturnCheck = Fapi_issueProgrammingCommand((uint32 *)u32Index, Buffer+i, 8,
                                                                                     0, 0, Fapi_AutoEccGeneration);
    
            // Wait until the Flash program operation is over
            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 to see if there are any program operation related errors
            oFlashStatus = Fapi_getFsmStatus();
            if(oFlashStatus != 0)
            {
                //Check FMSTAT and debug accordingly
                FMSTAT_Fail();
            }
    
            // Verify the programmed values.  Check for any ECC errors.
            // The program command itself does a verify as it goes.
            // Hence program verify by CPU reads (Fapi_doVerify()) is optional.
            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);
            }
        }
    
        return oReturnCheck;
    }

    缓冲区包含32个16位数据

    此致、

    Harsha

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

    Harsha、

    1) 1)请检查 C2000Ware 中的闪存 API 使用示例。  如下所示、用于编程/验证的数据缓冲区分配给此部分。  它应该在32位边界上对齐或在其中的倍数上对齐。  否则、读取将与偶数地址对齐-例如:访问偏移量0x3将导致从地址0x2和0x3返回数据、而不是0x3和0x4。

    2)程序函数可以一次对最大128位(8x16位或4x32位)进行编程。  因此,如果在每个程序命令之后进行验证,则可以验证最大为4*32位(128位)。  因此、当您对128位进行编程时、您可以通过验证的长度为4。

    谢谢、此致、

    Vamsi    

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

    您好、Vamsi、

    感谢我错过了使用 pragma 将缓冲区定向到 DataBufferSection、这就是它很可能采用默认对齐方式(可能不是32位)的原因。 现在我已经在链接器文件中指定了它并在.c 文件中调用它、错误就会得到解决。

    我还遇到了一个问题、在调试此错误时、我发现我的控制器由于程序正在写入 DCSM 而被欺骗、这是因为我没有将缓冲器定向到  DataBufferSection 、所以它正在 DCSM 中写入?

    感谢您的支持。

    此致、

    Harsha  

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

    Harsha、

    很高兴该建议帮助解决了该问题。

    关于您的新 DCSM 问题:否 不对齐32位边界上的写入缓冲区不会导致程序操作进入 DCSM 空间中的程序。  检查链接器 cmd 文件和映射文件以查看分配给该空间的内容。  您可能已经映射了其他内容。

    谢谢和关心 d、
    Vamsi