第3节 FLASH模块的解释
本文档举例说明了如何简单地配置和使用FLASH模块。编程人员可以很快地将它应用到自己的工程中。实例代码给出了通过M5213EVB板如何将一个长字写入flash中。代码还包含了将一个函数从ROM中复制到RAM,并在易失性存储器中执行的例程。从ROM中读取代码时,不能对它进行修改。
Flash内部是按以下方法划分的:
● 逻辑块 —— 只有一块(5212和5213中有256KB,5211中有128KB)。
当正在对某块进行擦除、编程或检验时,该块不可读。
● 物理块 —— 每个逻辑块有两个物理块
● 扇区 —— 逻辑块的一部分。整个逻辑块有32个扇区,每个扇区为8KB,也称为一个逻辑扇区
● 逻辑页 —— 每页为2KB
根据图1,整个逻辑块被分成多个扇区。每个扇区都可被编程为:
● 编程和擦除保护
● 声明为只作监控地址空间
● 存放数据或数据和指令的地址空间

图1 FLASH扇区的划分
整体擦除:擦除整个flash存储空间。必须禁止所有的flash存储保护
空白检测:验证整个flash空间都被擦除了
页擦除校验:验证flash的一个逻辑页被擦除了
3.1 实例:CFM模块的案例学习
编程代码在ROM中执行后,通过串口(UART0)显示信息,为了测试将一份长字菜单写入到flash中:
[0] 0xdeadbeef
[1] 0xcafebabe
[2] 0xbabadada
[3] 0xdecafbad
[4] 0xfeedface
[5] 0xdeadc0de
[6] 0xabadbabe
[7] 0xfeedbabe
[8] 0x00000000
[9] 0xFFFFFFFF
然后,串口终端等待输入与各长字有关的序号(如上所示),程序将执行下列操作:
3.2 实例:CFM时钟的配置
公式1给出了将flash频率维持在150kHz≤fCFM≤200kHz之内的公式,并作为内部flash的规范状态。

CFMCLKD [DIV[5:0]]:选择这样的公式1是有效的
CFMCLKD[PRODIV8]:如果fCORE大于12.8MHz,则置1
3.3 实例: CFM模块的配置
在第3节“实例:CFM模块的案例学习”选择了一个长字后,程序请求另一个选项。代码的最重要部分是从ROM中复制一个函数到RAM中,然后在RAM中执行该函数。然后所选的长字被删除了。
将一个函数从ROM中复制到RAM中有两种方法:
1.编译器无关代码(代码命名为CFMSoftwareDEMO)
Flash内部是按以下方法划分的:
● 逻辑块 —— 只有一块(5212和5213中有256KB,5211中有128KB)。
当正在对某块进行擦除、编程或检验时,该块不可读。
● 物理块 —— 每个逻辑块有两个物理块
● 扇区 —— 逻辑块的一部分。整个逻辑块有32个扇区,每个扇区为8KB,也称为一个逻辑扇区
● 逻辑页 —— 每页为2KB
根据图1,整个逻辑块被分成多个扇区。每个扇区都可被编程为:
● 编程和擦除保护
● 声明为只作监控地址空间
● 存放数据或数据和指令的地址空间

图1 FLASH扇区的划分
在运行时,可以通过以下操作来修改flash:
字编程:写入一个32位的字
页擦除:擦除flash的一个逻辑页
字编程:写入一个32位的字
页擦除:擦除flash的一个逻辑页
空白检测:验证整个flash空间都被擦除了
页擦除校验:验证flash的一个逻辑页被擦除了
3.1 实例:CFM模块的案例学习
编程代码在ROM中执行后,通过串口(UART0)显示信息,为了测试将一份长字菜单写入到flash中:
[0] 0xdeadbeef
[1] 0xcafebabe
[2] 0xbabadada
[3] 0xdecafbad
[4] 0xfeedface
[5] 0xdeadc0de
[6] 0xabadbabe
[7] 0xfeedbabe
[8] 0x00000000
[9] 0xFFFFFFFF
然后,串口终端等待输入与各长字有关的序号(如上所示),程序将执行下列操作:
- ● 读flash地址0x6000:检查最后一次写入是否成功
- ● 从0x6000地址开始擦除一页(2KB):在运行期间它被写入到flash中,只对这些位清0而不置1。只有通过清空这些位,执行擦除操作,该空间才可以写入新的长字。
- ● 写flash地址0x6000:这个字的验证在下一个读空间。
3.2 实例:CFM时钟的配置
公式1给出了将flash频率维持在150kHz≤fCFM≤200kHz之内的公式,并作为内部flash的规范状态。
CFMCLKD[PRODIV8]:如果fCORE大于12.8MHz,则置1
3.3 实例: CFM模块的配置
在第3节“实例:CFM模块的案例学习”选择了一个长字后,程序请求另一个选项。代码的最重要部分是从ROM中复制一个函数到RAM中,然后在RAM中执行该函数。然后所选的长字被删除了。
将一个函数从ROM中复制到RAM中有两种方法:
1.编译器无关代码(代码命名为CFMSoftwareDEMO)
- a) 声明一个变量,用于存放来自ROM的整个函数。这是在运行期间可以修改的RAM中的保留位置
- b) 在RAM中声明一个函数指针,指向RAM中存放函数的那个变量。从字符到函数指针的传递是必要的。
- c) 利用stdio.h库中的memcopy函数,将ROM中的整个函数空间复制到那个RAM中的变量。
- d) 执行那个指向变量的函数,该变量存储在RAM中的一个函数。这样就能在RAM中执行那个函数,返回到flash后可以继续执行那里的代码。
- e) 如果只从ROM中复制一个函数到RAM,就不需要修改lcf文件。
- a) 从CodeWarrior的ROM.lcf文件中声明一个存储段
- b) 之后,它就在RAM中声明一个段来存放函数
- c) 从代码中声明一个与那个段同名的段
- d) 将函数写入该段


