主题:controlSUITE中讨论的其他部件
工具/软件:Code Composer Studio
我在使用F2.8377万S芯片的闪存API工具时遇到了问题。 当调试闪存库0的读/写时,可以无故障地工作,但是当系统重新启动时,闪存API erase命令无法擦除有问题的扇区(任何扇区),并且生成的唯一错误是fmstat 0x0C10,它对应于erase verify和command fail。 如果我尝试对已清理的扇区进行编程, 则Fapi_issueProgrammingCommand调用将无法保存新数据。 生成的错误代码是两次出现的通用500错误。 当我逐行浏览至erase命令时,所有寄存器似乎都已正确设置。 我在程序中没有使用ECC或DCSM。 在执行实际的主程序代码之前,所有函数都在SectionCopy.asm中从闪存移至RAM,并且我已通过内存浏览器验证所有这些函数都已正确复制到ram。 由于我正在开发的系统要求具有可变操作设置的持久内存,因此应该采取哪些进一步的步骤来解决此问题。 我不能提供完整的代码块,但我会提供一些我当前在保存到闪存功能中的片段,因为它的大部分内容是从控制套件中的示例代码中提取的, 除了一些诊断输出代码之外,我还添加了一些诊断代码,以诊断故障点可能在哪里,并且大多数情况下已被注释掉。 我在多个器件上试用过此代码,甚至在TI-2.8377万s Launchpad上也试用过,但每个器件的结果都相同。 我主要担心的是调试器正在预加载某些内容,但在关闭电源后无法有效地将其恢复到RAM。 现在应该考虑什么来尝试诊断此故障?
此函数的关联代码块错误:
//禁用ECC。 ECC不必禁用即可执行FSM操作
//编程并擦除。
//然而,由于OTP ECC勘误,在Sonata Rev. 0芯片上,
//在使用Flash API函数时,禁用ECC以避免ECC错误
//读取TI-OTP
EALLOW;
// DcsmCommonRegs.FLSEM.ALL = 0x0A503;
Flash0EccRegs.ecc_enable.bit.enable = 0x00;
Flash0CtrlRegs.FRDCNTL.bit.RWAIT = 0x3;
Flash0CtrlRegs.FBAC.ALL = 0x14;
// Flash0CtrlRegs.FRD_INTF_CTRL.ALL = 0x3;
EDIS;
//
// Bank0擦除程序
//
EALLOW;
//
//将泵所有权授予FMC0
//
PUMPPREQUEST = 0x5A5A0002;
//
//此函数是初始化基于系统的Flash API所必需的
//执行任何其他Flash API操作之前的频率
//请注意,FMC0寄存器基本地址作为参数传递
//
oReturnCheck = Fapi_initializeAPI(F021_CPU0_W0_base_address, 194);
IF (oReturnCheck!= Fapi_Status_Success)
{
//
//查看Flash API文档以了解可能的错误
//
示例_错误(oReturnCheck);
// UARTprintf ("初始错误:%x,%x,%x\n",sectorIndex,sectorLength,dataBlockIndex);
返回;
}
/// UARTprintf ("初始通道:%x,%x,%x\n",sectorIndex,sectorLength,dataBlockIndex);
//
// Fapi_setActiveFlashBank函数为设置Flash Bank0和FMC0
//要在bank0上执行的其他闪存操作。
//请注意,传递的参数是Fapi_FlashBank0,因为FMC0寄存器
//基本地址被传递到Fapi_initializeAPI()
//
oReturnCheck = Fapi_setActiveFlashBank(Fapi_FlashBank0);
IF (oReturnCheck!= Fapi_Status_Success)
{
//
//查看Flash API文档以了解可能的错误
//
示例_错误(oReturnCheck);
// UARTprintf ("设置操作失败:%x,%x,%x\n",sectorIndex,sectorLength,dataBlockIndex);
返回;
}
// UARTprintf ("设置动作通过:%x,%x,%x\n",sectorIndex,sectorLength,dataBlockIndex);
//
//擦除扇区
//
// UINT32 *参考;
// for (i=0;i <= sectorLength;i+= 16)
// {
// ref =(sectorIndex + I);
// UARTprintf ("扇区预置:0x%x,0x%x,0x%x of 0x%x\n",*参考,参考,i, 截面长度);
// }
oReturnCheck = Fapi_issue3cCommandWithAddress(Fapi_EraseSector,
(UINT32 *)部门索引);
// for (i=0;i <= sectorLength;i+=16)
// {
// ref =(sectorIndex + I);
// UARTprintf ("扇区POST:0x%x,0x%x,0x%x of 0x%x\n",*参考,参考,i, 截面长度);
// }
//
//等待FSM完成擦除扇区操作
//
while (Fapi_checkFsmForReady()!= Fapi_Status_FsmReady){}
// UARTprintf ("擦除完成:%x,%x,%x\n",sectorIndex,sectorLength,dataBlockIndex);
//
//验证SectorL是否已擦除。 擦除步骤本身执行
//在运行时进行验证。 此验证是可以执行的第二次验证。
//
oReturnCheck = Fapi_doBlankCheck(UINT32 *)sectorIndex,
截面长度,
&oFlashStatusWord);
IF (oReturnCheck!= Fapi_Status_Success)
{
//
//查看Flash API文档以了解可能的错误
//如果Erase命令失败,请使用Fapi_getFsmStatus()函数获取
// fmstat寄存器内容,查看是否有EV位,ESUSP位,
//设置Cstat位或VOLTSTAT位(请参阅API文档了解
//更多详细信息)
//
示例_错误(oReturnCheck);
// UARTprintf ("擦除程序失败:%x,%x,%x\n",sectorIndex,sectorLength,dataBlockIndex);
返回;
}
// UARTprintf ("擦除程序通过:%x,%x,%x\n",sectorIndex,sectorLength,dataBlockIndex);
//
//可以为程序功能提供最多8个字的数据缓冲区。
//每个单词都被编程,直到整个缓冲区被编程或
//发现问题。 但是,要对大于8的缓冲区进行编程
//单词,程序函数可以循环调用,为进行8个单词的编程
//每次循环迭代,直到对整个缓冲区进行编程
//
//
//示例:将闪存扇区C中的0xFF字节与auto--
//生成的ECC
//
//
//在这种情况下,只需用数据填充缓冲区,即可编程到闪存中。
//
// for (i=0;i<=剑_in_flash_buffer;i++)
// {
// 缓冲[i]= i;
// }
对于(j=0; j<=blocksize;j+=256)
{
对于(i=0;i<=剑_闪_缓冲;i++)
{
IF ((i+j)<块大小)
{
缓冲区[i]=*(dataBlockIndex+i+j);
}
否则
{
缓冲区[i]= 0xFFFF;
}
// UARTprintf ("已加载缓冲区:%u,0 % ,0 % .1c",.1cn,i,j, 缓冲区[I]);
}
对于(i=0,u32Index = sectorIndex + j;
(u32Index <(sectorIndex + j +剑_闪_缓冲))&&
(oReturnCheck == Fapi_Status_Success);i+=8,u32Index+=8)
{
oReturnCheck = Fapi_issueProgrammingCommand ((UINT32 *) u32Index,Buffer+I,
8,0,0,
FAPI_DataOnly);
while (Fapi_checkFsmForReady()== Fapi_Status_FsmBusy);
IF (oReturnCheck!= Fapi_Status_Success)
{
//
//查看Flash API文档以了解可能的错误
//
示例_错误(oReturnCheck);
// UARTprintf ("程序失败:%x,%x,%x\n",sectorIndex,sectorLength,dataBlockIndex);
返回;
}
// UARTprintf ("程序通过:%x,%x,%x\n",sectorIndex,sectorLength,dataBlockIndex);
//
//读取fmstat寄存器内容以了解FSM的状态
// program命令进行任何调试
//
oFlashStatus = Fapi_getFsmStatus();
//
//验证编程的值。 程序步骤本身进行验证
//。 此验证是可以执行的第二次验证。
//
oReturnCheck = Fapi_doVerify(UINT32 *)u32Index,4,Buffer32+(I/2),
&oFlashStatusWord);
IF (oReturnCheck!= Fapi_Status_Success)
{
//
//查看Flash API文档以了解可能的错误
//
示例_错误(oReturnCheck);
// UARTprintf ("最终失败:%x,%x,%x\n",sectorIndex,sectorLength,dataBlockIndex);
返回;
}
// UARTprintf ("最终路径:%x,%x,%x\n",sectorIndex,sectorLength,dataBlockIndex);
}
提前感谢!
意愿