K10操作片上flash,芯片偶尔复位?(已解决)

2020-02-20 20:40发布

本帖最后由 w282529350 于 2014-1-22 10:06 编辑

请问各位有没有遇到过这种情况?

芯片的型号为MK10DX256VLL7,我是在bootloader程序里面操作的用户程序区的flash,bootloader程序的区域为0x0--0x3FFF, 用户程序的区域为0x4000--0x3FFFF

flash的驱动函数是参照网上的k60例程,在bootloder里面擦除或者读写用户程序区的flash,但是在测试的过程中,发现偶尔擦除或者写用户程序flash的时候,芯片会出现复位的现象。并不是必出,只是偶尔出现复位的情况,而且都是在操作用户程序区flash的时候,请问大家知不知道这是怎么一回事呀? 谢谢!
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
13条回答
FSL_TICS_TIANZH
1楼-- · 2020-02-21 02:09
感觉是你对flash的某个操作时间太长,然后引起复位,这个要具体看你的程序了.
FSL_TICS_TIANZH
2楼-- · 2020-02-21 03:18
 精彩回答 2  元偷偷看……
FSL_TICS_TIANZH
3楼-- · 2020-02-21 05:44
感觉是你对flash的某个操作时间太长,然后引起复位,这个要具体看你的程序了.
w282529350
4楼-- · 2020-02-21 10:21
本帖最后由 w282529350 于 2014-1-21 17:21 编辑
FSL_TICS_TIANZH 发表于 2014-1-21 15:49
感觉是你对flash的某个操作时间太长,然后引起复位,这个要具体看你的程序了. ...


您好,版主,谢谢您的回复,我的程序是根据这个例程改的,几乎没有动什么地方

//============================================================================
//文件名称:hw_flash.c
//功能概要:K60 Flash擦除/写入底层驱动程序源文件
//============================================================================

//包含头文件
#include "hw_flash.h"


// Flash控制器宏定义 ,内部使用
#define CCIF    (1<<7)
#define ACCERR  (1<<5)
#define FPVIOL  (1<<4)
#define MGSTAT0 (1<<0)


//Flash命令宏定义,内部使用
#define RD1BLK    0x00   // 读整块Flash
#define RD1SEC    0x01   // 读整个扇区
#define PGMCHK    0x02   // 写入检查
#define RDRSRC    0x03   // 读目标数据
#define PGM4      0x06   // 写入长字
#define ERSBLK    0x08   // 擦除整块Flash
#define ERSSCR    0x09   // 擦除Flash扇区
#define PGMSEC    0x0B   // 写入扇区
#define RD1ALL    0x40   // 读所有的块
#define RDONCE    0x41   // 只读一次
#define PGMONCE   0x43   // 只写一次
#define ERSALL    0x44   // 擦除所有块
#define VFYKEY    0x45   // 验证后门访问钥匙
#define PGMPART   0x80   // 写入分区
#define SETRAM    0x81   // 设定FlexRAM功能

//=================内部调用函数声明==========================================
//==========================================================================
//函数名称:hw_flash_sign_off
//函数返回:无
//参数说明:无
//功能概要:配置Flash存储控制器,清除Flash预读取缓冲
//==========================================================================
static void hw_flash_sign_off(void);

//==========================================================================
//函数名称:hw_flash_cmd_launch
//函数返回:0-成功 1-失败
//参数说明:无
//功能概要:启动Flash命令
//==========================================================================
static uint_32 hw_flash_cmd_launch(void);

//===========================================================================

//=================外部接口函数==============================================
//==========================================================================
//函数名称:hw_flash_init
//函数返回:无
//参数说明:无
//功能概要:初始化flash模块
//==========================================================================
void hw_flash_init(void)
{
        _int_disable();                          //DisableInterrupts
        //清除FMC缓冲区
    hw_flash_sign_off();
   
    // 等待命令完成
    while(!(FTFL_FSTAT & CCIF));
   
    // 清除访问出错标志位
    FTFL_FSTAT = ACCERR | FPVIOL;
        _int_enable();                                //EnableInterrupts
}

//==========================================================================
//函数名称:hw_flash_erase_sector
//函数返回:函数执行执行状态:0=正常;非0=异常。
//参数说明:sectorNo:扇区号(K60N512实际使用0~255)
//功能概要:擦除指定flash扇区
//==========================================================================
uint_8 hw_flash_erase_sector(uint_16 sectorNo)
{
    union
    {
        uint_32  word;
        uint_8   byte[4];
    } dest;
   
    dest.word    = (uint_32)(sectorNo*(1<<11));

    // 设置擦除命令
    FTFL_FCCOB0 = ERSSCR; // 擦除扇区命令
   
    // 设置目标地址
    FTFL_FCCOB1 = dest.byte[2];
    FTFL_FCCOB2 = dest.byte[1];
    FTFL_FCCOB3 = dest.byte[0];
   
    // 执行命令序列
    if(1 == hw_flash_cmd_launch())    //若执行命令出现错误
        return 1;     //擦除命令错误
   
    // 若擦除sector0时,则解锁设备
    if(dest.word <= 0x800)
    {
        // 写入4字节
        FTFL_FCCOB0 = PGM4;
        // 设置目标地址
        FTFL_FCCOB1 = 0x00;
        FTFL_FCCOB2 = 0x04;
        FTFL_FCCOB3 = 0x0C;
        // 数据
        FTFL_FCCOB4 = 0xFF;
        FTFL_FCCOB5 = 0xFF;
        FTFL_FCCOB6 = 0xFF;
        FTFL_FCCOB7 = 0xFE;
        // 执行命令序列
        if(1 == hw_flash_cmd_launch())  //若执行命令出现错误
            return 2;   //解锁命令错误
    }  
   
    return 0;  //成功返回
}

