[Kinetis] 请教大家KE02写Flash问题

[复制链接]
 楼主| summer_zq 发表于 2015-5-27 17:28 | 显示全部楼层 |阅读模式
又遇到新问题了。。。
我写了段程序,计算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
为啥单步好好的连续就异常了呢,我看了延时什么的都加上了的,这不科学。。。
FSL_TICS_Jeremy 发表于 2015-5-28 17:00 | 显示全部楼层
1. 你的代码好像没有严格遵照flash command 执行步骤,请参考以下下方的代码:
  1. uint16_t Flash_Program2LongWords(uint32_t wNVMTargetAddress, uint32_t dwData0, uint32_t dwData1)
  2. {
  3.         uint16_t err = FLASH_ERR_SUCCESS;
  4.        
  5.         // Check address to see if it is aligned to 4 bytes
  6.         // Global address [1:0] must be 00.
  7.         if(wNVMTargetAddress & 0x03)
  8.         {
  9.                 err = FLASH_ERR_INVALID_PARAM;
  10.                 return (err);
  11.         }
  12.         // Clear error flags
  13.         FTMRH_FSTAT = 0x30;
  14.        
  15.         // Write index to specify the command code to be loaded
  16.         FTMRH_FCCOBIX = 0x0;
  17.         // Write command code and memory address bits[23:16]       
  18.         FTMRH_FCCOBHI = FLASH_CMD_PROGRAM;// program FLASH command
  19.         FTMRH_FCCOBLO = wNVMTargetAddress>>16;// memory address bits[23:16]
  20.         // Write index to specify the lower byte memory address bits[15:0] to be loaded
  21.         FTMRH_FCCOBIX = 0x1;
  22.         // Write the lower byte memory address bits[15:0]
  23.         FTMRH_FCCOBLO = wNVMTargetAddress;
  24.         FTMRH_FCCOBHI = wNVMTargetAddress>>8;
  25.         
  26.         // Write index to specify the word0 (MSB word) to be programmed
  27.         FTMRH_FCCOBIX = 0x2;
  28.         // Write the word 0
  29. #if     defined(BIG_ENDIAN)               
  30.         //FTMRH_FCCOB = (dwData0>>16) & 0xFFFF;
  31.         FTMRH_FCCOBHI = (dwData0>>16)>>8;
  32.         FTMRH_FCCOBLO = (dwData0>>16);
  33.         
  34.         // Write index to specify the word1 (LSB word) to be programmed
  35.         FTMRH_FCCOBIX = 0x3;
  36.         // Write word 1
  37.         //FTMRH_FCCOB = (dwData0) & 0xFFFF;
  38.         FTMRH_FCCOBHI = (dwData0) >>8;
  39.         FTMRH_FCCOBLO = (dwData0);
  40.        
  41.         // Write index to specify the word0 (MSB word) to be programmed
  42.         FTMRH_FCCOBIX = 0x4;
  43.         // Write the word2
  44.         //FTMRH_FCCOB = (dwData1>>16) & 0xFFFF;
  45.         FTMRH_FCCOBHI = (dwData1>>16)>>8;
  46.         FTMRH_FCCOBLO = (dwData1>>16);
  47.         
  48.         // Write index to specify the word1 (LSB word) to be programmed
  49.         FTMRH_FCCOBIX = 0x5;
  50.         // Write word 3
  51.         //FTMRH_FCCOB = (dwData1) & 0xFFFF;
  52.         FTMRH_FCCOBHI = (dwData1) >>8;
  53.         FTMRH_FCCOBLO = (dwData1);
  54. #else
  55.         //FTMRH_FCCOB = (dwData0) & 0xFFFF;
  56.         FTMRH_FCCOBHI = (dwData0) >>8;
  57.         FTMRH_FCCOBLO = (dwData0);
  58.         
  59.         // Write index to specify the word1 (LSB word) to be programmed
  60.         FTMRH_FCCOBIX = 0x3;
  61.         // Write word 1
  62.         FTMRH_FCCOBHI = (dwData0>>16)>>8;
  63.         FTMRH_FCCOBLO = (dwData0>>16);
  64.        
  65.         // Write index to specify the word0 (MSB word) to be programmed
  66.         FTMRH_FCCOBIX = 0x4;
  67.         // Write the word2
  68.         //FTMRH_FCCOB = (dwData1) & 0xFFFF;
  69.         FTMRH_FCCOBHI = (dwData1) >>8;
  70.         FTMRH_FCCOBLO = (dwData1);        
  71.         
  72.         // Write index to specify the word1 (LSB word) to be programmed
  73.         FTMRH_FCCOBIX = 0x5;
  74.         // Write word 3
  75.         //FTMRH_FCCOB = (dwData1>>16) & 0xFFFF;
  76.         FTMRH_FCCOBHI = (dwData1>>16)>>8;
  77.         FTMRH_FCCOBLO = (dwData1>>16);
  78. #endif
  79.         // Launch the command
  80.         FTMRH_LaunchCMD(TRUE);
  81.        
  82.         // Check error status
  83.         if(FTMRH_FSTAT & FTMRH_FSTAT_ACCERR_MASK)
  84.         {
  85.                 err |= FLASH_ERR_ACCESS;
  86.         }
  87.         if(FTMRH_FSTAT & FTMRH_FSTAT_FPVIOL_MASK)
  88.         {
  89.                 err |= FLASH_ERR_PROTECTION;               
  90.         }
  91.         if(FTMRH_FSTAT & FTMRH_FSTAT_MGSTAT0_MASK)
  92.         {
  93.                 err |= FLASH_ERR_MGSTAT0;               
  94.         }
  95.         if(FTMRH_FSTAT & FTMRH_FSTAT_MGSTAT1_MASK)
  96.         {
  97.                 err |= FLASH_ERR_MGSTAT1;               
  98.         }       
  99.        
  100.         return (err);
  101. }


2.还有在program byte之前,确保该区域处于erase 状态,这在参考手册有注明
2015-05-28_16-59-55.jpg
风的样子 发表于 2015-5-28 18:25 | 显示全部楼层
FSL_TICS_Jeremy 发表于 2015-5-28 17:00
1. 你的代码好像没有严格遵照flash command 执行步骤,请参考以下下方的代码:

这样看代码真的舒服多了
追逐浪花 发表于 2015-5-28 22:51 | 显示全部楼层
没有遇到过你说的问题呢,帮你顶一下吧
FSL_TICS_Jeremy 发表于 2015-6-5 09:57 | 显示全部楼层
非常感谢你关于Kinetis的技术问题。如果你没有其他问题,我们将此帖默认为已解决.
 楼主| summer_zq 发表于 2015-7-1 20:24 | 显示全部楼层
知道怎么回事了,有相同问题的可参考https://community.freescale.com/docs/DOC-103951
xydrj 发表于 2017-5-16 16:41 | 显示全部楼层
我也遇到同样问题,不知如何解决。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

6

主题

50

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部