Part Number:TMS320F280039C-Q1Other Parts Discussed in Thread:C2000WARE

调用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
Lydia:
感谢您对TI产品的关注!
关于你的咨询,我们正在确认你的问题,稍后回复您。
,
chen feng:
需要上传cmd文件吗?
,
chen feng:
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__ >= 20012000GROUP { /* 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
}
,
chen feng:
WriteAddr地址为0xAFFE0 NumToWrite 为16 ,全是0xFFFF,写入不进去
,
Eirwen:
FSM值0x30表示用户尝试编程"1",其中已存在"0"。
您能否删除它并重新编程,看看您是否面临同样的问题?
您是否首先使用0xFF对该区域进行编程,然后尝试使用不同的值对其进行编程? 因为我在您的编程位置后看到0x55AA值。
,
chen feng:
一:删除它并重新编程,看看您是否面临同样的问题?
扇区整体擦除,在整个扇区写入,是可以的,我是当作模拟EEPROM来用的,这样要多消耗三十多ms,这样我们升级会出问题超时,而且还影响寿命。
二:使用0xFF对该区域进行编程,然后尝试使用不同的值对其进行编程?
写入0xFFFF,没有报错,但是其他值写入不进去还是报0x30
我写入地址0xAFFE0,128bit地址对齐,应该没有问题才对。
0xAFFF0有数据,应该不会影响到地址0xAFFE0,写入16个半字的数据才对
,
chen feng:
/*写一个字节数据,但是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的地址0x10001if(WriteAddr<EEPROM_BASE||(WriteAddr>=(EEPROM_BASE+(uint32_t)EEPROM_SECTOR_SIZE*EEPROM_SIZE)))return;//非法地址if(NumToWrite ==0) return;//Btwo_Sector15_start0xAF000U0x10001if(WriteAddr + NumToWrite >= (EEPROM_BASE+(uint32_t)EEPROM_SECTOR_SIZE*EEPROM_SIZE)) return;offaddr=WriteAddr-EEPROM_BASE;//实际偏移地址.sec_addr= offaddr/EEPROM_SECTOR_SIZE;//扇区地址0sec_off = offaddr%EEPROM_SECTOR_SIZE;//扇区内的偏移地址(2个字节为基本单位)sec_remain=EEPROM_SECTOR_SIZE-sec_off;//以两个字节为基本单位的话,所以一页内有STM_SECTOR_SIZE个基本单位。//一页内剩余多少个基本单位呢?直接减去一页内的偏移地址就可以了if(NumToWrite<=sec_remain)sec_remain=NumToWrite;//不大于该扇区范围if(NumToWrite ==1){#ifdef flashdebugtest3++;#endifFLASH_Write_HalfWord(WriteAddr,pBuffer[0]);return ;}else{while(1){memset(FLASH_BUF,0,EEPROM_SECTOR_SIZE);FLASH_ReadHalfData(sec_addr*EEPROM_SECTOR_SIZE+EEPROM_BASE,FLASH_BUF,EEPROM_SECTOR_SIZE);for(i=0;i<sec_remain;i++){if(FLASH_BUF[sec_off+i]!=0xffff)break;//当检查到有地址内地数据不为0xffff,那么就跳出for循环;}if(i<sec_remain)//判断i的值是否小于该页的剩余量,如果小于,则说明要擦除整页。{#ifdef flashdebugtest4++;#endifFLASH_ErasePage(sec_addr*EEPROM_SECTOR_SIZE+EEPROM_BASE);//擦除这个扇区for(i=0;i<sec_remain;i++){FLASH_BUF[i+sec_off]=pBuffer[i];}FlashFlag=FLASH_Write_NoCheck(sec_addr*EEPROM_SECTOR_SIZE+EEPROM_BASE,FLASH_BUF,EEPROM_SECTOR_SIZE);//写入整个扇区(页)}else{//写已经擦除了的,直接写入扇区剩余区间.if(sec_off %8 ==0)// 写入地址对齐{for(i=0;i<sec_remain;i++){FLASH_BUF[i+sec_off]=pBuffer[i];}if(sec_remain %8 !=0)// 存储的数据不是8的倍数{for(i=0;i< (8- sec_remain%8);i++)//数据会补齐,先检测是否全为0Xffff{if(FLASH_BUF[i+sec_off+sec_remain]!=0xffff){#ifdef flashdebugtest5++;#endifFLASH_ErasePage(sec_addr*EEPROM_SECTOR_SIZE+EEPROM_BASE);//擦除这个扇区break;}}}if(sec_remain %8 ==0){#ifdef flashdebugtest6++;#endif// 如果写2个扇区里面内容会进入这条语句FLASH_Write_NoCheck(WriteAddr,&FLASH_BUF[sec_off],sec_remain);//写已经擦除了的,直接写入扇区剩余区间}else{#ifdef flashdebugtest7++;#endifFlashFlag=FLASH_Write_NoCheck(WriteAddr,&FLASH_BUF[sec_off],(sec_remain/8+1)*8);//写已经擦除了的,直接写入扇区剩余区间}}else// 写入地址不对齐{if((sec_off % 8 +sec_remain) >8)// 以8个地址对齐 , 偏移地址+要写入的数据的长度{for(i=0;i< ((sec_remain/8+2)*8);i++)//数据会补齐,先检测是否全为0Xffff{if(FLASH_BUF[i+(sec_off/8)*8] !=0xffff){#ifdef flashdebugtest8++;#endifFLASH_ErasePage(sec_addr*EEPROM_SECTOR_SIZE+EEPROM_BASE);//擦除这个扇区break;}}if(i<((sec_remain/8+2)*8)){#ifdef flashdebugtest9++;#endiffor(i=0;i<sec_remain;i++){FLASH_BUF[i+sec_off]=pBuffer[i];}FlashFlag=FLASH_Write_NoCheck(sec_addr*EEPROM_SECTOR_SIZE+EEPROM_BASE,FLASH_BUF,EEPROM_SECTOR_SIZE);//写入整个扇区(页)}else{#ifdef flashdebugtest10++;#endiffor(i=0;i<sec_remain;i++){FLASH_BUF[i+sec_off]=pBuffer[i];}// 如果写2个扇区里面内容会进入这条语句FlashFlag=FLASH_Write_NoCheck((WriteAddr/8)*8,&FLASH_BUF[(sec_off/8) *8],(sec_remain/8+2)*8);//写已经擦除了的,直接写入扇区剩余区间}}else{for(i=0;i< ((sec_remain/8+1)*8);i++)//数据会补齐,先检测是否全为0Xffff{if(FLASH_BUF[i+(sec_off/8)*8] !=0xffff){#ifdef flashdebugtest11++;#endifFlashFlag=FLASH_ErasePage(sec_addr*EEPROM_SECTOR_SIZE+EEPROM_BASE);//擦除这个扇区break;}}if(i<((sec_remain/8+1)*8)){#ifdef flashdebugtest12++;#endiffor(i=0;i<sec_remain;i++){FLASH_BUF[i+sec_off]=pBuffer[i];}FlashFlag=FLASH_Write_NoCheck(sec_addr*EEPROM_SECTOR_SIZE+EEPROM_BASE,FLASH_BUF,EEPROM_SECTOR_SIZE);//写入整个扇区(页)}else{#ifdef flashdebugtest13++;#endiffor(i=0;i<sec_remain;i++){FLASH_BUF[i+sec_off]=pBuffer[i];}FlashFlag=FLASH_Write_NoCheck((WriteAddr/8)*8,&FLASH_BUF[(sec_off/8) *8],((sec_remain/8+1)*8));//写已经擦除了的,直接写入扇区剩余区间}}}}if(NumToWrite==sec_remain)break;//写入结束了,跳出while循环else//写入未结束{sec_addr++;//扇区地址增1sec_off=0;//偏移位置为0pBuffer+=sec_remain;//指针偏移WriteAddr+=sec_remain;//写地址偏移NumToWrite-=sec_remain; //字节(16位)数递减if(NumToWrite>(EEPROM_SECTOR_SIZE)){sec_remain=EEPROM_SECTOR_SIZE;//下一个扇区还是写不完}else{sec_remain=NumToWrite;//下一个扇区可以写完了}}}} }FLASH_Write()函数就是模拟EEPROM的函数接口,在函数里面我调用的是FLASH_Write_NoCheck()
uint16_t *EEpromTemp =(uint16_t *) 0x9010;
#define SelfLearn_ADDRESS 0x0AFFE0
,
chen feng:
上面模拟EEPROM函数
FLASH_Write(SelfLearn_ADDRESS,EEpromTemp,10);
是进入
,这部分代码中
,
Eirwen:
抱歉,我不清楚你在做什么步骤,当你看到失败?
1.擦除和编程总是成功的。
2.当您第一次使用0xffff值对位置进行编程并使用其他值重新编程时,编程会给fmstat错误0x30。
,
chen feng:
一:擦除和编程总是成功的,
是整个扇区擦除
FLASH_ErasePage(sec_addr*EEPROM_SECTOR_SIZE+EEPROM_BASE);//擦除这个扇区
#ifdef __cplusplus #pragma CODE_SECTION(".TI.ramfunc"); #else #pragma CODE_SECTION(FLASH_ErasePage, ".TI.ramfunc"); #endifuint16_t FLASH_ErasePage(uint32_t WriteAddr) {//uint16 i = 0;uint16 sectorNo =0;Fapi_StatusTypeoReturnCheck;oReturnCheck = Fapi_initializeAPI(F021_CPU0_BASE_ADDRESS,DEVICE_SYSCLK_FREQ/1000000U);if(oReturnCheck != Fapi_Status_Success){#ifdef flashdebugFlashError1++;#endifreturn 1;}oReturnCheck = Fapi_setActiveFlashBank(Fapi_FlashBank2);if(oReturnCheck != Fapi_Status_Success){#ifdef flashdebugFlashError2++;#endifreturn 2;}sectorNo =(WriteAddr-EEPROM_BASE)/EEPROM_SECTOR_SIZE +15;Example_EraseAppBackSector(sectorNo);return 0; }FlashFlag=FLASH_Write_NoCheck(sec_addr*EEPROM_SECTOR_SIZE+EEPROM_BASE,FLASH_BUF,EEPROM_SECTOR_SIZE);//写入整个扇区(页)
// 不检查的写入 // 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_StatusTypeoReturnCheck =0;oReturnCheck = Fapi_initializeAPI(F021_CPU0_BASE_ADDRESS,DEVICE_SYSCLK_FREQ/1000000U);if(oReturnCheck != Fapi_Status_Success){#ifdef flashdebugFlashError9++;#endifreturn 1;}oReturnCheck = Fapi_setActiveFlashBank(Fapi_FlashBank2);if(oReturnCheck != Fapi_Status_Success){#ifdef flashdebugFlashError10++;#endifreturn 2;}//Fapi_StatusTypeoReturnCheck;uint32 u32Index = 0;uint16 i = 0;Fapi_FlashStatusTypeoFlashStatus;//Fapi_FlashStatusWordTypeoFlashStatusWord;//// 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 flashdebugFlashError3++;#endifreturn 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 flashdebugFlashError4++;#endifreturn 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 flashdebugFlashError5++;#endifreturn 5;} #endif}return 0; }我们要存储的数据更新在FLASH_BUF数组中,EEPROM_SECTOR_SIZE 大小长度为0x1000
但是这样整体擦除,在整体写入,会应用flash使用次数,因为我们当作模拟EEPROM使用的,
,
chen feng:
二:第一次使用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也没有写入进去
,
Eirwen:
使用0xFFFF对闪存地址值进行编程时,表示闪存已编程。 闪存状态机为这些地址编程ECC值。 在擦除并重新编程闪光灯之前,您不能将编程值更改为其他值。
但是,如果您想使用任何特定扇区作为EEPROM,则可以使用该扇区。 C200ware中的EEPROM仿真示例位于"C2000ware\driverlib\f28003x\examples\flash"。 您可以参考此示例并相应地实施。 有关EEPROM仿真的详细信息,请参阅此文档:https://www.ti.com/lit/sprade8.
,
chen feng:
但是这样也不对呀,因为我对另一个地址0x0AFFF0 ,这个地址我写升级标志位,在APP跳转Boot是擦除扇区之后在写入FFFF,在升级成功时,Boot跳转到APP时,APP程序对地址0x0AFFF0写0X55AA55AA,是可以的
TI中文支持网


,这部分代码中



