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.

280049 FLASH 一个SCETOR的不同地址可以分别进行写操作吗

Other Parts Discussed in Thread: C2000WARE

FLASH操作需求说明:

第一次上电  操作FLASH_BANK1_SEC6 0x096000 

首先使用API接口,擦除FLASH_BANK1_SEC6

Fapi_issueAsyncCommandWithAddress(Fapi_EraseSector,0x96000);

然后使用API接口,向地址0x096000 写入数据

Fapi_issueProgrammingCommand(
Uint32 *pu32StartAddress,                                        // = 0x96000
Uint16 *pu16DataBuffer,                                           // = ui16[8]
Uint16 u16DataBufferSizeInWords,                          // = 8
Uint16 *pu16EccBuffer,                                            // =NONE
Uint16 u16EccBufferSizeInBytes,                             // =NONE
Fapi_FlashProgrammingCommandsType oMode     // = Fapi_DataOnly
);

下电再上电,不执行擦除操作

使用API接口,向地址0x096008 写入数据

Fapi_issueProgrammingCommand(
Uint32 *pu32StartAddress,                                        // = 0x96008
Uint16 *pu16DataBuffer,                                           // = ui16[8]
Uint16 u16DataBufferSizeInWords,                          // = 8
Uint16 *pu16EccBuffer,                                            // =NONE
Uint16 u16EccBufferSizeInBytes,                             // =NONE
Fapi_FlashProgrammingCommandsType oMode     // = Fapi_DataOnly
);

操作结果,是0x096000的数据正常写入,但是下电在上电向0x96008地址写数据是失败,Fapi_issueProgrammingCommand返回的错误信息为“Fapi_Error_AsyncIncorrectEccBufferLength”

