TMS320F280039C-Q1: FLASH存储不进去,但是不报错

Part Number: TMS320F280039C-Q1

调用Fapi_issueProgrammingCommand(),不报错,但是数据没有存储进去,之后Fapi_getFsmStatus(),报0x30错误,但是flash区域我看过全是0xffff,没有数据

用Fapi_doBlankCheck()函数也校验过这片区域全是0xffff,不应该写入不进去

#ifdef __cplusplus
#pragma CODE_SECTION(".TI.ramfunc");
#else
#pragma CODE_SECTION(FLASH_Write_NoCheck, ".TI.ramfunc");
#endif
uint16_t FLASH_Write_NoCheck(uint32_t WriteAddr,uint16_t *pBuffer,uint16_t NumToWrite)
{
Fapi_StatusType oReturnCheck =0;


oReturnCheck = Fapi_initializeAPI(F021_CPU0_BASE_ADDRESS,
DEVICE_SYSCLK_FREQ/1000000U);

if(oReturnCheck != Fapi_Status_Success)
{
#ifdef flashdebug
FlashError9++;
#endif
return 1;
}

oReturnCheck = Fapi_setActiveFlashBank(Fapi_FlashBank2);

if(oReturnCheck != Fapi_Status_Success)
{
#ifdef flashdebug
FlashError10++;
#endif
return 2;
}

// Fapi_StatusType oReturnCheck;
uint32 u32Index = 0;
uint16 i = 0;
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 option 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 Sector6 while programming with AutoEcc mode.
//
// In this example, 0x100 bytes are programmed in Flash Sector6
// along with auto-generated ECC.
//

for(i=0, u32Index = WriteAddr; (u32Index < (WriteAddr+NumToWrite));i+= 8, u32Index+= 8)
{
oReturnCheck = Fapi_issueProgrammingCommand((uint32 *)u32Index,(uint16_t *)&pBuffer[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);
#ifdef flashdebug
FlashError3++;
#endif
return 3;
}

//
// 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();
#ifdef flashdebug
FlashError4++;
#endif
return 4;
}

#if 0
//
// Verify the programmed values. Check for any ECC errors.
//
oReturnCheck = Fapi_doVerify((uint32 *)u32Index,
0x4, (UInt32 *)&pBuffer[i],
&oFlashStatusWord);

if(oReturnCheck != Fapi_Status_Success)
{
//
// Check Flash API documentation for possible errors
//
// Example_Error(oReturnCheck);
#ifdef flashdebug
FlashError5++;
#endif
return 5;
}
#endif
}
return 0;
}

