继续研究这个project,昨天代码在读取到ECC数据之后总会出现ERROR的提醒。为了方便查找问题,在project中添加了printf语句来确认每个过程是否完成。它在代码中出现的是如图的报错:
因为直接copy的例程,所以到Flash_APIguide中去看了它对函数的介绍。出现问题的代码如下:
oReturnCheck = Fapi_doBlankCheck((uint32 *)Bzero_Sector7_start, Sector8KB_u32length, &oFlashStatusWord);
if(oReturnCheck != Fapi_Status_Success)
{
Example_Error(oReturnCheck);
}
Fapi_doBlankCheck为检查sector是否为空的函数(在文档中将flash数据为空定义为数据全部为1),如果不为空就会进入if执行Example_Error。
代码出现这个问题是因为在把数据写入后将这个函数多复制了一次,写入数据以后的扇区内容肯定不为空,因此会显示Example_Error。于是调整代码,在完成指定扇区的写入和ECC数据读取后,擦除掉写入的内容,再检查是否为空就不存在错误了,代码也可以顺利运行。
ReadECCValues(Bzero_Sector7_ecc, WORDS_IN_FLASH_BUFFER/8+1);
// erase the designated flash module after programming and ECC read
oReturnCheck = Fapi_issueAsyncCommandWithAddress(Fapi_EraseSector, (uint32 *)Bzero_Sector7_start);
while (Fapi_checkFsmForReady() != Fapi_Status_FsmReady) {}
if (oReturnCheck != Fapi_Status_Success)
{
printf("Error: EraseSector failed after programming with status %d\n", oReturnCheck);
Example_Error(oReturnCheck);
}
else
{
printf("擦除完成:擦除操作完成后清除Flash中的数据");
printf("\n");
}*/
// Do blank check after erase
oReturnCheck = Fapi_doBlankCheck((uint32 *)Bzero_Sector7_start, Sector8KB_u32length, &oFlashStatusWord);
if(oReturnCheck != Fapi_Status_Success)
{
Example_Error(oReturnCheck);
}
// Example is done here
Example_Done();
对例程中出现的函数进行介绍。在TI例程flashapi_ex1_program_autoecc使用记录-优快云博客中提到针对flash的操作可以分为三个阶段:1.擦除(erase),2.编程(program),3.验证(verify)。针对这三个步骤API库中都已经定义了相关的函数。
首先,需要使用Fapi_initializeAPI()对Flash模块进行初始化:
oReturnCheck = Fapi_initializeAPI(F021_CPU0_BASE_ADDRESS, 100);
//初始化Flash API,提供Flash控制器基地址和操作频率。返回值oReturnCheck用于判断是否初始化成功,如果失败则调用Example_Error处理错误。
if(oReturnCheck != Fapi_Status_Success)
{
printf("Error: Fapi_initializeAPI failed with status %d\n", oReturnCheck);
Example_Error(oReturnCheck); // 确保在初始化失败时停止执行
}//初始化是否成功
else
{
printf("初始化成功");
printf("\n");
}
初始化成功后,需要确认想要操作的flash区域,F280049C中的flash区域可以分为Bank0和Bank1,这两部分不能同时进行操作。每个Bank分为16个扇区(Sector),都有对应的ECC地址。在执行操作前需要确定针对哪个Bank进行操作。API中提供了Fapi_setActiveFlashBank()来实现功能。再将Bank0设置为‘active’后,使用Fapi_issueAsyncCommandWithAddress()函数对特定位置中的数据进行擦除(guidebook中对该函数的解释:Issues an erase command to the Flash State Machine along with a user-provided sector address. 使用用户提供的扇区地址向闪存状态机发出擦除命令)。
// Initialize the Flash banks and FMC for erase and program operations.
oReturnCheck = Fapi_setActiveFlashBank(Fapi_FlashBank0);
//选择 Flash Bank0
if(oReturnCheck != Fapi_Status_Success)
{
printf("Error: Fapi_setActiveFlashBank failed with status %d\n", oReturnCheck);
Example_Error(oReturnCheck); // 确保在设置失败时停止执行
}//是否能够正确选择
else
{
printf("正确选择");
printf("\n");
}
oReturnCheck = Fapi_issueAsyncCommandWithAddress(Fapi_EraseSector,
(uint32 *)Bzero_Sector7_start);
// Wait until FSM is done with erase sector operation
while (Fapi_checkFsmForReady() != Fapi_Status_FsmReady) {}
if(oReturnCheck != Fapi_Status_Success)
{
printf("Error: EraseSector failed with status %d\n", oReturnCheck);
Example_Error(oReturnCheck); // 确保在擦除失败时停止执行
}//是否完成擦除操作
接下来是使用Fapi_getFsmStatus()返回FMSTAT寄存器的值来确认状态机是否完成了工作。(This register allows the user application to determine whether an erase or program operation is successfully completed or in progress or suspended or failed. The user application should check the value of this register to determine if there is any failure after each erase and program operation.)我觉得这里也可以直接使用Blankcheck函数通过判断扇区是否为blank来检查。只是Fapi_getFsmStatus()函数可以帮助我们返回更多的信息。
// Read FMSTAT register contents to know the status of FSM after erase
oFlashStatus = Fapi_getFsmStatus();
if(oFlashStatus != 0)
{
printf("Error: Fapi_initializeAPI failed with status %u\n", (unsigned int)oReturnCheck);
printf("FMSTAT: 0x%X\n", (unsigned int)oFlashStatus);
FMSTAT_Fail();
}//检查擦除后的闪存状态
else
{
printf("擦除完成");
printf("\n");
}
下面就进入到了'Program'环节,使用Fapi_issueProgrammingCommand()将数据写入到指定的扇区中:
for(u32Index = 0x84000; (u32Index < 0x84200) &&
(oReturnCheck == Fapi_Status_Success); u32Index+=8)
{
//
// Issue program command
//
oReturnCheck = Fapi_issueProgrammingCommand((uint32 *)u32Index, au16DataBuffer, 8,
0, 0, Fapi_AutoEccGeneration);
while (Fapi_checkFsmForReady() != Fapi_Status_FsmReady){}
if(oReturnCheck != Fapi_Status_Success)
{
Example_Error (oReturnCheck);
}
下图是手册中对该函数参数的介绍:
最后是对整个操作进行确认(verify),使用Fapi_doVerify()函数来确认写入是否正确:
// Verify the programmed values
oReturnCheck = Fapi_doVerify((uint32 *)u32Index, 4, Buffer32 + (i / 2), &oFlashStatusWord);
if(oReturnCheck != Fapi_Status_Success)
{
printf("Error: EraseSector failed with status %u\n", (unsigned int)oReturnCheck);
Example_Error(oReturnCheck);
}
else{
printf("写入正确");
printf("\n");
}
以上就是一个简单的Flash操作过程。
目前在代码中遇到一个问题:例程给出的扇区是bank0_sector6,修改为sector7可以正常运行,但是修改为sector2就会直接进入中断无法运行。