×
嵌入式 > 技术百科 > 详情

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

发布时间:2024-05-20 发布时间:
|

上一篇讲到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 /* 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 /* 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. */

/* CCOBIX end = 0 */

/* CCOB Params - NONE */

/* MGSTAT set if fault, FPVIOL / ACCERR set where appropriate */

#define UNSECURE_FLASH 0x0B

/*Supports a method of releasing MCU security by erasing all program and data Flash

blocks and verifying that all program and data Flash blocks are erased. */

/* CCOBIX end = 0 */

/* CCOB Params - NONE */

/* MGSTAT set if fault */

#define SET_USER_MARGIN_LEVEL 0x0D

/*Specifies a user margin read level for all program Flash blocks. */

/* CCOBIX end = 1 */

/* CCOB Params - gpage, level setting (0-2) in CCOB[1] */

/* ACCERR set if invalid level */

#define SET_FIELD_MARGIN_LEVEL 0x0E

/*Specifies a field margin read level for all program Flash blocks (special modes only). */

/* CCOBIX end = 1 */

/* CCOB Params - gpage, level setting (0-4) in CCOB[1] */

/* ACCERR set if invalid level */

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

/* **** P-Flash Only Commands ****/

#define ERASE_VERIFY_P_FLASH_SECTION 0x03

/*Verify that a given number of words starting at the address provided are erased. */

/* CCOBIX end = 2 */

/* CCOB Params - global address, number of phrases in CCOB[2]*/

/* MGSTAT set if fault */

#define READ_ONCE 0x04

/* Read a phrase from a dedicated 64 word area in a hidden region of a programFlash block

that was previously programmed using the Program Once command. */

/* CCOBIX end = 1 */

/* CCOB Params - read once index (0-3) in CCOB[1], phrase in CCOB [5:2] */

/* returns phrase in CCOB [4:1] */

#define PROGRAM_P_FLASH 0x06

/* Program a phrase in a program Flash block and any previously loaded phrases for any

other program Flash block (see Load Data Field command). */

/* CCOBIX end = 5 */

/* CCOB Params - global address, phrase in CCOB [5:2] */

/* MGSTAT set if fault, FPVIOL / ACCERR set where appropriate */

#define PROGRAM_ONCE 0x07

/* Program a dedicated 64 word area in a hidden region of a program Flash block that is

allowed to be programmed only once. */

/* CCOBIX end = 5 */

/* CCOB Params - read once index (0-3) in CCOB[1], phrase in CCOB [5:2] */

/* MGSTAT set if fault */

#define ERASE_P_FLASH_BLOCK 0x09

/* Erase a program Flash block.

An erase of the full program Flash block is only possible when FPLDIS, FPHDIS and

FPOPEN bits in the FPROT register are set prior to launching the command. */

/* CCOBIX end = 1 */

/* CCOB Params - global address */

/* MGSTAT set if fault, FPVIOL / ACCERR set where appropriate */

#define ERASE_P_FLASH_SECTOR 0x0A

/* Erase all bytes in a program Flash sector. */

/* CCOBIX end = 1 */

/* CCOB Params - global address */

/* MGSTAT set if fault, FPVIOL / ACCERR set where appropriate */

#define VERIFY_BACKDOOR_ACCESS_KEY 0x0C

/*Supports a method of releasing MCU security by verifying a set of security keys. */

/* CCOBIX end = 4 */

/* CCOB Params - backdoor key in CCOB [1:4] */

/* ACCERR set if not verified */

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

/**** D-Flash Only Commands ****/

#define ERASE_D_FLASH_BLOCK 0x09

/* Erase a program Flash block.

An erase of the full program Flash block is only possible when DPOPEN bit in the DFPROT

register is set prior to launching the command. */

/* CCOBIX end = 1 */

/* CCOB Params - global address */

/* MGSTAT set if fault, FPVIOL / ACCERR set where appropriate */

#define ERASE_VERIFY_D_FLASH_SECTION 0x10

/* Verify that a given number of words starting at the address provided are erased. */

/* CCOBIX end = 2 */

/* CCOB Params - global address of first word, number of words to verify CCOB[2]*/

/* MGSTAT set if fault */

#define PROGRAM_D_FLASH 0x11

/* Program up to four words in the data Flash block (see Load Data Field command). */

/* CCOBIX end = 2 */

/* CCOB Params - global address, up to 4 data words in CCOB [2:5] */

/* MGSTAT set if fault, EPVIOL / ACCERR set where appropriate */

#define ERASE_D_FLASH_SECTOR 0x12

/* Erase all bytes in a data Flash sector. */

/* CCOBIX end = 2 */

/* CCOB Params - global address */

/* MGSTAT set if fault, EPVIOL set where appropriate */

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

#define ENABLE_EEPROM_EMULATION 0x13

// Requests the FTMSM to enable EEPROM emulation.

// CCOBIX end = 0

// CCOB Params - NONE

#define DISABLE_EEPROM_EMULATION 0x14

// Requests the FTMSM to suspend all current erase and program activity related to

// EEPROM emulation but leave current EEE tags set.

// CCOBIX end = 0

// CCOB Params - NONE

#define CANCEL_EEPROM_EMULATION 0x15 /* M22E mask only */

// Requests the FTMSM to suspend all current erase and program activity related to

// EEPROM emulation and clear all outstanding EEE tags.

// CCOBIX end = 0

// CCOB Params - NONE

#define EEPROM_QUERY 0x15 /* M48H mask only */

// Requests EEE status information.

// CCOBIX end = 0

// CCOB Return Params -

// CCOB[1] DFPART - size of D-Flash user partition (x256 bytes)

// CCOB[2] ERPART - size of EEE ram (x256 bytes)

// CCOB[3] ECOUNT - typical number of erase cycles for the EEE sectors

// CCOB[4] Dead sector count / Ready sector count

#define PARTITION_D_FLASH 0x20 /* M48H mask only */

// Partition a section of D-Flash for user access and EEE.

// CCOBIX end = 2

// CCOB Params - n

[1] [2] [3]
飞思卡尔MC9S12内部Flash读写

『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
FPGA及CPLD应用领域不断拓展