WriteAddr地址为0xAFFE0  NumToWrite 为16

  • TI品的关注!

    关于你的咨,我正在确你的问题,稍后回复您。

  • 需要上传cmd文件吗?

  • MEMORY
    {
    //BEGIN : origin = 0x00080000, length = 0x00000002
    BOOT_RSVD : origin = 0x00000002, length = 0x00000126

    RAMM0 : origin = 0x00000128, length = 0x000002D8
    RAMM1 : origin = 0x00000400, length = 0x000003F8
    // RAMM1_RSVD : origin = 0x000007F8, length = 0x00000008 /* Reserve and do not use for code as per the errata advisory "Memory: Prefetching Beyond Valid Memory" */

    RAMLS0 : origin = 0x00008000, length = 0x00000800
    RAMLS3 : origin = 0x00008800, length = 0x00000800
    //RAMLS3 : origin = 0x00009000, length = 0x00000800
    //RAMLS3 : origin = 0x00009800, length = 0x00000800
    RAMLS4 : origin = 0x00009000, length = 0x00000200
    //RAMLS5 : origin = 0x0000A800, length = 0x00000800
    RAMLS5 : origin = 0x00009200, length = 0x00003E00
    //RAMLS6 : origin = 0x0000B000, length = 0x00000800
    //RAMLS7 : origin = 0x0000B800, length = 0x00000800

    RAMGS0 : origin = 0x0000D000, length = 0x00002ff0
    //RAMGS1 : origin = 0x0000D000, length = 0x00001000
    //RAMGS2 : origin = 0x0000E000, length = 0x00001000
    //RAMGS3 : origin = 0x0000F000, length = 0x00000FF8
    // RAMGS3_RSVD : origin = 0x0000FFF8, length = 0x00000008 /* Reserve and do not use for code as per the errata advisory "Memory: Prefetching Beyond Valid Memory" */

    BOOTROM : origin = 0x003F8000, length = 0x00007FC0
    SECURE_ROM : origin = 0x003F2000, length = 0x00006000

    /* Flash sectors */
    /* BANK 0 */
    FLASH_BANK0_SEC0 : origin = 0x080000, length = 0x001000
    FLASH_BANK0_SEC1 : origin = 0x081000, length = 0x001000
    FLASH_BANK0_SEC2 : origin = 0x082000, length = 0x001000
    FLASH_BANK0_SEC3 : origin = 0x083000, length = 0x001000
    FLASH_BANK0_SEC4 : origin = 0x084000, length = 0x001000
    FLASH_BANK0_SEC5 : origin = 0x085000, length = 0x001000
    FLASH_BANK0_SEC6 : origin = 0x086000, length = 0x001000
    FLASH_BANK0_SEC7 : origin = 0x087000, length = 0x001000
    FLASH_BANK0_SEC8 : origin = 0x088000, length = 0x001000
    FLASH_BANK0_SEC9 : origin = 0x089000, length = 0x001000
    FLASH_BANK0_SEC10 : origin = 0x08A000, length = 0x001000
    FLASH_BANK0_SEC11 : origin = 0x08B000, length = 0x001000
    FLASH_BANK0_SEC12 : origin = 0x08C000, length = 0x001000
    FLASH_BANK0_SEC13 : origin = 0x08D000, length = 0x001000
    FLASH_BANK0_SEC14 : origin = 0x08E000, length = 0x001000
    FLASH_BANK0_SEC15 : origin = 0x08F000, length = 0x001000


    /* BANK 1 */
    FLASH_BANK1_SEC15 : origin = 0x09F000, length = 0x001000

    /* BANK 2 */
    FLASH_BANK2_SEC0 : origin = 0x0A0000, length = 0x001000
    FLASH_BANK2_SEC1 : origin = 0x0A1000, length = 0x001000
    FLASH_BANK2_SEC2 : origin = 0x0A2000, length = 0x001000
    FLASH_BANK2_SEC3 : origin = 0x0A3000, length = 0x001000
    FLASH_BANK2_SEC4 : origin = 0x0A4000, length = 0x001000
    FLASH_BANK2_SEC5 : origin = 0x0A5000, length = 0x001000
    FLASH_BANK2_SEC6 : origin = 0x0A6000, length = 0x001000
    FLASH_BANK2_SEC7 : origin = 0x0A7000, length = 0x001000
    FLASH_BANK2_SEC8 : origin = 0x0A8000, length = 0x001000
    FLASH_BANK2_SEC9 : origin = 0x0A9000, length = 0x001000
    FLASH_BANK2_SEC10 : origin = 0x0AA000, length = 0x001000
    FLASH_BANK2_SEC11 : origin = 0x0AB000, length = 0x001000
    FLASH_BANK2_SEC12 : origin = 0x0AC000, length = 0x001000
    FLASH_BANK2_SEC13 : origin = 0x0AD000, length = 0x001000
    FLASH_BANK2_SEC14 : origin = 0x0AE000, length = 0x001000
    FLASH_BANK2_SEC15 : origin = 0x0AF000, length = 0x000FF0

    RESET : origin = 0x003FFFC0, length = 0x00000002


    #ifdef __TI_COMPILER_VERSION__
    #if __TI_COMPILER_VERSION__ >= 20012000
    GROUP { /* GROUP memory ranges for crc/checksum of entire flash */
    #endif
    #endif
    BEGIN : origin = 0x090000, length = 0x000002
    FLASH_BANK1_SEC0 : origin = 0x090002, length = 0x0019FE
    FLASH_BANK1_SEC1 : origin = 0x091A00, length = 0x001000
    FLASH_BANK1_SEC2 : origin = 0x092A00, length = 0x000B00
    FLASH_BANK1_SEC3 : origin = 0x093500, length = 0x00BB00-0x80
    // FLASH_BANK0_SEC15_RSVD : origin = 0x0AFFF0, 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=CRC16_ALT)
    CRC_TABLE : origin = 0x09F000-0x80, length = 0x000080
    #endif
    #endif
    }


    SECTIONS
    {
    codestart : > BEGIN, ALIGN(8)
    .text : >> FLASH_BANK1_SEC3, ALIGN(8)

    .cinit : > FLASH_BANK1_SEC0, ALIGN(8)
    .switch : > FLASH_BANK1_SEC0, ALIGN(8)
    .reset : > RESET, TYPE = DSECT /* not used, */

    .stack : > RAMM1

    #if defined(__TI_EABI__)
    .init_array : > FLASH_BANK1_SEC0, ALIGN(8)
    .bss : > RAMLS5, ALIGN(2)
    .bss:output : > RAMLS3
    .bss:cio : > RAMLS0
    .data : > RAMLS5, ALIGN(2)
    .sysmem : > RAMLS5, ALIGN(2)
    .const : > FLASH_BANK1_SEC2, ALIGN(8)
    #else
    .pinit : > FLASH_BANK1_SEC0, ALIGN(8)
    .ebss : >> RAMM0|RAMLS5|RAMLS3, ALIGN(2)
    .esysmem : > RAMLS5, ALIGN(2)
    .cio : > RAMLS0
    .econst : > FLASH_BANK1_SEC2, ALIGN(8)

    #endif

    ramgs0 : > RAMGS0
    ramgs1 : > RAMGS0

    /* Allocate IQ math areas: */
    IQmath : > FLASH_BANK1_SEC0, ALIGN(8)
    IQmathTables : > FLASH_BANK1_SEC1, ALIGN(8)

    GROUP
    {
    .TI.ramfunc
    { -l FAPI_F28003x_COFF_v1.58.10.lib}

    }
    LOAD = FLASH_BANK1_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
    .TI.memcrc > CRC_TABLE


    }

  • WriteAddr地址为0xAFFE0  NumToWrite 为16 ,全是0xFFFF,写入不进去

  • FSM值0x30表示用户尝试编程"1",其中已存在"0"。

    您能否删除它并重新编程,看看您是否面临同样的问题?

    您是否首先使用0xFF对该区域进行编程,然后尝试使用不同的值对其进行编程? 因为我在您的编程位置后看到0x55AA值。

  • 一:删除它并重新编程,看看您是否面临同样的问题?

    扇区整体擦除,在整个扇区写入,是可以的,我是当作模拟EEPROM来用的,这样要多消耗三十多ms,这样我们升级会出问题超时,而且还影响寿命。

    二:使用0xFF对该区域进行编程,然后尝试使用不同的值对其进行编程? 

    写入0xFFFF,没有报错,但是其他值写入不进去还是报0x30

    我写入地址0xAFFE0,128bit地址对齐,应该没有问题才对。

    0xAFFF0有数据,应该不会影响到地址0xAFFE0,写入16个半字的数据才对

  • Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    /*DSP*/
    #ifdef __cplusplus
    #pragma CODE_SECTION(".TI.ramfunc");
    #else
    #pragma CODE_SECTION(FLASH_Write, ".TI.ramfunc");
    #endif
    /*
    * 0XAF000---0xAFFFF
    * WriteAddr
    * pBuffer
    * NumToWrite
    */
    void FLASH_Write(uint32_t WriteAddr,uint16_t* pBuffer,uint16_t NumToWrite)
    {
    uint16 FlashFlag =0;
    uint32_t sec_addr;//
    uint16_t sec_off; //(16)
    uint16_t sec_remain;//(16)
    uint16_t i;
    uint32_t offaddr; //0xAE000U 0x1000 1
    if(WriteAddr<EEPROM_BASE||(WriteAddr>=(EEPROM_BASE+(uint32_t)EEPROM_SECTOR_SIZE*EEPROM_SIZE)))return;//
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    FLASH_Write()函数就是模拟EEPROM的函数接口,在函数里面我调用的是FLASH_Write_NoCheck()

    uint16_t *EEpromTemp =(uint16_t *) 0x9010;

    #define  SelfLearn_ADDRESS  0x0AFFE0 

  • 上面模拟EEPROM函数

    FLASH_Write(SelfLearn_ADDRESS,EEpromTemp,10);

    是进入 ,这部分代码中

  • 抱歉,我不清楚你在做什么步骤,当你看到失败?

    1.擦除和编程总是成功的。

    2.当您第一次使用0xffff值对位置进行编程并使用其他值重新编程时,编程会给fmstat错误0x30。

  • 一:擦除和编程总是成功的,

    是整个扇区擦除

    FLASH_ErasePage(sec_addr*EEPROM_SECTOR_SIZE+EEPROM_BASE);//擦除这个扇区

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    #ifdef __cplusplus
    #pragma CODE_SECTION(".TI.ramfunc");
    #else
    #pragma CODE_SECTION(FLASH_ErasePage, ".TI.ramfunc");
    #endif
    uint16_t FLASH_ErasePage(uint32_t WriteAddr)
    {
    //uint16 i = 0;
    uint16 sectorNo =0;
    Fapi_StatusType oReturnCheck;
    oReturnCheck = Fapi_initializeAPI(F021_CPU0_BASE_ADDRESS,
    DEVICE_SYSCLK_FREQ/1000000U);
    if(oReturnCheck != Fapi_Status_Success)
    {
    #ifdef flashdebug
    FlashError1++;
    #endif
    return 1;
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    FlashFlag=FLASH_Write_NoCheck(sec_addr*EEPROM_SECTOR_SIZE+EEPROM_BASE,FLASH_BUF,EEPROM_SECTOR_SIZE);//写入整个扇区(页)

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    //
    // WriteAddr:
    // pBuffer:
    // NumToWrite:(16)
    #ifdef __cplusplus
    #pragma CODE_SECTION(".TI.ramfunc");
    #else
    #pragma CODE_SECTION(FLASH_Write_NoCheck, ".TI.ramfunc");
    #endif
    uint16_t FLASH_Write_NoCheck(uint32_t WriteAddr,uint16_t *pBuffer,uint16_t NumToWrite)
    {
    Fapi_StatusType oReturnCheck =0;
    oReturnCheck = Fapi_initializeAPI(F021_CPU0_BASE_ADDRESS,
    DEVICE_SYSCLK_FREQ/1000000U);
    if(oReturnCheck != Fapi_Status_Success)
    {
    #ifdef flashdebug
    FlashError9++;
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    我们要存储的数据更新在FLASH_BUF数组中,EEPROM_SECTOR_SIZE 大小长度为0x1000

    但是这样整体擦除,在整体写入,会应用flash使用次数,因为我们当作模拟EEPROM使用的,

  • 二:第一次使用0xffff值对位置进行编程并使用其他值重新编程时,编程会给fmstat错误0x30。

    这个没有使用整个扇区擦除,整体扇区写入的方式,而是指令地址写入

    uint16_t *EEpromTemp =(uint16_t *) 0x9010; ,

    memcpy((uint16_t *)EEpromTemp,(uint16_t *)TxFlashbuff,16);

    FLASH_Write(SelfLearn_ADDRESS,EEpromTemp,10);

    TxFlashbuff 数组里面数据全为0xFFFF

    这样调用FLASH_Write()这个模拟EEPROM的函数,没有报错

    之后更改TxFlashbuff 数组数据

    再次调用FLASH_Write()这个模拟EEPROM的函数,报错了

    因为我也判断了,SelfLearn_ADDRESS地址flash里面数据全是0XFFFF,不要擦除,可以直接写入

    FlashFlag=FLASH_Write_NoCheck(WriteAddr,&FLASH_BUF[sec_off],(sec_remain/8+1)*8);//写已经擦除了的,直接写入扇区剩余区间

    通过仿真查看这个变量报错,flash也没有写入进去

x 出现错误。请重试或与管理员联系。