首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

程序执行时写闪存的应用实例

程序执行时写闪存的应用实例

转载自《电子工程专辑》
作者:肖德勇
产品开发软件经理


闪存(flash)是一种可在线进行电擦写,掉电后信息不丢失的存储器。它具有低操作电压、低功耗、大容量、擦写速度快等特点。在嵌入式系统中广泛使用闪存来保存程序。在实际应用中为了节省整个嵌入式系统的成本和系统复杂程度,整个系统仅设计成具有一块闪存,CPU执行的程序被保存在闪存中,设备产生的重要数据也保存在该闪存中,且这些数据必须在设备运行过程中及时进行更新保存。因此要求系统在程序执行时必须完成向闪存中保存数据信息的功能,也就是CPU从闪存中取指执行程序时,同时向闪存中写入数据。绝大多数闪存芯片是不支持同时对芯片进行读写操作的。本文通过一个完整的应用实例,详细介绍了在应用程序执行过程中写SST32HF162的方法,并提供了相应的C语言源程序代码,同时对C语言代码的可行性进行了详细的分析。

图1:写闪存流程。

介绍IAP吗?请继续,期待你的转贴

图2:写扇区流程。

[此贴子已经被作者于2005-12-8 11:30:23编辑过]

SST32HF162存储器特点

SST32HF162是来自SST公司的Combo存储器,其结构为1M×16闪存+128K×16 SRAM。它的主要特点如下:2.7~3V单电源供电;读写SRAM时可同时对闪存进行读写操作;支持JEDEC单电源闪存存储器标准;向其命令寄存器写入相应的指令即可完成闪存的擦除、写操作;通过查询特定的数据位可监控擦除或写操作是否完成。可对任一扇区、块进行读、写或擦除操作,而不影响其它部分的数据;扇区大小为2K字;支持字节编程方式。

向闪存的特定寄存器连续写入3个特定的字节可开始一个写循环,而后写入地址以及相应的数据就可对闪存进行编程操作。在写闪存期间仅有读检测位有效,其他命令都将被忽略。由于编程指令不能使闪存中的逻辑“0”改写为“1”,因此在编程闪存时必须先进行擦除操作。闪存编程命令见表1。

 

 

 

 

 

 

系统环境描述

用单一的平板地址空间,该地址空间的大小为232个8位字节。这些字节单元的地址是一个无符号的32位整数值,其取值范围为0到232-1。ARM体系支持32位或16位的数据总线,本文介绍的系统使用16位的数据总线,因此ARM的地址空间可以看作是231个16位的半字单元。

源程序代码要求系统环境中有SRAM,SRAM的大小至少能容纳写一个字到闪存中的程序代码。对于SRAM以及闪存的实际地址分配没有特别要求。

[此贴子已经被作者于2005-12-8 11:33:35编辑过]

写闪存过程

1.搬移闪存中的程序到SRAM中

系统中仅设计有一块闪存,且同块闪存在写入时读出的数据无效,因此在闪存写入期间MCU不能再从闪存中取指执行程序。因在读写SRAM时可以进行闪存的写入操作,所以我们可以将写闪存时MCU将执行的代码全部搬移到SRAM中,强制程序在SRAM中执行。通过执行SRAM中的程序完成对闪存的擦除以及写入的工作。

2.闪存写入以扇区为单位

在进行闪存写入时,首先必须进行擦除,而后再编程闪存。闪存擦除时以扇区为单位,在本应用中每个扇区为2K字。当每次写入数据少于一个扇区的大小时,原来保存在该扇区中的信息将被擦除。因此在进行写闪存时必须先读出原来在该区中保存的信息,而后与准备写入的信息共同组成一个扇区内容,再开始写闪存的操作。

程序实现流程见图1和图2。

图3:WriteWord函数编译后生成的伪代码。

[此贴子已经被作者于2005-12-8 11:42:09编辑过]

源程序技术难点分析

以上两个C语言函数在编译完成后将作为程序代码的一部分,它将和其他程序代码一样保存在闪存中。为此将产生的问题1:WriteWord函数是怎样被搬移到SRAM中的?问题2:WriteWord函数代码被搬移到SRAM中后因此时函数保存起始地址发生变更,函数还能正确运行吗?

对于第一个问题的解决,在程序中定义了proginram这个全局静态数组,该数组在ARM编译器进行编译时将被标记为zidata段映象,这种映象将在程序运行时自动在RAM空间分配相应的内存区域。因此当将WriteWord函数起始地址的信息保存到proginram数组中时,就完成了代码从闪存中搬移到SRAM中的操作。

对于问题2,整个程序指令都是由顺序指令以及分支指令组成的。顺序指令指程序执行完当前指令后将执行紧接着它的下一条指令。分支指令指程序执行完当前指令后将执行该指令之前或之后某个偏移处的指令。在程序执行时,CPU将使用PC指针来标记当前运行的程序地址。

1.指令执行

对于顺序指令,PC指针总是自动完成指向下一条执行指令的增1操作,只要PC的首地址正确,程序将正确的执行直到代码结束。

2.分支指令

对于分支指令,在程序执行过程中确定正确的目标跳转地址将是程序能否正确运行的关键。在ARM体系中,跳转指令有:B/跳转指令;BL/带返回的跳转指令;BLX/带返回和状态切换的跳转指令;BX/带状态切换的跳转指令。现在以B(跳转指令)为例进行说明跳转指令的执行情况。

每条B指令由表2中的4字节内容组成,其中跳转目标地址的计算方法是:将指令中的Signed_immed_24这24位带符号数的补码扩展为32位(扩展其符号位);将此32位数左移两位;将得到的数加到PC寄存器中,得到跳转的目标地址。因此有如下结论:跳转指令的执行是以当前PC指针值为基准的,在闪存保存的程序仅保存了跳转的偏移量。

WriteWord函数编译后生成的伪指令如图3中灰色字体。

从函数产生的伪代码可以看出,对于WriteWord函数,在编译后形成的指令由一些数据操作指令以及跳转指令B组成,而对于数据操作指令都是顺序执行的。而跳转指令B的执行情况前面已经进行了相应的分析,因此函数WriteWord从闪存中移入SRAM中后依旧可以正确运行。

设计要点小结

1. 在应用程序中写闪存时必须先将相应的写程序搬移到SRAM中,通过执行SRAM中的程序完成写闪存功能。不能既执行闪存中的程序又写该片闪存。

2. 在写闪存时必须保证不破坏原来的数据,同时必须禁止系统的中断以防止执行存储在闪存中的中断响应程序。

3. 因为程序是静态编址的,即程序在编译链接时就已经确定了指令执行期间的跳转目标地址,因此必须确定原存储在闪存中的程序搬移到SRAM中后,该代码段在新的起始地址是否能正确执行。
好久没来,好东西多了不少!强烈支持楼主!
返回列表