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.

F28035调用API函数Flash_Erase() 擦除片上FLASH返回错误值#21

Other Parts Discussed in Thread: MOTORWARE

目前在做一个基于CAN通讯的在线DSP升级程序,用到F28035芯片,在调用API函数进行数据擦除与写入的调试阶段遇到了问题,一直没有解决,还望TI大神以及做过相关技术工作的牛人们看到后予以解答。具体情况如下:

调用28035_API函数向FLASH扇区写入数据之前需要先进行对应扇区的擦除,在仿真器烧录后运行调试都正常,擦除和烧写实验成功,程序整体框架和函数都是参照TI官方API例程进行编写,调用API功能前运行DINT语句禁用了全局中断,可是程序脱离仿真环境复位重新加载以后,调用Flash_Erase()函数返回错误代码#21,对应STATUS_FAIL_PRECONDITION,Flash_DepRecover()函数调用也无法解决这个问题,计划擦除扇区为FLASHE(首地址为0x3EE000),可是Flash_Erase()函数中用于检测擦除状态的FLASH_ST变量FEraseStat返回的FirstFailAddr为0x3F0000,让人百思不得其解。请问这样的问题究竟如何解决?排除芯片本身的问题,可能的错误会出在哪里?

  • 你好

    请使用flash API V100a中的Flash2803x_API_V100.lib。不要使用2803x_FlashAPI_BootROMSymbols.lib。

    Victor

  • 您好,谢谢您的慷慨解答,问题目前已经解决了,28035由于API函数本身固化在BootRom当中,因此在尽量减小程序大小的目标下使用了2803x_FlashAPI_BootROMSymbols.lib,免去了api函数从flash向RAM的搬移工作,目前以此方式程序已经调通。

    接下来说一下前期我程序的问题,实际上是因为我个人没能区分清楚piccolo系列芯片与delfino系列的区别,我的程序原始是在28335中调试的,后来移植到035后,Flash_CPUScaleFactor = SCALE_FACTOR配置语句使用了EALLOW保护,而这样的配置在335芯片中是不需要的。

    一直没能注意到这个问题,把调试的重心放在了CMD以及初始化宏定义的纠错上,实际上把EALLOW和EDIS加上后,程序立刻就跑通了,不再出现重启后无法运行的情况,返回值也不在显示为#21

  • 碰到与您相同的问题,也是把EALLOW和EDIS加上后,程序立刻就跑通了。非常感谢您的分享。

  • 你好!我调试CAN Boot程序,读写flash是参照官方V130的例程Example_2803xFlashProgramming写的。现在擦写Flash时候,Status = Flash_Erase(SECTORG,&FlashStatus);返回191,Flash_CPUScaleFactor = SCALE_FACTOR把EALLOW和EDIS加上也还是不行。可否把你的程序给我参考一下啊,我对CAN BOOT还是不太懂,官网资料配合百度慢慢调试,感觉好难~我邮箱574404258@qq.com,QQ也是这个,可以的话麻烦指导一下,谢谢!!

  • 您好,我个人的程序涉及模块很多,不太方便分享,但就某一个.c文件而言,与官方例程没有本质差别。

    如果您仅仅是希望调试BootLoader更新功能的话,可以把您的程序段,主要是api.c和调用api功能的.c以及cmd文件打包发送给我,我有空帮您检查一下。

    而且我重新查询了一下状态反馈表,擦除报错返回值里并没有191,所以您的问题我目前也无法猜测原因。需要进一步联系,可以发送邮件至我个人邮箱,371661830@qq.com.

  • 您好!我问题已经解决了,但是原因还是不明白。具体解决就是main函数这段代码中,去掉DINT/EINT/ERTM就可以了,所有功能都还是可以正常运行,Flash也可以正常读写;加上的话运行到擦除Flash处就走不下去了,定时器任务也乱了 ,但是去掉Flash相关的操作加上DINT/EINT/ERTM,其他模块都可以正常运行。你看能帮忙分析下是什么原因吗?

    后续有问题再麻烦您多多指教!谢谢!

    InitSysCtrl(); //Initialize System Control

    DINT;

    InitPieCtrl(); //Initialize PIE control registers to their default state.
    IER = 0x0000; //Disable CPU interrupts and clear all CPU interrupt flags
    IFR = 0x0000; //Disable CPU interrupts and clear all CPU interrupt flags
    InitPieVectTable(); //Initialize the PIE vector table with pointers to the shell Interrupt

    Init_SCIA();
    Init_GPIO();
    Init_ECAN();
    Init_CpuTimers();
    // Init_I2C_Eeprom();
    SetupID(InitAddr()); //通过拨码开关设置模块地址号;
    EINT;
    ERTM;

    Status = Example_CsmUnlock();
    if(Status == STATUS_SUCCESS)
    {
    }

    // RAM拷贝
    MemCopy(&RamfuncsLoadStart, &RamfuncsLoadEnd, &RamfuncsRunStart);
    InitFlash();
    EALLOW;
    Flash_CPUScaleFactor = SCALE_FACTOR;
    EDIS;

    VersionHex = Flash_APIVersionHex();
    if(VersionHex != 0x0100)
    {
    }
    Version = Flash_APIVersion();
    if(Version != (float32)1.00)
    {
    }

    while(1)
    {
    CanBootLoad();
    }

  • 您好,我看了您的程序,其实问题非常清楚了——您在调用API功能时并没有禁用系统的全局中断,导致FLASH操作过程受到干扰,因此系统报错,无法正常运行。

    这里需要注意两个问题,

    一是您的EINT与ERTM这两个使能全局中断的指令应当放在RAM拷贝指令之后,在系统开机初期让程序不受外界打扰,专心搬移API功能到RAM中运行。

    二是封装好全部的API功能函数,随后在每次调用API功能前禁用中断,调用结束后,再进行使能,恢复中断,注意,必须是“每次”,API函数必须在没有外界中断干扰的情况下运行。

    具体的参考依据以及程序的简单样例我已截图在下方,您可以仔细阅读官方文件Flash2803x_API_usingCCS4.0v_Readme.pdf获取API功能使用的详细说明。

  • 你好,我想请教一下,在调用api函数的时候的,JTAG会对DSP造成影响吗?我现在的情况是,插上仿真器可以擦除flash,拔掉之后就无法擦除了,也不报错

  • 非常感谢楼主分享,我也碰到同样的问题,按照你的方法解决掉了,感谢感谢。

  • 您好,初用TI 的DSP,在使用Flash API也遇到了问题,在擦除flash时程序卡在了擦除函数那里,没有出来;解锁与读版本号正常,读版本号返回值为256;下面是我的程序,添加在motorware的lab 05b的例程里;期望得到您的回答。谢谢!


    #defineWORDS_IN_FLASH_BUFFER 0x100 // Programming data buffer, Words
    Uint16 Buffer[WORDS_IN_FLASH_BUFFER];

    typedef struct {
    Uint16 *StartAddr;
    Uint16 *EndAddr;
    } SECTOR;

    /*--- Global variables used to interface to the flash routines */
    FLASH_ST FlashStatus;

    #define FLASH_END_ADDR 0x3F7FFF
    #define FLASH_START_ADDR 0x3D8000
    SECTOR Sector[8]= {
    (Uint16 *) 0x3D8000,(Uint16 *) 0x3DBFFF,
    (Uint16 *) 0x3DC000,(Uint16 *) 0x3DFFFF,
    (Uint16 *) 0x3E0000,(Uint16 *) 0x3E3FFF,
    (Uint16 *) 0x3E4000,(Uint16 *) 0x3E7FFF,
    (Uint16 *) 0x3E8000,(Uint16 *) 0x3EBFFF,
    (Uint16 *) 0x3EC000,(Uint16 *) 0x3EFFFF,
    (Uint16 *) 0x3F0000,(Uint16 *) 0x3F3FFF,
    (Uint16 *) 0x3F4000,(Uint16 *) 0x3F7FFF,
    };
    //----------------------------------------

    #pragma DATA_SECTION("CsmPwlFile")
    volatile struct CSM_PWL CsmPwl;

    #pragma DATA_SECTION("CsmRegsFile")
    volatile struct CSM_REGS CsmRegs;

    #pragma DATA_SECTION(Flash_CPUScaleFactor, "FlashScalingVar");
    Uint32 Flash_CPUScaleFactor;

    #pragma DATA_SECTION(Flash_CallbackPtr, "FlashCallbackVar");
    void (*Flash_CallbackPtr) (void);

    #ifdef FLASH
    #pragma CODE_SECTION(Example_CallFlashAPI,"ramfuncs");
    #endif
    void Example_CallFlashAPI(void)
    {
    DINT;
    Uint16 i;
    Uint16 Status;
    Uint16 *Flash_ptr; // Pointer to a location in flash
    Uint32 Length; // Number of 16-bit values to be programmed

    CsmUnlock();

    EALLOW;
    Flash_CPUScaleFactor = SCALE_FACTOR;
    Flash_CallbackPtr = NULL;
    EDIS;


    Status = Flash_APIVersionHex(); //返回值为256


    Status = Flash_Erase(SECTORH,&FlashStatus); //程序卡在了这了,出不来
    if(Status != STATUS_SUCCESS)
    {
    return ;
    }
    for(i=0;i<WORDS_IN_FLASH_BUFFER;i++)
    {
    Buffer[i] = 0x100+i;
    }
    Flash_ptr = Sector[7].StartAddr;
    Length = 0x100;
    Status = Flash_Program(Flash_ptr,Buffer,Length,&FlashStatus);
    if(Status != STATUS_SUCCESS)
    {
    return ;
    }
    EINT;
    // --------------
    }