//==========================================================================
//函数名称:hw_flash_read
//函数返回:读取字节数。
//参数说明:sectNo:目标扇区号 (K60N512实际使用0~255)
//         offset:读出扇区内部偏移地址(0~2043)
//         cnt:读出字节数目(0~2043)
//         buf:目的数据缓冲区首地址
//功能概要:flash读出操作
//==========================================================================
int hw_flash_read(uint_16 sectNo,uint_16 offset, uint_8 *buf, int_32 iNbrToRead)
{
        int i = 0;
                uint_32 iAddress;
                iAddress = 2048*sectNo + offset;
        while(i < iNbrToRead ) {
           *(buf + i) = *(volatile uint_8*) iAddress++;
           i++;
        }
        return i;
}

//==========================================================================
//函数名称:hw_flash_write
//函数返回:函数执行状态:0=正常;非0=异常。
//参数说明:sectNo:目标扇区号 (K60N512实际使用0~255)
//         offset:写入扇区内部偏移地址(0~2043)
//         cnt:写入字节数目(0~2043)
//         buf:源数据缓冲区首地址
//功能概要:flash写入操作
//==========================================================================
uint_8 hw_flash_write(uint_16 sectNo,uint_16 offset,uint_16 cnt,uint_8 buf[])
{
    uint_32 size;
    uint_32 destaddr;
   
    union
    {
        uint_32   word;
        uint_8  byte[4];
    } dest;
   
    if(offset%4 != 0)
        return 1;   //参数设定错误,偏移量未对齐(4字节对齐)
   
    // 设置写入命令
    FTFL_FCCOB0 = PGM4;
    destaddr = (uint_32)(sectNo*(1<<11) + offset);//计算地址
    dest.word = destaddr;
    for(size=0; size<cnt; size+=4, dest.word+=4, buf+=4)
    {
        // 设置目标地址
        FTFL_FCCOB1 = dest.byte[2];
        FTFL_FCCOB2 = dest.byte[1];
        FTFL_FCCOB3 = dest.byte[0];

        // 拷贝数据
        FTFL_FCCOB4 = buf[3];
        FTFL_FCCOB5 = buf[2];
        FTFL_FCCOB6 = buf[1];
        FTFL_FCCOB7 = buf[0];
        
        if(1 == hw_flash_cmd_launch())
            return 2;  //写入命令错误
    }
   
    return 0;  //成功执行
}

//=================内部函数实现=============================================
//==========================================================================
//函数名称:hw_flash_sign_off
//函数返回:无
//参数说明:无
//功能概要:配置Flash存储控制器,清除Flash预读取缓冲
//==========================================================================
void hw_flash_sign_off(void)
{  
    // 清除缓冲
    FMC_PFB0CR |= FMC_PFB0CR_S_B_INV_MASK;
    FMC_PFB1CR |= FMC_PFB0CR_S_B_INV_MASK;
}

//==========================================================================
//函数名称:hw_flash_cmd_launch
//函数返回:0-成功 1-失败
//参数说明:无
//功能概要:启动Flash命令
//==========================================================================
static uint_32 hw_flash_cmd_launch(void)
{
    // 清除访问错误标志位和非法访问标志位
    FTFL_FSTAT = ACCERR | FPVIOL;
   
    // 启动命令
    FTFL_FSTAT = CCIF;

    // 等待命令结束
    while(!(FTFL_FSTAT & CCIF));

    // 检查错误标志
    if(FTFL_FSTAT & (ACCERR | FPVIOL | MGSTAT0))
        return 1 ; //执行命令出错
  
    return 0; //执行命令成功
}
//==========================================================================


另外我的时钟配置是SYSCLK:48M BUSCLK:3.2M FLExBUSCLK:3.2M FLASHCLK:3.2M,难道是flash时钟太低了? 会不会是这的原因?  
w282529350
5楼-- · 2020-02-21 16:21
本帖最后由 w282529350 于 2014-1-22 10:06 编辑
FSL_TICS_TIANZH 发表于 2014-1-21 15:49
感觉是你对flash的某个操作时间太长,然后引起复位,这个要具体看你的程序了. ...


再次感谢版主的回复,应该是某一个flash指令的执行过程被中断打断了,导致执行时间过长引起芯片的复位,但是具体哪个中断还没有确定,解决办法就是在flash命令执行的过程关闭中断
static uint_32 hw_flash_cmd_launch(void)
{
   _int_disable();                          //DisableInterrupts
    // 清除访问错误标志位和非法访问标志位
    FTFL_FSTAT = ACCERR | FPVIOL;
   
    // 启动命令
    FTFL_FSTAT = CCIF;

    // 等待命令结束
    while(!(FTFL_FSTAT & CCIF));
   _int_enable();                                //EnableInterrupts

    // 检查错误标志
    if(FTFL_FSTAT & (ACCERR | FPVIOL | MGSTAT0))
        return 1 ; //执行命令出错
  
    return 0; //执行命令成功
}
FSL_TICS_ZJJ
6楼-- · 2020-02-21 18:53
感谢楼主的解决方案分享,一般情况下在操作flash的时候,最好关闭中断。

一周热门 更多>