打印
[Kinetis]

请教大家KE02写Flash问题

[复制链接]
2495|9
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
又遇到新问题了。。。
我写了段程序,计算Flash CRC16校验码,存放在最后2 Byte位置,以后开机时做Flash自检用的。在向Flash写入校验码这一段,单步能运行下去,连续运行就不对了,不知是何原因?下面是程序。

//****************************************
// Sub:          fFlash_init
// Parameter:
// Return:
// Funktion:     initialize flash driver
//****************************************
void fFlash_init(void){
        SIM_SCGC |= SIM_SCGC_FLASH_MASK;
        if(!(FTMRH->FCLKDIV & FTMRH_FCLKDIV_FDIVLD_MASK)){                        // FCLKDIV register has not been written since the last reset
                FTMRH->FCLKDIV |= 0x7;                                                                        //divide 8MHz BUSCLK down to 1MHz
                FTMRH->FCLKDIV |= FTMRH_FCLKDIV_FDIVLCK_MASK;                         // lock the prescaler
        }
}

//****************************************
// Sub:          fFlash_EraseSector
// Parameter:    sector number to be erased
// Return:
// Funktion:     erase flash sector, each flash sector is of 512 bytes long
//****************************************
void fFlash_EraseSector(unsigned char SectorNo){
        FTMRH->FSTAT = 0x30;                                                                                // Clear error flags

        FTMRH->FCCOBIX = 0x0;                                                                                // Write index to specify the command code to be loaded
        FTMRH->FCCOBHI = _FLASH_CMD_ERASE_SECTOR;                                        // Write command code
        FTMRH->FCCOBLO = 0;                                                                                        // memory address bits[23:16]

        FTMRH->FCCOBIX = 0x1;                                                                                // Write index to specify the lower byte memory address bits[15:0] to be loaded
        FTMRH->FCCOBLO = SectorNo * _FLASH_SECTOR_SIZE - 1;                        // Write the lower byte memory address bits[15:0]
        FTMRH->FCCOBHI = (SectorNo * _FLASH_SECTOR_SIZE - 1) >> 8;

        FTMRH->FSTAT = 0x80;                                                                                // launch the command
        while (!(FTMRH->FSTAT & FTMRH_FSTAT_CCIF_MASK));                        // Wait till command is completed
}

//****************************************
// Sub:          fFlash_WriteChecksum
// Parameter:    word programming data
// Return:
// Funktion:     program checksum to the last 2 bytes of flash
//****************************************
void fFlash_WriteChecksum(unsigned short crc){
        FTMRH_FSTAT |= 0x30;                                                                                //clear error flags

        FTMRH->FCCOBIX = 0x0;                                                                                //write index to specify the command code to be loaded
        FTMRH->FCCOBHI = _FLASH_CMD_PROGRAM;                                                //program FLASH command
        FTMRH->FCCOBLO = 0x00;                                                                                //target address bits[23:16]

        FTMRH->FCCOBIX = 0x1;                                                                                //Write index to specify the lower byte memory address bits[15:0] to be loaded
        FTMRH->FCCOBLO = 0xfc;
        FTMRH->FCCOBHI = 0xff;

        FTMRH->FCCOBIX = 0x2;                                                                                // Write index to specify the word0 (MSB word) to be programmed
        FTMRH->FCCOBHI = 0xff;
        FTMRH->FCCOBLO = 0xff;

        FTMRH->FCCOBIX = 0x3;                                                                                // Write index to specify the word1 (LSB word) to be programmed
        FTMRH->FCCOBHI = crc;
        FTMRH->FCCOBLO = crc >> 8;

        FTMRH->FSTAT = 0x80;                                                                                //launch the command
        while (!(FTMRH->FSTAT & FTMRH_FSTAT_CCIF_MASK));                        //Wait till command is completed
}

我函数调用的顺序是先init再erase然后write。单步运行能够顺利写入,数据再读出来看也是对的。连续运行时程序会卡在fFlashWrite_Checksum的最后两句也就是启动写操作以及等待操作完成,而且程序是进入了一个系统文件startup_ARMLtdGCC.S,这个文件里面我看了是一些系统reset的设置。不明白怎么会运行到这边,我的设置有什么问题吗?请大家帮忙看看,谢谢了!

相关帖子

沙发
舒斯特尔| | 2015-5-27 22:59 | 只看该作者
明天上午帮你看看

使用特权

评论回复
板凳
FSL_TICS_Jeremy| | 2015-5-28 09:25 | 只看该作者
我建议你可以先参考FRDM-KE02提供的sample code package中Flash例程
sample code package下载链接如下:
http://www.freescale.com/zh-Hans ... ab=Design_Tools_Tab

使用特权

评论回复
地板
summer_zq|  楼主 | 2015-5-28 14:23 | 只看该作者
本帖最后由 summer_zq 于 2015-5-28 14:36 编辑
FSL_TICS_Jeremy 发表于 2015-5-28 09:25
我建议你可以先参考FRDM-KE02提供的sample code package中Flash例程
sample code package下载链接如下:
ht ...

就是按例程写的,关键步骤都差不多。现在情况就是单步运行一切正常,连续运行的话执行到那两句就跑飞到startup_ARMLtdGCC.S里面去了,卡住位置的语句是:
#ifndef __NO_SYSTEM_INIT
    // Low-level system initialise must be done here so to avoid WDOG timeout
    bl    SystemInitLowLevel
#endif
为啥单步好好的连续就异常了呢,我看了延时什么的都加上了的,这不科学。。。

使用特权

