【飞思卡尔 MC9S12】内部Flash读写

本文介绍了飞思卡尔MC9S12微控制器的内部Flash读写操作,强调了在操作Flash时代码不能存储在被操作的Flash块中的原则。文章提出了将Flash操作代码存储到RAM中的解决方案,并详细阐述了如何提取和执行函数的二进制代码,以及Flash的擦除和写入流程。此外,还提到了PFlash和DFlash的差异以及使用示例。
摘要由CSDN通过智能技术生成

上一篇:【飞思卡尔 MC9S12】PRM文件与内存映射(Flash、RAM、EEE)

上一篇讲到PRM文件与内存映射,其中有个重要寄存器叫做GPAGE,可以全局访问所有地址范围,Flash操作也是基于这个地址。

在讲述Flash读写之前,有一个重要概念要普及,就是Flash操作代码不能存储在被操作的Flash物理块中,例如我要擦除一个Flash中某一个扇区内容,这个擦除动作的代码不能存在这个Flash物理块中(Flash中代码运行时,相当于读操作,此时不能擦写)。

那我们如何擦写Flash呢?

很简单,只有一个解决方案,就是将Flash操作代码存储到RAM中。不过,就我们以往的理解,函数都是存储在Flash中的,如何存储到RAM中呢?

由这个解决方案引申出好几个子解决方案。

一、通过在PRM文件中设置 RAM RELOCATE_TO 到对应的Flash块,运行时将代码复制到这块RAM中,这样执行函数时,实际上是在RAM中执行;

二、直接将操作函数的二进制存到数组中,将数组当做函数体执行。

 

此处我们使用第二种方案,这种方案PRM比较简洁,无需多余设置,函数执行前也不需要进行Copy动作。

不过这个方案最大的难点在于:如何获取到函数的二进制代码,并在RAM中执行?

这实际上是两个问题。我们下面先解决这两个问题,然后再讲述Flash操作详细流程。

Flash擦除或写入都是先将地址及数据写到寄存器中,最后运行启动执行指令,只有这个执行指令需要放到RAM中。这个指令如下:

FSTAT = 0x80; //执行擦写命令
while(FSTAT_CCIF == 0U);  //等待操作完毕

我们先将这个操作的二进制代码提取出来。

新建一个CodeWarrior工程,默认即可,删除掉Start12.c和datapage.c,修改main.c中的内容,改为如下:

#include <hidef.h>      /* common defines and macros */
#include "derivative.h"      /* derivative-specific definitions */


void _Startup(void) 
{
    FSTAT = 0x80;
    while(FSTAT_CCIF == 0U);
}

编译,查看S19文件。

S0610000473A5C576F726B5C50726F6A656374735C467265657363616C655C4D43395331325845503130305C436F6D6D6F6E5C4D43395331325F426F6F746C6F616465725C434349465F416E645F576169745C62696E5C50726F6A6563742E6162732C
S10EC000C6807B01061F010680FB3D8B
S105FFFEC0003D
S9030000FC

第一行为文件名,第二行为代码二进制,第三行为Vector Table,我们需要的是第二行。

S1 0E C000 C6 80 7B 01 06 1F 01 06 80 FB 3D 8B

我们将红色部分的代码二进制存到数组中,然后就可以直接在RAM中使用代码了(实际上就是通过汇编跳到函数的起始地址)。

//RAM中定义的函数
unsigned char flash_fire_and_wait[11]={0xC6,0x80,0x7B,0x01,0x06,0x1F,0x01,0x06,0x80,0xFB,0x3D};

//运行RAM中的函数
_asm("JSR flash_fire_and_wait");

 

好,最基本的问题解决了,现在我们来看看Flash擦写具体流程(PFlash与DFlash原理相似,只是Sector大小和操作指令不同,此处专讲PFlash,下一篇将DFlash模拟EEPROM)。

需要注意的是,Flash操作时钟只能分频到1MHz左右,具体的参考手册上有表格,对应各个晶振频率的分频数。

先贴上所有代码。

#include <hidef.h>      /* common defines and macros */
#include "derivative.h"      /* derivative-specific definitions */

#include "Typedefs.h"
#include "flash.h"
#include "string.h"




/**** P-Flash and D-Flash Commands ****/

#define ERASE_VERIFY_ALL_BLOCKS  0x01 
/* Verify that all program and data Flash blocks are erased. */
/* CCOBIX end = 0 */
/* CCOB Params - NONE */
/* MGSTAT set if fault */

#define ERASE_VERIFY_BLOCK       0x02      
/* Verify that a Flash block is erased. */
/* CCOBIX end = 0 */
/* CCOB Params - gpage */
/* MGSTAT set if fault */

#define ERASE_ALL_BLOCKS         0x08 
/* Erase all program and data Flash blocks.
   An erase of all Flash blocks is only possible when the FPLDIS, FPHDIS, and FPOPEN
   bits in the FPROT register and the EPDIS and EPOPEN bits in the EPROM register are
   set prior to launching the command. */
/*
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值