请问我这样操作可以吗?如果不可以这样操作,要怎样操作才能实现的目的:在不同的时间向同一扇区的不同地址写入数据。

  • 我认为这种方式是可以的

    您可以参考下面链接的Table 6. Uses of Different Programming Modes来了解使用该模式的相关内容

    www.ti.com/.../spnu628a.pdf

    若是可以的话,请给出详细的代码内容

    另外请问您现在使能ECC了吗?
  • ECC默认是使能的:

    “TMS320F28004x Flash API Reference Guide”这份操作指导我看过了,使用的写模式就是Table 6. Uses of Different Programming Modes中的“Fapi_DataOnly”模式,

    操作FLASH的代码如下:

    void EepromTest(void)
    {

    Fapi_FlashStatusType oFlashStatus;
    Fapi_FlashStatusWordType oFlashStatusWord;

    Uint16 au16DataBuffer[2][8] = {{0x0001, 0x0203, 0x0405, 0x0607, 0x0809, 0x0A0B, 0x0C0D, 0x0E0F},
                                                      {0x0002, 0x0204, 0x0406, 0x0607, 0x0808, 0x0A0c, 0x0C0c, 0x0E0c}};
    Uint32 *DataBuffer32 = (Uint32 *)au16DataBuffer;

    if(uiErase == 1)
    {
         uiErase = 0;
         oReturnCheck1 = Fapi_issueAsyncCommandWithAddress(Fapi_EraseSector, (Uint32 *)0x96000);
         // Wait until FSM is done with erase sector operation
        while(Fapi_checkFsmForReady() != Fapi_Status_FsmReady){}
        if(oReturnCheck1 != Fapi_Status_Success)
        {
        //Example_Error (oReturnCheck);
        }

                 oFlashStatus = Fapi_getFsmStatus();
                if (oFlashStatus!=0)
                {
                //FMSTAT_Fail();
                }

                oReturnCheck1 = Fapi_doBlankCheck((Uint32 *)0x96000, 0x800,&oFlashStatusWord);
               if(oReturnCheck1 != Fapi_Status_Success)
               {
               //Example_Error(oReturnCheck);
               }
        }

       if(uiWrite == 1)

       {

    uiWrite = 0;
    //u32Index = 0x96000;
    //Programe
    for(u32Index = 0x96000; (u32Index < 0x96100) &&
    (oReturnCheck1 == Fapi_Status_Success); u32Index+=8)
    {
        oReturnCheck1 = Fapi_issueProgrammingCommand((Uint32 *)u32Index,au16DataBuffer[uiDataNum],8,0,0,Fapi_DataOnly);
        ErrorCode = oReturnCheck1;
        while (Fapi_checkFsmForReady() != Fapi_Status_FsmReady){}
    }

    }

    if(uiWrite == 2)
    {
    uiWrite = 0;
    //u32Index = 0x96008;
    //Programe
    for(u32Index = 0x96200; (u32Index < 0x96300) &&
    (oReturnCheck1 == Fapi_Status_Success); u32Index+=8)
    {
    oReturnCheck1 = Fapi_issueProgrammingCommand((Uint32 *)u32Index,au16DataBuffer[uiDataNum],8,0,0,Fapi_DataOnly);
    ErrorCode = oReturnCheck1;
    while (Fapi_checkFsmForReady() != Fapi_Status_FsmReady){}
    }
    }

    }

    Debug下,手动修改uiErase和uiWrite变量值来进行擦除和写操作。代码复制尽量格式对齐比较麻烦,看起来有点费劲,麻烦了!

  • 这个代码看起来有点费劲,请您点击右下角的 “使用高级编辑器编辑文本” 然后以附件形式上传一下您的工程,谢谢
  • 工程无法上传,公司电脑加密的。你只需要把这个函数拷贝到任意一个已对FLASH进行初始化的工程里就可以了。
  • 那请您以下面的方式上传一下代码或者c文件,我这边直接拷过去,全是格式错误

  • 所有文件形式都是加密的,外发后都无法打开。但是我不知道为什么复制一段代码你都无法拷贝下来。
  • 是的,我这边20几个错误,且都没办法消除
  • 不好意思,前两天比较忙。今天又测试了一下。找到问题了,
    在执行这个循环写操作的过程中:
    for(u32Index = 0x96000; (u32Index < 0x96100) &&
    (oReturnCheck1 == Fapi_Status_Success); u32Index+=8)
    {
    oReturnCheck1 = Fapi_issueProgrammingCommand((Uint32 *)u32Index,au16DataBuffer[uiDataNum],8,0,0,Fapi_DataOnly);
    ErrorCode = oReturnCheck1;
    while (Fapi_checkFsmForReady() != Fapi_Status_FsmReady){}
    }

    每次写结束后的,while (Fapi_checkFsmForReady() != Fapi_Status_FsmReady){}判断会触发watchdog复位。

    但是新的问题来了:
    1、如果把这个判断去掉,后面的数据有可能写不成功(应为上次写操作还未结束)。
    2、实际执行过程我也不会使用while去等待写结束,这样会严重影响我的程序实时性和软件负载率。
    我应该怎样去写一段数据到FLASH呢?
  • 请您看一下wiki页面内FAQ描述

    11. Does Fapi_issueProgrammingCommand() function call return after completing the program operation?

    Answer. No, this function issues a program command to the Flash State Machine for the user-provided address and data. This function does not wait until the program operation is over; it just issues the command and returns back. Hence, the success status returned by this function should not be taken for a successful program operation. A success-status return from this function means that the address, data and/or ECC supplied by the user application meet the requirements of the program operation and that the program command is issued successfully. The user application must wait for the FMC to complete the program operation before accessing the Flash bank on which the program command is issued. The Fapi_checkFsmForReady() function can be used to monitor the status of an issued command.

    此函数向闪存状态机发出程序命令,以获取用户提供的地址和数据。该功能不会等到程序操作结束后才执行。它只是发出命令并返回。因此,不应将此函数返回的成功状态用于成功的编程操作。从该功能返回成功状态意味着用户应用程序提供的地址,数据和/或ECC满足程序操作的要求,并且程序命令已成功发出。用户应用程序必须等待FMC完成编程操作,然后才能访问在其上发出了程序命令的Flash库。Fapi_checkFsmForReady()函数可用于监视已发出命令的状态。

     

    12. If the Fapi_issueProgrammingCommand() function does not wait for the program operation completion, how do we know whether the program operation succeeded or not?

    Answer. The user application must check the FMSTAT value when FSM has completed the program operation. FMSTAT indicates if there is any failure occurrence during the program operation. The user application can use the Fapi_getFSMStatus() function to obtain the FMSTAT value. See device specific Flash API reference guide provided in C2000Ware for FMSTAT details. Also, the user application should use the Fapi_doVerify() function to verify that the Flash is programmed correctly.

    FSM完成程序操作后,用户应用程序必须检查FMSTAT值。FMSTAT指示在程序运行期间是否发生任何故障。用户应用程序可以使用Fapi_getFSMStatus()函数获取FMSTAT值。有关FMSTAT的详细信息,请参见C2000Ware中提供的特定于设备的Flash API参考指南。此外,用户应用程序应使用Fapi_doVerify()函数来验证Flash的编程是否正确。

  • 谢谢您耐心的细致的解答
  • 很高兴能帮到您