评论回复
5
FSL_TICS_Jeremy| | 2015-5-28 17:00 | 只看该作者
1. 你的代码好像没有严格遵照flash command 执行步骤,请参考以下下方的代码:
uint16_t Flash_Program2LongWords(uint32_t wNVMTargetAddress, uint32_t dwData0, uint32_t dwData1)
{
        uint16_t err = FLASH_ERR_SUCCESS;
       
        // Check address to see if it is aligned to 4 bytes
        // Global address [1:0] must be 00.
        if(wNVMTargetAddress & 0x03)
        {
                err = FLASH_ERR_INVALID_PARAM;
                return (err);
        }
        // Clear error flags
        FTMRH_FSTAT = 0x30;
       
        // Write index to specify the command code to be loaded
        FTMRH_FCCOBIX = 0x0;
        // Write command code and memory address bits[23:16]       
        FTMRH_FCCOBHI = FLASH_CMD_PROGRAM;// program FLASH command
        FTMRH_FCCOBLO = wNVMTargetAddress>>16;// memory address bits[23:16]
        // Write index to specify the lower byte memory address bits[15:0] to be loaded
        FTMRH_FCCOBIX = 0x1;
        // Write the lower byte memory address bits[15:0]
        FTMRH_FCCOBLO = wNVMTargetAddress;
        FTMRH_FCCOBHI = wNVMTargetAddress>>8;
        
        // Write index to specify the word0 (MSB word) to be programmed
        FTMRH_FCCOBIX = 0x2;
        // Write the word 0
#if     defined(BIG_ENDIAN)               
        //FTMRH_FCCOB = (dwData0>>16) & 0xFFFF;
        FTMRH_FCCOBHI = (dwData0>>16)>>8;
        FTMRH_FCCOBLO = (dwData0>>16);
        
        // Write index to specify the word1 (LSB word) to be programmed
        FTMRH_FCCOBIX = 0x3;
        // Write word 1
        //FTMRH_FCCOB = (dwData0) & 0xFFFF;
        FTMRH_FCCOBHI = (dwData0) >>8;
        FTMRH_FCCOBLO = (dwData0);
       
        // Write index to specify the word0 (MSB word) to be programmed
        FTMRH_FCCOBIX = 0x4;
        // Write the word2
        //FTMRH_FCCOB = (dwData1>>16) & 0xFFFF;
        FTMRH_FCCOBHI = (dwData1>>16)>>8;
        FTMRH_FCCOBLO = (dwData1>>16);
        
        // Write index to specify the word1 (LSB word) to be programmed
        FTMRH_FCCOBIX = 0x5;
        // Write word 3
        //FTMRH_FCCOB = (dwData1) & 0xFFFF;
        FTMRH_FCCOBHI = (dwData1) >>8;
        FTMRH_FCCOBLO = (dwData1);
#else
        //FTMRH_FCCOB = (dwData0) & 0xFFFF;
        FTMRH_FCCOBHI = (dwData0) >>8;
        FTMRH_FCCOBLO = (dwData0);
        
        // Write index to specify the word1 (LSB word) to be programmed
        FTMRH_FCCOBIX = 0x3;
        // Write word 1
        FTMRH_FCCOBHI = (dwData0>>16)>>8;
        FTMRH_FCCOBLO = (dwData0>>16);
       
        // Write index to specify the word0 (MSB word) to be programmed
        FTMRH_FCCOBIX = 0x4;
        // Write the word2
        //FTMRH_FCCOB = (dwData1) & 0xFFFF;
        FTMRH_FCCOBHI = (dwData1) >>8;
        FTMRH_FCCOBLO = (dwData1);        
        
        // Write index to specify the word1 (LSB word) to be programmed
        FTMRH_FCCOBIX = 0x5;
        // Write word 3
        //FTMRH_FCCOB = (dwData1>>16) & 0xFFFF;
        FTMRH_FCCOBHI = (dwData1>>16)>>8;
        FTMRH_FCCOBLO = (dwData1>>16);
#endif
        // Launch the command
        FTMRH_LaunchCMD(TRUE);
       
        // Check error status
        if(FTMRH_FSTAT & FTMRH_FSTAT_ACCERR_MASK)
        {
                err |= FLASH_ERR_ACCESS;
        }
        if(FTMRH_FSTAT & FTMRH_FSTAT_FPVIOL_MASK)
        {
                err |= FLASH_ERR_PROTECTION;               
        }
        if(FTMRH_FSTAT & FTMRH_FSTAT_MGSTAT0_MASK)
        {
                err |= FLASH_ERR_MGSTAT0;               
        }
        if(FTMRH_FSTAT & FTMRH_FSTAT_MGSTAT1_MASK)
        {
                err |= FLASH_ERR_MGSTAT1;               
        }       
       
        return (err);
}


2.还有在program byte之前,确保该区域处于erase 状态,这在参考手册有注明

使用特权

评论回复
6
风的样子| | 2015-5-28 18:25 | 只看该作者
FSL_TICS_Jeremy 发表于 2015-5-28 17:00
1. 你的代码好像没有严格遵照flash command 执行步骤,请参考以下下方的代码:

这样看代码真的舒服多了

使用特权

评论回复
7
追逐浪花| | 2015-5-28 22:51 | 只看该作者
没有遇到过你说的问题呢,帮你顶一下吧

使用特权

评论回复
8
FSL_TICS_Jeremy| | 2015-6-5 09:57 | 只看该作者
非常感谢你关于Kinetis的技术问题。如果你没有其他问题,我们将此帖默认为已解决.

使用特权

评论回复
9
summer_zq|  楼主 | 2015-7-1 20:24 | 只看该作者
知道怎么回事了,有相同问题的可参考https://community.freescale.com/docs/DOC-103951

使用特权

评论回复
10
xydrj| | 2017-5-16 16:41 | 只看该作者
我也遇到同样问题,不知如何解决。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

6

主题

50

帖子

0

粉丝