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.

TMS320F28075: 重新上电以后FLASH无法擦除编程问题

Part Number: TMS320F28075
Other Parts Discussed in Thread: C2000WARE

F021库版本为1.54,功能是在固件中擦除并重新编程某些扇区,用于参数保存,固件升级等。

目前现象是:使用CCS加载.out文件,然后直接运行,FLASH擦除编程一切正常。

同样的工程同样的cmd和out文件,使用CCS加载以后,然后拔掉仿真器重新上电,FLASH会进入一种类似“锁死”的状态,无法擦除也无法编程。

检查擦除以后Fapi_getFsmStatus的返回值,擦除空Sector返回0x0810,擦除非空Sector返回0x0C10,根据FMSTAT寄存器描述:spruhm9f文档的3.15.21.6节

涉及FMSTAT的三个位:

  • bit11 文档上是保留的
  • bit10 EV表示擦除有错误
  • bit4 CSTAT表示执行命令有错误

这几个位只是告诉用户出错了,具体什么错误并没有描述,并且bit11是保留的,文档并没有描述,对问题诊断并没有太大意义。

查看两种情况下的FLASH寄存器:

```
#重新上电无法擦除FLASH时FLASH控制寄存器
0x05F800 0200 0000 0000 0000 0000 0000 0000 0000
0x05F808 0000 0000 0000 0000 0000 0000 0000 0000
0x05F810 0000 0000 0000 0000 0000 0000 0000 0000
0x05F818 0000 0000 0000 0000 0000 0000 000F 0000
0x05F820 0003 0000 8001 0000 0001 0860 0000 0000
0x05F828 0000 0000 0000 0000 0000 0000 0000 0000
0x05F830 00FC 0000 55AA 0000 0000 0000 0000 0000
0x05F838 0000 0000 0000 0000 0000 0000 0000 0000
0x05F840 000B 0000 0055 00EB 0000 00DB 0000 000F
0x05F848 0716 0000 A000 0000 0004 0000 010A 0700
#CCS加载正常擦除时FLASH控制寄存器
0x05F800 0200 0000 0000 0000 0000 0000 0000 0000
0x05F808 0000 0000 0000 0000 0000 0000 0000 0000
0x05F810 0000 0000 0000 0000 0000 0000 0000 0000
0x05F818 0000 0000 0000 0000 0000 0000 000F 0000
0x05F820 0003 0000 8001 0000 0001 0860 0000 0000
0x05F828 0000 0000 0000 0000 0000 0000 0000 0000
0x05F830 00FC 0000 0000 0000 0000 0000 0000 0000
0x05F838 0000 0000 0000 0000 0000 0000 0000 0000
0x05F840 000B 0000 008C 01E9 0000 01BE 0000 0000
0x05F848 071B 0000 9000 0000 0004 0000 010A 0700
```

文档上列出的寄存器并没有明显异常,但是确实有一些地址不同,这些地址没有文档描述。

