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.

程序烧写到FLASH 中,重新上电后出现问题

Other Parts Discussed in Thread: TMS320C6727

当重新上电后,发现读不到之前烧写在flash特定地址中的数据,使用CCSmemory观察flash存储器全为0,这是什么情况?

  • 你之前烧写完成后可以看到打开memory view 能看到FLASH中有程序吗?

  • tanson,

    描述一下你的CCS烧写操作过程。

    确认一下目标配置文件的仿真器和芯片都正确。

    如果你是使用FLASH API,确保函数都在RAM中运行。

    Eric

  • 现在的情况是有的时候能看到,有的时候看到整个扇区都是0,但是一旦看到了,重复断电上电都能看到,是不是我的芯片有什么问题呢?

  • 烧写和FLASH API运行应该是没问题的,因为脱机后通过上位机修改参数后程序可以按照指令运行。

    现在的情况是有的时候烧很多次,重新上电看到数据所在扇区的数据都是0,但是有的时候有莫名其妙的能读到数据的,没有存储的单元全为FFFF也就是说 处于正常状态,是不是我的芯片有问题呢?

      thanks Eric

  • tanson,

    你能不能说明一下你是如何使用flashAPI的,你是使用flash API操作还是使用CCS直接烧写?

    在调用flash api的时候你是否有把中断关掉。有时候烧写成功,有时候却不行,那我认为应该是你调用flash API的代码存在bug。

    Eric

  • 是使用flash api烧写的。

    首先我将一个参数,比如说是PID的P = 100参数烧写进flash的0x330000存储单元,在上位机试试显示这个P得值,当发现P的值变为100后,使用这个参数值去控制系统运行,在没断电的时候这些都能正常运行,而且使用这个P值的时候是直接从地址0x330000中读取出来的,说明确实API烧写进去了。

    然后我将系统断电,再次上电后等待上位机读取P值,这个值也是从0x330000中读取的却发现读到的是FFFF。此时我再次通过上位机烧写一个P=100进去,可以发现P上位机显示为100,而且系统正常运行。

    经过以上实验,我分析得到,API函数是运行了的,不然我从0X330000中读取数据上位机不会显示出100.但是断电后却有的时候存不住。

  • 直接拿仿真器看,排除上位机读错的可能性。

  • 好的,我去试试

  • tanson,

    你用的是什么芯片,什么FLASH API?

    重新上电后用上位机读取全为0xFFFF,是不是每次都这样?接仿真器后用memory窗观察,是否也是0xFFFF。

    另外我从上面的帖子看,还有扇区都为0的情况?

    Eric

  • 芯片是28335 ,API是210版本,是上电后有CCS中看到的是全为0,偶尔会出现全为F,但是上位机读取0x330000存储单元,读到的值为-1,就是FFFF吧

  • tanson,

    能不能把你调用FLASH API 对0x330000的代码传上来分析一下。还有cmd文件。mempy函数。

    Eric

  • 1:API的使用

    #pragma CODE_SECTION(Example_CallFlashAPI,"ramfuncs");
    void Example_CallFlashAPI(void)
    {
    Uint16 Status;
    Uint16 * Flash_ptr; // Pointer to a location in flash
    Uint32 Length; // Number of 16-bit values to be programmed
    float32 Version; // Version of the API in floating point
    Uint16 VersionHex; // Version of the API in decimal encoded hex

    /*------------------------------------------------------------------
    Check the version of the API

    Flash_APIVersion() returns the version in floating point.
    FlashAPIVersionHex() returns the version as a decimal encoded hex.

    FlashAPIVersionHex() can be used to avoid processing issues
    associated with floating point values.
    ------------------------------------------------------------------*/
    VersionHex = Flash_APIVersionHex();
    if(VersionHex != 0x0210)
    {
    // Unexpected API version
    // Make a decision based on this info.
    asm(" ESTOP0");
    }


    Version = Flash_APIVersion();
    if(Version != (float32)2.10)
    {
    // Unexpected API version
    // Make a decision based on this info.
    asm(" ESTOP0");
    }

    /*------------------------------------------------------------------
    Before programming make sure the sectors are Erased.

    ------------------------------------------------------------------*/

    // Example: Erase Sector B,C
    // Sectors A and D have the example code so leave them
    // programmed.

    // SECTORB, SECTORC are defined in Flash2833x_API_Library.h
    Status = Flash_Erase(SECTORB,&FlashStatus);
    if(Status != STATUS_SUCCESS)
    {
    Example_Error(Status);
    }

    /*------------------------------------------------------------------
    Program Flash Examples

    ------------------------------------------------------------------*/

    // A buffer can be supplied to the program function. Each word is
    // programmed until the whole buffer is programmed or a problem is
    // found. If the buffer goes outside of the range of OTP or Flash
    // then nothing is done and an error is returned.

    Buffer = buffer;

    Flash_ptr = (Uint16 *)0x330000;
    Length = 1;
    Status = Flash_Program(Flash_ptr,&Buffer,Length,&FlashStatus);
    if(Status != STATUS_SUCCESS)
    {
    Example_Error(Status);
    }



    // Verify the values programmed. The Program step itself does a verify
    // as it goes. This verify is a 2nd verification that can be done.
    Status = Flash_Verify(Flash_ptr,&Buffer,Length,&FlashStatus);
    if(Status != STATUS_SUCCESS)
    {
    Example_Error(Status);
    }

    }

    /*------------------------------------------------------------------
    For this example, if an error is found just stop here
    -----------------------------------------------------------------*/
    #pragma CODE_SECTION(Example_Error,"ramfuncs");
    void Example_Error(Uint16 Status)
    {

    // Error code will be in the AL register.
    asm(" ESTOP0");
    asm(" SB 0, UNC");//请问这里是什么意思?????
    }

    2:CMD文件

    MEMORY
    {
    PAGE 0: /* Program Memory */
    /* Memory (RAM/FLASH/OTP) blocks can be moved to PAGE1 for data allocation */

    ZONE0 : origin = 0x004000, length = 0x001000 /* XINTF zone 0 */
    RAML0 : origin = 0x008000, length = 0x001000 /* on-chip RAM block L0 */
    RAML1 : origin = 0x009000, length = 0x001000 /* on-chip RAM block L1 */
    RAML2 : origin = 0x00A000, length = 0x001000 /* on-chip RAM block L2 */
    RAML3 : origin = 0x00B000, length = 0x001000 /* on-chip RAM block L3 */
    ZONE6 : origin = 0x0100000, length = 0x100000 /* XINTF zone 6 */
    ZONE7A : origin = 0x0200000, length = 0x00FC00 /* XINTF zone 7 - program space */
    FLASHH : origin = 0x300000, length = 0x008000 /* on-chip FLASH */
    FLASHG : origin = 0x308000, length = 0x008000 /* on-chip FLASH */
    FLASHF : origin = 0x310000, length = 0x008000 /* on-chip FLASH */
    FLASHE : origin = 0x318000, length = 0x008000 /* on-chip FLASH */
    FLASHD : origin = 0x320000, length = 0x008000 /* on-chip FLASH */
    FLASHC : origin = 0x328000, length = 0x008000 /* on-chip FLASH */
    FLASHA : origin = 0x338000, length = 0x007F80 /* on-chip FLASH */
    CSM_RSVD : origin = 0x33FF80, length = 0x000076 /* Part of FLASHA. Program with all 0x0000 when CSM is in use. */
    BEGIN : origin = 0x33FFF6, length = 0x000002 /* Part of FLASHA. Used for "boot to Flash" bootloader mode. */
    CSM_PWL : origin = 0x33FFF8, length = 0x000008 /* Part of FLASHA. CSM password locations in FLASHA */
    OTP : origin = 0x380400, length = 0x000400 /* on-chip OTP */
    ADC_CAL : origin = 0x380080, length = 0x000009 /* ADC_cal function in Reserved memory */

    IQTABLES : origin = 0x3FE000, length = 0x000b50 /* IQ Math Tables in Boot ROM */
    IQTABLES2 : origin = 0x3FEB50, length = 0x00008c /* IQ Math Tables in Boot ROM */
    FPUTABLES : origin = 0x3FEBDC, length = 0x0006A0 /* FPU Tables in Boot ROM */
    ROM : origin = 0x3FF27C, length = 0x000D44 /* Boot ROM */
    RESET : origin = 0x3FFFC0, length = 0x000002 /* part of boot ROM */
    VECTORS : origin = 0x3FFFC2, length = 0x00003E /* part of boot ROM */

    PAGE 1 : /* Data Memory */
    /* Memory (RAM/FLASH/OTP) blocks can be moved to PAGE0 for program allocation */
    /* Registers remain on PAGE1 */

    BOOT_RSVD : origin = 0x000000, length = 0x000050 /* Part of M0, BOOT rom will use this for stack */
    RAMM0 : origin = 0x000050, length = 0x0003B0 /* on-chip RAM block M0 */
    RAMM1 : origin = 0x000400, length = 0x000400 /* on-chip RAM block M1 */
    RAML4 : origin = 0x00C000, length = 0x001000 /* on-chip RAM block L1 */
    RAML5 : origin = 0x00D000, length = 0x001000 /* on-chip RAM block L1 */
    RAML6 : origin = 0x00E000, length = 0x001000 /* on-chip RAM block L1 */
    RAML7 : origin = 0x00F000, length = 0x001000 /* on-chip RAM block L1 */
    ZONE7B : origin = 0x20FC00, length = 0x000400 /* XINTF zone 7 - data space */
    FLASHB : origin = 0x330000, length = 0x008000 /* on-chip FLASH */
    }

    /* Allocate sections to memory blocks.
    Note:
    codestart user defined section in DSP28_CodeStartBranch.asm used to redirect code
    execution when booting to flash
    ramfuncs user defined section to store functions that will be copied from Flash into RAM
    */

    SECTIONS
    {

    Flash28_API:
    {
    -lFlash28335_API_V210.lib(.econst)
    -lFlash28335_API_V210.lib(.text)
    } LOAD = FLASHD,
    RUN = RAML0,
    LOAD_START(_Flash28_API_LoadStart),
    LOAD_END(_Flash28_API_LoadEnd),
    RUN_START(_Flash28_API_RunStart),
    PAGE = 0
    .cinit : > FLASHA PAGE = 0
    .pinit : > FLASHA, PAGE = 0
    .text : > FLASHA PAGE = 0
    codestart : > BEGIN PAGE = 0
    ramfuncs : LOAD = FLASHD,
    RUN = RAML0,
    LOAD_START(_RamfuncsLoadStart),
    LOAD_END(_RamfuncsLoadEnd),
    RUN_START(_RamfuncsRunStart),
    PAGE = 0

    csmpasswds : > CSM_PWL PAGE = 0
    csm_rsvd : > CSM_RSVD PAGE = 0

    /* Allocate uninitalized data sections: */
    .stack : > RAMM1 PAGE = 1
    .ebss : > RAML4 PAGE = 1
    .esysmem : > RAMM1 PAGE = 1

    /* Initalized sections go in Flash */
    /* For SDFlash to program these, they must be allocated to page 0 */
    .econst : > FLASHA PAGE = 0
    .switch : > FLASHA PAGE = 0

    /* Allocate IQ math areas: */
    IQmath : > FLASHC PAGE = 0 /* Math Code */
    IQmathTables : > IQTABLES, PAGE = 0, TYPE = NOLOAD
    IQmathTables2 : > IQTABLES2, PAGE = 0, TYPE = NOLOAD
    FPUmathTables : > FPUTABLES, PAGE = 0, TYPE = NOLOAD

    /* Allocate DMA-accessible RAM sections: */
    DMARAML4 : > RAML4, PAGE = 1
    DMARAML5 : > RAML5, PAGE = 1
    DMARAML6 : > RAML6, PAGE = 1
    DMARAML7 : > RAML7, PAGE = 1

    /* Allocate 0x400 of XINTF Zone 7 to storing data */
    ZONE7DATA : > ZONE7B, PAGE = 1

    /* .reset is a standard section used by the compiler. It contains the */
    /* the address of the start of _c_int00 for C Code. /*
    /* When using the boot ROM this section and the CPU vector */
    /* table is not needed. Thus the default type is set here to */
    /* DSECT */
    .reset : > RESET, PAGE = 0, TYPE = DSECT
    vectors : > VECTORS PAGE = 0, TYPE = DSECT

    /* Allocate ADC_cal function (pre-programmed by factory into TI reserved memory) */
    .adc_cal : load = ADC_CAL, PAGE = 0, TYPE = NOLOAD

    }

    3:memory copy

    MemCopy(&Flash28_API_LoadStart, &Flash28_API_LoadEnd, &Flash28_API_RunStart);
    MemCopy( &RamfuncsLoadStart, &RamfuncsLoadEnd, &RamfuncsRunStart );

    void MemCopy(Uint16 *SourceAddr, Uint16* SourceEndAddr, Uint16* DestAddr)
    {
    while(SourceAddr < SourceEndAddr)
    {
    *DestAddr++ = *SourceAddr++;
    }
    return;
    }

  • tanson,

    1.看起来你的flash API函数没有问题,你的代码中Buffer和buffer应该都是全局变量吧,然后将这个变量的值烧写到扇区B的起始地址0x330000中,我的理解是否对?

    2. 你在调用flash API的时候,有没有关掉看门狗和中断?

    3. memcopy函数有没有在一开始就调用,避免当调用flash API的时候,程序还没copy到RAM中。

    4. 在带仿真器调试的时候,是否有进入example error的情况?

    5. 如果以上4点都没有问题,或者说在仿真的时候不能定位问题,我觉得你可以在Example_CallFlashAPI()函数中插入GPIO34 toggle的代码,如在Flash erase前面加这个代码,然后在flash program前后加这个代码,以及verify函数,通过示波器观察GPIO34的波形,看Flash API函数是否正确执行。

    希望对你有帮助!

    Eric

  • 感谢Eric的回答

    1、Buffer和buffer确实都是全局变量,并且把值烧写到地址0x330000中

    2、在调用FLASH API的时候我只是关掉了全局中断,调用完成之后全局中断打开,由于系统初始化的时候我将看门狗关闭了,也就是程序中没有使用看门狗,在调用FLASH API的时候就没有关闭看门狗和打开看门狗的操作,不知道这里是不是有问题?

    3、memcopy函数是在初始化完成之后就调用了,保证在调用FLASH API之前就copy了。

    4、带仿真器调试的时候没有出现异常

    关于您提到的第五点我会认真做实验看一下,再次感谢您耐心悉心的指导。

  • tanson,

    那单机跑的时候,出错的概率是百分之百吗?

    是否有一块demo板,用demo板再测一下程序,排除硬件的问题。

    Eric

     

  • 还有,检查一下晶振,系统时钟有没有问题,可以用示波器查看sysclkout, 还有电源。

    Eric

  • 确实之前出现过晶振不正常工作的情况,单机跑的时候偶尔也会读到正确值。

  • 嗯,tanson,你可以在烧写的时候观察SYSCLKOUT引脚,看时钟是不是出现问题。最好的话也可以查看一下电源。

    Eric

  • 好的,我做完实验再反馈

  • 我用的是TMS320C6727的DSP。通过EMIF访问的外部异步器件/FLASH空间,起始地址0x90000000,终止地址0x9FFFFFFF。自己给定的0到100的数字先写进RAM中,再把RAM-0x10000000开始的地址中的内容,送入外部FLASH-0x90000000开始的地址中,通过CCS中memory观察,写进去了,但是断电后,重新上电,connect后,再去读数据不是之前写入的,而都是0xFFFFFFF,什么情况。先假设一定写进去了,那再去读数据一定是有的,结果是没有,说明没有写进去。同理,如果没有写进去,那0x90000000-0x90000300地址内写入的数据怎么解释?难道它不是FLASH的地址?但是EMIF访问的外部异步器件/FLASH空间,起始地址是0x90000000,终止地址是0x9FFFFFFF。这种情况FLASH有可能是坏了的造成吗?还是其它原因。。。麻烦解答一下,非常感谢

  • 你的程序里面有没有运行flash API的函数?如果观察窗看到了,应该是写进去了。

    你这个C6000的问题到DSP的帖子区提问吧,会有更熟悉的同事在支持。

    ERIC

  • 您好,我在程序调试的过程中也遇到了相似的问题。将程序刷写到Flash后,在线调试,程序周期性重启,xrs引脚周期性产生一个20us的低电平,应该是看门狗的输出。但是看门狗已经关了,断点调试发现程序运行到ADC初始化中ADC_cal();语句时,出现问题。    ADC_cal();  EDIS;  我把断点设置在EDIS,然后再打开,系统就能正常运行。不在线调试也是自己重启。求大神指导一下