如何进一步诊断这个问题呢?

  • 补充一下,FlashAPI和其它FLASH相关代码都在SRAM中,重新上电以后只是FLASH无法正常擦除编程,固件其它功能都没问题,包括FLASH读取。

    在使用F28075之前,同样的代码都在F280049上使用过,没有任何问题。这次只是更换了FlashAPI,两者的FlashAPI很像,但是又不完全相同。不知道为何F28075会遇到这么多问题。

  • 还有个问题比较疑惑,之前二代C2K芯片比如28335,28035之类的芯片,内部使用NOR FLASH,虽然擦除慢了些,使用上还是很省心的,基本没出过什么问题。
    三代的C2K芯片比如280049/28377/28075可能是更换了NAND FLASH,文档和FlashAPI中大段的篇幅都在讲ECC,其实用户并不太关心ECC问题,这种细节厂商内部封装好就行了,完全没必要暴露给客户,其它的MCU,比如ARM,内部FLASH和SRAM也带校验,但是基本上细节都对用户屏蔽了。不知道三代C2K这么做的目的是什么。

  • 您好我们已收到您的问题并升级到英文论坛,温馨提示您由于圣诞节及新年假期,英文论坛回复将稍慢,敬请谅解!

  • 是否可以提供0x5F800地址处的FLASH寄存器更详细一点的描述?用于进一步诊断。

    或者说CCS加载固件和上电自举运行对FLASH来说哪里会有不同?两种情况下,只有FLASH擦除编程有异常。

  • 您好,关于您的问题已帮您升级英文论坛,温馨提示您英文论坛的回复由于假期将会稍慢,敬请谅解!为了更好地管理论坛,我们会将该帖先关闭,如您还需其他帮助请随时联系我们:

    e2e.ti.com/.../tms320f28075-flash-cannot-erase-programming-after-power-up

  • hi,英文论坛有回复,本来我要直接回复的,提示必须有公司邮箱,我无法回复。因此麻烦帮忙回复一下。

    他文EALLOW/EDIS有没有加,实际我肯定是加了的,而且文章已经提到使用CCS加载.out文件,然后直接运行,FLASH擦除编程一切正常的。如果没有EALLOW/EDIS,CCS直接加载也应该不行对吧?

  • 您好,CCS flash load是由于 TI开发的CCS 闪存插件而产生的。 工程师其实是想问下您的应用程序对闪存 API 的使用情况。

  • 我表达的可能不够清楚。我说的擦除flash是在ccs加载完程序以后运行程序,然后用SCIA连入芯片,输入一个命令擦除的。执行这个擦除命令的时候ccs已经加载完程序了。但是我ccs加载完同一个.out固件,重新断电上电,再执行擦除命令就不行了。

    应用程序对闪存API访问是加了EALLOW和EDIS的。如果我代码中不加的话,在ccs加载完out文件以后,直接运行和重新上电运行,我通过串口输入的擦除命令应该都无法擦除FLASH。

  • 这是初始化FlashAPI和擦除扇区使用的函数,都加了EALLOW和EDIS。

    #pragma CODE_SECTION(InitFlashAPI,".TI.ramfunc");
    Fapi_StatusType InitFlashAPI(void)
    {
    	Fapi_StatusType st = Fapi_Status_Success;
    
    	EALLOW;
    
    	// 使用INTOSC2,PLL主频120M,120*1.03 = 123.6,取124
    	st = Fapi_initializeAPI(F021_CPU0_BASE_ADDRESS, 124);
    	if (st != Fapi_Status_Success)
    	{
    		return st;
    	}
    
    	st = Fapi_setActiveFlashBank(Fapi_FlashBank0);
    	if (st != Fapi_Status_Success)
    	{
    		return st;
    	}
    
    	EDIS;
    
    	return st;
    }
    
    
    #pragma CODE_SECTION(eraseFlashSector,".TI.ramfunc");
    Uint32 eraseFlashSector(Uint16 sector)
    {
    	Fapi_StatusType st;
    	Fapi_FlashStatusType fst;
    	Uint32 addr = 0;
    
    	if(sector < 'a' || sector > 'n')
    	{
    		return 0;
    	}
    
    	addr = flashSectorStart[sector - 'a'];
    
    	EALLOW;
    	st = Fapi_issueAsyncCommandWithAddress(Fapi_EraseSector, (uint32*)addr);
    	while (Fapi_checkFsmForReady() != Fapi_Status_FsmReady)
    	{
    		KickDog();
    	}
    	// FLASH0CTRL_BASE = 0x05F800 FMSTAT偏移量0x2A
    	// FMSTAT寄存器描述:spruhm9f文档的3.15.21.6节
    	// 擦除空Sector返回0x0810,擦除非空Sector返回0x0C10
    	fst = Fapi_getFsmStatus();
    	EDIS;
    
    	if(st != Fapi_Status_Success || fst != 0)
    	{
    		addr = 0;
    		printx("st=0x____ ", st);
    		printx("fst=0x________\r\n", fst);
    	}
    
    	return addr;
    }

  • 您好,在擦除之前,器件是secured吗? 无法从上述代码中擦除时, CCS 闪存插件是能够成功擦除是吗?

  • 肯定不是secured呀,从来没开启过安全模块,而且软件开发阶段,secure功能没有人打开的。我以为这个是大家都知道的常识,所以就没提。

    CCS肯定能擦除,因为我已经成功Load固件并运行了,Load的第一步就是擦除,CCS也免不了的。

  • Can customer try the flash programming example from C2000Ware and see whether it is able to erase the flash successfully or not?  This helps us to know whether it is code problem or something else.

    C2000Ware的demo测试过没有问题,但是那个demo只能用CCS加载运行,我工程中CCS直接加载也没有问题。所以这没有什么帮助。

    是这个demo:C2000Ware_4_00_00_00\device_support\f2807x\examples\cpu1\flash_programming\cpu01

  • Can you send a project that I can build and run on my side?  Please remove all the proprietary info.

    代码本身比较大,包括解析用户命令擦除这部分,抱歉不能公开,去掉又无法复现这个问题,感觉死循环了。

  • 280049和28075这两款芯片同属第三代的C28x,FLASH都是NAND,都有ECC,他们的FlashAPI也都是F021库,然而一个是库来管理EALLOW/EDIS,另外一个却要让用户来管理EALLOW/EDIS,如此割裂的行为除了给用户带来麻烦并没有什么好处。

  • 您好这个帮您反馈下,您的意见我们已收到哈,非常抱歉给您带来的不便。

  • 您好,英文论坛这边针对您的反馈工程师给出了一些答复,您可以看下。

    如果您无法公开project,您请参考以下回复中提供的方法:

    e2e.ti.com/.../3950204

  • 我看过了,并没有什么帮助。

    目前唯一的线索就是同样一个.out目标文件,使用ccs load进去直接运行可以正常擦除FLASH,重新上上电就无法擦除了。而且如果是用第三方的工具比如C2Prog烧录那个.out文件,烧录完成以后不断电直接运行,也是无法擦除FLASH的,显然ccs在load目标文件的时候做了额外的一些事情,我想知道它做了什么额外的工作导致可以擦除FLASH。

    我看了f28075.gel这个文件的内容,它的OnReset()函数中有个SetupDCSM()设置加密模块DCSM的操作,怀疑和加密有关,我把它去掉,ccs加载仍然可以正常擦除,说明和DCSM关系不大。我的工程并没有使用DCSM来加密,这种情况下,是否还需要额外的工作来保证FLASH可擦除吗?

  • 如果不使用DCSM来加密的话,初始化的时候是否要调用DCSM_unlockZone1CSM()通过全FF的密码来解密呢?

  • 这里似乎无法直接上传文件作为附件?那只好贴代码了,代码是精简过的,去掉了不相关的内容。

    HAL.c文件,包括了函数的初始化。

    #include <hal.h>
    
    //*****************************************************************************
    //
    // Function to initialize the device. Primarily initializes system control to a
    // known state by disabling the watchdog, setting up the SYSCLKOUT frequency,
    // and enabling the clocks to the peripherals.
    //
    //*****************************************************************************
    void Device_init(void)
    {
    	SysCtl_disableWatchdog();
    
    #ifdef _FLASH
    	//
    	// Copy time critical code and flash setup code to RAM. This includes the
    	// following functions: InitFlash();
    	//
    	// The RamfuncsLoadStart, RamfuncsLoadSize, and RamfuncsRunStart symbols
    	// are created by the linker. Refer to the device .cmd file.
    	//
    	//memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (size_t) &RamfuncsLoadSize);
    #endif
    
    	//
    	// Set up PLL control and clock dividers
    	//
    	SysCtl_setClock(DEVICE_SETCLOCK_CFG);
    
    	//
    	// Make sure the LSPCLK divider is set to the default (divide by 4)
    	//
    	SysCtl_setLowSpeedClock(SYSCTL_LSPCLK_PRESCALE_4);
    
    	//
    	// These asserts will check that the #defines for the clock rates in
    	// device.h match the actual rates that have been configured. If they do
    	// not match, check that the calculations of DEVICE_SYSCLK_FREQ and
    	// DEVICE_LSPCLK_FREQ are accurate. Some examples will not perform as
    	// expected if these are not correct.
    	//
    	ASSERT(SysCtl_getClock(DEVICE_OSCSRC_FREQ) == DEVICE_SYSCLK_FREQ);
    	ASSERT(SysCtl_getLowSpeedClock(DEVICE_OSCSRC_FREQ) == DEVICE_LSPCLK_FREQ);
    
    	//
    	// Call Flash Initialization to setup flash waitstates. This function must
    	// reside in RAM.
    	//
    	Flash_initModule(FLASH0CTRL_BASE, FLASH0ECC_BASE, DEVICE_FLASH_WAITSTATES);
    
    	//
    	// Turn on all peripherals
    	//
    	Device_enableAllPeripherals();
    }
    
    //*****************************************************************************
    //
    // Function to turn on all peripherals, enabling reads and writes to the
    // peripherals' registers.
    //
    // Note that to reduce power, unused peripherals should be disabled.
    //
    //*****************************************************************************
    void Device_enableAllPeripherals(void)
    {
    #if 1
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TIMER0);
    
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_SCIA);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_SCIB);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_SCIC);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_SCID);
    #else
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_CLA1);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_DMA);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TIMER0);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TIMER1);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TIMER2);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_HRPWM);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);
    
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EMIF1);
    
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EPWM1);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EPWM2);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EPWM3);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EPWM4);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EPWM5);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EPWM6);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EPWM7);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EPWM8);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EPWM9);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EPWM10);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EPWM11);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EPWM12);
    
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_ECAP1);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_ECAP2);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_ECAP3);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_ECAP4);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_ECAP5);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_ECAP6);
    
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EQEP1);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EQEP2);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EQEP3);
    
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_SD1);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_SD2);
    
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_SCIA);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_SCIB);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_SCIC);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_SCID);
    
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_SPIA);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_SPIB);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_SPIC);
    
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_I2CA);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_I2CB);
    
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_CANA);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_CANB);
    
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_MCBSPA);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_MCBSPB);
    
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_USBA);
    
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_ADCA);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_ADCB);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_ADCD);
    
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_CMPSS1);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_CMPSS2);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_CMPSS3);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_CMPSS4);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_CMPSS5);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_CMPSS6);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_CMPSS7);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_CMPSS8);
    
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_DACA);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_DACB);
    #endif
    }
    
    //*****************************************************************************
    //
    // Function to disable pin locks and enable pullups on GPIOs.
    //
    //*****************************************************************************
    void Device_initGPIO(void)
    {
    
    }
    
    #pragma CODE_SECTION(InitFlashAPI,".TI.ramfunc");
    Fapi_StatusType InitFlashAPI(void)
    {
    	Fapi_StatusType st = Fapi_Status_Success;
    
    	EALLOW;
    
    	// 使用INTOSC2,PLL主频120M,120*1.03 = 123.6,取124
    	st = Fapi_initializeAPI(F021_CPU0_BASE_ADDRESS, 124);
    	if (st != Fapi_Status_Success)
    	{
    		return st;
    	}
    
    	st = Fapi_setActiveFlashBank(Fapi_FlashBank0);
    	if (st != Fapi_Status_Success)
    	{
    		return st;
    	}
    
    	EDIS;
    
    	return st;
    }
    
    // sector = a-n
    #pragma CODE_SECTION(eraseFlashSector,".TI.ramfunc");
    Uint32 eraseFlashSector(Uint16 sector)
    {
    	Fapi_StatusType st;
    	Fapi_FlashStatusType fst;
    	Uint32 addr = 0;
    
    	if(sector < 'a' || sector > 'n')
    	{
    		return 0;
    	}
    
    	addr = flashSectorStart[sector - 'a'];
    
    	EALLOW;
    	st = Fapi_issueAsyncCommandWithAddress(Fapi_EraseSector, (uint32*)addr);
    	while (Fapi_checkFsmForReady() != Fapi_Status_FsmReady)
    	{
    		KickDog();
    	}
    	// FLASH0CTRL_BASE = 0x05F800 FMSTAT偏移量0x2A
    	// FMSTAT寄存器描述:spruhm9f文档的3.15.21.6节
    	// 擦除空Sector返回0x0810,擦除非空Sector返回0x0C10
    	fst = Fapi_getFsmStatus();
    	EDIS;
    
    	if(st != Fapi_Status_Success || fst != 0)
    	{
    		addr = 0;
    		printx("st=0x____ ", st);
    		printx("fst=0x________\r\n", fst);
    	}
    
    	return addr;
    }
    
    //*****************************************************************************
    //
    // Error handling function to be called when an ASSERT is violated
    //
    //*****************************************************************************
    #pragma CODE_SECTION(__error__,".TI.ramfunc");
    void __error__(char *filename, uint32_t line)
    {
    	//
    	// An ASSERT condition was evaluated as false. You can use the filename and
    	// line parameters to determine what went wrong.
    	//
    	ESTOP0;
    }
    
    // initCPUTimers - This function initializes all three CPU timers
    // to a known state.
    void initCPUTimers(void)
    {
    	//
    	// Initialize timer period to maximum
    	//
    	CPUTimer_setPeriod(CPUTIMER0_BASE, 0xFFFFFFFF);
    	CPUTimer_setPeriod(CPUTIMER1_BASE, 0xFFFFFFFF);
    	CPUTimer_setPeriod(CPUTIMER2_BASE, 0xFFFFFFFF);
    
    	//
    	// Initialize pre-scale counter to divide by 1 (SYSCLKOUT)
    	//
    	CPUTimer_setPreScaler(CPUTIMER0_BASE, 0);
    	CPUTimer_setPreScaler(CPUTIMER1_BASE, 0);
    	CPUTimer_setPreScaler(CPUTIMER2_BASE, 0);
    
    	//
    	// Make sure timer is stopped
    	//
    	CPUTimer_stopTimer(CPUTIMER0_BASE);
    	CPUTimer_stopTimer(CPUTIMER1_BASE);
    	CPUTimer_stopTimer(CPUTIMER2_BASE);
    
    	//
    	// Reload all counter register with period value
    	//
    	CPUTimer_reloadTimerCounter(CPUTIMER0_BASE);
    	CPUTimer_reloadTimerCounter(CPUTIMER1_BASE);
    	CPUTimer_reloadTimerCounter(CPUTIMER2_BASE);
    }
    
    // configCPUTimer - This function initializes the selected timer to the
    // period specified by the "freq" and "period" parameters. The "freq" is
    // entered as Hz and the period in uSeconds. The timer is held in the stopped
    // state after configuration.
    void configCPUTimer(uint32_t cpuTimer, float freq, float period)
    {
    	uint32_t temp;
    
    	//
    	// Initialize timer period:
    	//
    	temp = (uint32_t) (freq / 1000000 * period);
    	CPUTimer_setPeriod(cpuTimer, temp);
    
    	//
    	// Set pre-scale counter to divide by 1 (SYSCLKOUT):
    	//
    	CPUTimer_setPreScaler(cpuTimer, 0);
    
    	//
    	// Initializes timer control register. The timer is stopped, reloaded,
    	// free run disabled, and interrupt enabled.
    	// Additionally, the free and soft bits are set
    	//
    	CPUTimer_stopTimer(cpuTimer);
    	CPUTimer_reloadTimerCounter(cpuTimer);
    	CPUTimer_setEmulationMode(cpuTimer,
    			CPUTIMER_EMULATIONMODE_STOPAFTERNEXTDECREMENT);
    	CPUTimer_enableInterrupt(cpuTimer);
    }
    
    
    #pragma CODE_SECTION(DELAY_MS,".TI.ramfunc");
    void DELAY_MS(Uint16 n)
    {
    	while(n--)
    	{
    		KickDog();
    		DEVICE_DELAY_US(500);
    		KickDog();
    		DEVICE_DELAY_US(500);
    	}
    }
    
    #pragma CODE_SECTION(SystemReset,".TI.ramfunc");
    void SystemReset(void)
    {
    	SysCtl_resetDevice();
    }
    
    const Uint32 flashSectorStart[14] =
    {
    	0x080000, 0x082000, 0x084000, 0x086000,
    	0x088000, 0x090000, 0x098000, 0x0A0000, 0x0A8000, 0x0B0000,
    	0x0B8000, 0x0BA000, 0x0BC000, 0x0BE000
    };
    const Uint32 flashSectorSize[14] =
    {
    	0x2000, 0x2000, 0x2000, 0x2000,
    	0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
    	0x2000, 0x2000, 0x2000, 0x2000,
    };
    
    #pragma CODE_SECTION(isFlashEmpty,".TI.ramfunc");
    Uint32 isFlashEmpty(Uint32 start, Uint32 len)
    {
    	Fapi_FlashStatusWordType fswt;
    	Fapi_StatusType st;
    
    	EALLOW;
    	st = Fapi_doBlankCheck((Uint32 *)start, len>>1, &fswt);
    	EDIS;
    
    	if(Fapi_Status_Success == st)
    	{
    		return 0;
    	}
    	else
    	{
    		return fswt.au32StatusWord[0];
    	}
    }
    
    //
    // Fapi_serviceWatchdogTimer - Watchdog servicing function
    //
    #pragma CODE_SECTION(Fapi_serviceWatchdogTimer,".TI.ramfunc");
    Fapi_StatusType Fapi_serviceWatchdogTimer(void)
    {
       //
       // User to add their own watchdog servicing code here
       //
       KickDog();
       return(Fapi_Status_Success);
    }
    
    //
    // Fapi_setupEepromSectorEnable - Enables EEPROM sectors for bank and sector
    //                                erase
    //
    #pragma CODE_SECTION(Fapi_setupEepromSectorEnable,".TI.ramfunc");
    Fapi_StatusType Fapi_setupEepromSectorEnable(void)
    {
       //
       // Value must be 0xFFFF to enable erase and programming of the
       // EEPROM bank, 0 to disable
       //
       Fapi_GlobalInit.m_poFlashControlRegisters->Fbse.u32Register = 0xFFFF;
    
       //
       // Enables sectors 32-63 for bank and sector erase
       //
       FAPI_WRITE_LOCKED_FSM_REGISTER(Fapi_GlobalInit.m_poFlashControlRegisters->FsmSector.u32Register,
                                      0x0U);
    
       //
       // Enables sectors 0-31 for bank and sector erase
       //
       FAPI_WRITE_LOCKED_FSM_REGISTER(Fapi_GlobalInit.m_poFlashControlRegisters->FsmSector1.u32Register,
                                      0x0U);
    
       //
       // Enables sectors 32-63 for bank and sector erase
       //
       FAPI_WRITE_LOCKED_FSM_REGISTER(Fapi_GlobalInit.m_poFlashControlRegisters->FsmSector2.u32Register,
                                      0x0U);
    
       return(Fapi_Status_Success);
    }
    
    //
    // Fapi_setupBankSectorEnable - Setup and enable bank sectors 0-15
    //
    #pragma CODE_SECTION(Fapi_setupBankSectorEnable,".TI.ramfunc");
    Fapi_StatusType Fapi_setupBankSectorEnable(void)
    {
       //
       // Enable sectors 0-15 for erase and programming
       //
       Fapi_GlobalInit.m_poFlashControlRegisters->Fbse.u32Register = 0xFFFF;
       FAPI_WRITE_LOCKED_FSM_REGISTER(Fapi_GlobalInit.m_poFlashControlRegisters->FsmSector.u32Register,
                                      0x0U);
    
       return(Fapi_Status_Success);
    }

    main.c运行逻辑

    #include <hal.h>
    #include <string.h>
    #include <stdlib.h>
    #include <stdint.h>
    #include <stdio.h>
    #include "main.h"
    #include "syscall.h"
    #include "util.h"
    
    
    void main(void)
    {
    //	CopyLibrary();
    	Device_init();
    	Device_initGPIO();
    	InitFlashAPI();
    	EEPROM_Init();
    	EEPROM_Load();
    	initCPUTimers();
    	configCPUTimer(CPUTIMER0_BASE, DEVICE_SYSCLK_FREQ, 10000);	// 10ms sysTick
    	Interrupt_initModule();
    	Interrupt_initVectorTable();
    	InitSystem();
    	Run();
    }
    
    void InitSystem(void)
    {
    	BOOL isSave = FALSE;
    
    	Interrupt_register(INT_TIMER0,  &cpuTimer0ISR);
    	Interrupt_enable(INT_TIMER0);
    
    	Interrupt_enableInCPU(INTERRUPT_CPU_INT1);
    	Interrupt_enableInCPU(INTERRUPT_CPU_INT8);
    	Interrupt_enableInCPU(INTERRUPT_CPU_INT9);
    
    	EINT;
    	ERTM;
    
    	if(isSave)
    	{
    		EEPROM_Save();
    	}
    }
    
    #pragma CODE_SECTION(CleanUp,".TI.ramfunc");
    void CleanUp(void)
    {
    //	DeInitECana();
    	CPUTimer_stopTimer(CPUTIMER0_BASE);
    	__disable_interrupts();
    	SysCtl_disableWatchdog();
    }
    
    #pragma CODE_SECTION(Run,".TI.ramfunc");
    void Run(void)
    {
    	BOOL isRunUserApp = TRUE;
    
    	LED_ON();
    	CPUTimer_startTimer(CPUTIMER0_BASE);
    
    	SysCtl_setWatchdogPrescaler(SYSCTL_WD_PRESCALE_64);
    	SysCtl_enableWatchdog();
    
    	while(TRUE)
    	{
    		tskSyscall(&scia);
    		tskSyscall(&scib);
    		tskSyscall(&scic);
    		KickDog();
    	}
    }
    
    #pragma CODE_SECTION(cpuTimer0ISR,".TI.ramfunc");
    __interrupt void cpuTimer0ISR(void)
    {
    	ymodem.timeout++;
    	sysTickTimer++;
    	if(sysTickTimer > 50)
    	{
    		LED_SET(sysTickTimer&0x40);
    	}
    	Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP1);
    }
    
    // SCIA
    #pragma CODE_SECTION(sciaRxISR,".TI.ramfunc");
    __interrupt void sciaRxISR(void)
    {
    	CONSOLE_REGS *sci = &scia;
    	if(UART_SCIA == (consoleMask & UART_SCIA))
    	{
    		if((HWREGH(sci->iface.sci + SCI_O_RXST) & SCI_RXST_RXRDY) == SCI_RXST_RXRDY)
    		{
    			consoleUsed = UART_SCIA;
    		}
    		tskRecvSciData(sci);
    	}
    	Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9);
    }
    
    // SCIB
    #pragma CODE_SECTION(scibRxISR,".TI.ramfunc");
    __interrupt void scibRxISR(void)
    {
    	CONSOLE_REGS *sci = &scib;
    
    	if(UART_SCIB == (consoleMask & UART_SCIB))
    	{
    		if((HWREGH(sci->iface.sci + SCI_O_RXST) & SCI_RXST_RXRDY) == SCI_RXST_RXRDY)
    		{
    			consoleUsed = UART_SCIB;
    		}
    		tskRecvSciData(sci);
    	}
    	Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9);
    }
    
    // SCIC
    #pragma CODE_SECTION(scicRxISR,".TI.ramfunc");
    __interrupt void scicRxISR(void)
    {
    	CONSOLE_REGS *sci = &scic;
    
    	if(UART_SCIC == (consoleMask & UART_SCIC))
    	{
    		if((HWREGH(sci->iface.sci + SCI_O_RXST) & SCI_RXST_RXRDY) == SCI_RXST_RXRDY)
    		{
    			consoleUsed = UART_SCIC;
    		}
    		tskRecvSciData(sci);
    	}
    	Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP8);
    }
    
    
    

  • 擦除出错,返回的故障代码本来应该对定位问题有很大帮助,然而实际返回的bit4和bit10并没有什么参考价值,只是告诉用户出错了,具体什么错误没有提。

    bit11文档并没有描述,关于FLASH操作寄存器是否有进一步的文档描述?可以看到两种情况下寄存器地址是有差异的。

  • 1) #define DEVICE_FLASH_WAITSTATES 2

    2)124M和120M都试过,没有差别,请尽快更新文档

    5)The boot ROM code does this dummy read for covenience. 所以用户代码不需要特殊处理?

    6)the flash erase is not successful after the power up, means running it standalone (in flash boot mode) 

  • 经过千辛万苦,无数次尝试,问题解决了,具体原因,我也说不清楚,毕竟FlashAPI是个黑盒子,看不到内部细节。

    方法:去掉FlashAPI中看门狗回调函数Fapi_serviceWatchdogTimer()中的踢狗操作就没有问题了。

    本帖子前面的代码中有,KickDog是个宏定义,展开以后SysCtl_serviceWatchdog,这算是官方给客户挖的坑吗?

  • //
    // Fapi_serviceWatchdogTimer - Watchdog servicing function
    //
    #pragma CODE_SECTION(Fapi_serviceWatchdogTimer,".TI.ramfunc");
    Fapi_StatusType Fapi_serviceWatchdogTimer(void)
    {
       //
       // User to add their own watchdog servicing code here
       //
    
       return(Fapi_Status_Success);
    }

    就是这个函数,注释里面让客户添加自己的踢狗操作,加上SysCtl_serviceWatchdog()就会出现本帖中提到的奇怪bug

  • 好的感谢您的反馈,再次抱歉为您带来的不便。以上您提到的问题我们会尽快反馈到工程师,进一步改进并为用户带来更优的体验!再次感谢!