概述
电可擦写只读存储器(EEPROM)通常用于工业应用中存储可更新的数据。EEPROM是一种永久性(非易失性)存储系统,用于复杂系统(如计算机)和其他电子设备中,在断电情况下存储和保留少量数据。
出于低成本目的,外部EEPROM可以使用ARM微控制器的片上资源进行替代:
● 片上4 Kbytes备份SRAM
● 片上闪存,配备特定的软件算法
很多ARM微控制器具有4 Kbytes的备份SRAM,当主VDD电源断电时,可以从VBAT电源供电。 只要VBAT存在(通常在电池供电应用中),这个备份SRAM可以作为内部EEPROM使用(无需任何额外软件),具有CPU频率下高速访问的优势。
对于没有备份SRAM用于其他目的和/或应用程序不使用VBAT电源时,可以使用片上闪存存储器(配备特定的软件算法)来模拟EEPROM存储器。
本文探讨了使用MCU微控制器的片上闪存模拟EEPROM机制的软件解决方案。 通过至少使用两个扇区的闪存,模拟是通过在它们填满时交换数据来实现的,这种方式对用户是透明的。
本文力图探讨通过EEPROM模拟驱动程序满足以下要求:
● 提供轻量级实现,提供简单的API,包括初始化、读取数据和写入数据的三个函数,以及减少占用空间。
● 简单且易于更新的代码模型
● 对用户透明的清理和内部数据管理
● 后台扇区擦除
● 至少使用两个闪存存储器扇区,如果可能的话,使用更多扇区进行磨损平衡
模拟的EEPROM大小是灵活的,在扇区大小的限制和约束范围内,并允许最大EEPROM大小。
1 外部与模拟EEPROM的主要差异
EEPROM对于许多嵌入式应用至关重要,这些应用需要在运行过程中以字节或字为单位更新非易失性数据。这些系统中常用的微控制器大多基于内嵌的闪存技术。为了减少组件数量、节省印刷电路板(PCB)空间以及降低系统成本,可以使用MCU微控制器的内嵌闪存代替外部EEPROM,实现代码和数据的同步存储。
与闪存不同,外部EEPROM在重新写入数据前无需进行擦除操作来清空空间。要在内嵌闪存中存储数据,需要特定的软件管理。 模拟软件的设计取决于多种因素,包括EEPROM的可靠性、所用闪存的架构以及产品的具体需求。
对于任何采用相同闪存技术的微控制器来说,内嵌闪存与外部串行EEPROM之间的主要区别是相同的,主要差异在表1中进行了总结。
表1 外部EEPROM与模拟EEPROM的区别
特性 | 外部EEPROM (例如, M24C64: I²C串行访问EEPROM) | 使用片上闪存模拟的EEPROM | 使用片上备份SRAM模拟的EEPROM (1) |
---|---|---|---|
写时间 | 随机字节写入时间5毫秒内 字程序时间20毫秒 页(32字节)写入时间5毫秒 | 半字节程序时间从30微秒至237.25毫秒(2) | 一旦开始,依赖CPU |
擦除时间 | N/A | 删去擦除时间:1秒至3秒(取决于扇区大小) | N/A |
写入方法 | 一旦开始,不依赖CPU 只需要适当的供电 | 一旦开始,依赖CPU 如果CPU复位,写入操作会中断,但当前的闪存写入操作不会被软件复位中断。 可以以字节(8位)、半字(16位)或全字(32位)的方式访问 | 可以以字节(8位)、半字(16位)或全字(32位)的方式访问 软件复位会中断写入操作 |
读取访问 | 串行: 一百微秒 | 并行: (@168 MHz) 半字节的访问时间从0.68微秒到251微秒(2) | CPU速度,带1个等待状态 |
写入/擦除周期 | 100万次写入周期 | 每个扇区(大页面)10,000次写入周期。使用多个片上闪存页面相当于增加写入周期的数量。见第3.4节:循环能力和页面分配。 | 只要VBAT存在就没有限制 |
注:
- 使用片上备份SRAM模拟的EEPROM可以以CPU速度运行,且无需等待状态。
- 半字节程序时间可能因不同的写入操作而有所变化。
请注意,表中的"NA"表示"不适用","CPU"是"中央处理单元"的缩写。此外,表中的时间和操作可能因具体的硬件和软件实现而异。
1.1 写入访问时间的差异
由于闪存具有更短的写入访问时间,关键参数可以在模拟的EEPROM中比在外部串行EEPROM中更快地存储,从而提高数据存储效率。
1.2 擦除时间的差异
擦除时间的差异是独立EEPROM和使用嵌入式闪存模拟的EEPROM之间的另一个主要区别。与闪存不同,EEPROM在写入前不需要擦除操作来腾出空间。这意味着存储数据在闪存中需要某种形式的软件管理。此外,由于闪存块的擦除过程不会持续很长时间,设计闪存管理软件时,应考虑到可能会中断擦除过程的电源关闭和其他异常事件(例如复位)。
为了设计出健壮的闪存管理软件,必须对闪存擦除过程有深入的了解。在MCU微控制器的嵌入式闪存的CPU复位情况下,正在进行的扇区擦除或批量擦除操作不会被中断。
1.3 写入方法的相似性
外部EEPROM和使用MCU微控制器嵌入式闪存模拟的EEPROM之间的一个相似之处是写入方法。
● 独立外部EEPROM:一旦由CPU启动,写入一个字的操作不能被CPU复位中断。只有电源故障会中断写入过程,因此适当地调整去耦电容的大小可以确保在独立EEPROM内部完成整个写入过程。
● 使用嵌入式闪存模拟的EEPROM:一旦由CPU启动,写入过程可能会被电源故障中断。在CPU复位的情况下,MCU的嵌入式闪存上正在进行的字写入操作不会被中断。EEPROM算法会停止,但当前的闪存字写入操作不会被CPU复位中断。
2 实现EEPROM模拟
2.1 原理
在EEPROM模拟中,通常使用一种称为“磨损平衡”的技术,它涉及在多个闪存扇区之间轮换写入操作,以避免过度写入任何一个扇区,从而延长闪存的使用寿命。通过在两个扇区之间交替使用,当一个扇区填满数据时,它将被标记为“RECEIVE_DATA”,而另一个擦除的扇区将变为“VALID_PAGE”,用于新数据的写入。当“RECEIVE_DATA”扇区的数据被完全转移到“VALID_PAGE”扇区时,前者将被擦除并准备好接收新的数据,而后者则变为“ERASED”状态,等待下一次数据写入。
这种模拟方法需要精心设计的软件算法来管理数据在两个扇区之间的移动,确保数据的完整性,并在写入操作期间处理任何可能的电源故障或系统重置。
EEPROM模拟的实现方式多种多样,需要考虑闪存存储器的限制和产品需求。下面详细说明的方法要求至少分配两个相同大小的闪存存储器扇区用于非易失性数据:一个最初被擦除,提供逐字节可编程性;另一个在前者扇区需要进行垃圾回收时准备接管。一个占用每个扇区第一个半字(16位)的头字段指示扇区的状态。这些扇区中的每一个都被视为一个页面,并在本文档的其余部分中被称为页面0和页面1。
头字段位于每个页面的基地址,并提供页面状态信息。 每个页面有三种可能的状态:
● ERASED(已擦除):页面为空。
● RECEIVE_DATA(接收数据):页面正在从另一个已满的页面接收数据。
● VALID_PAGE(有效页面):页面包含有效数据,并且直到所有有效数据完全转移到已擦除的页面,这个状态不会改变。 图1显示了页面状态是如何变化的。
图1. 页面0和页面1之间头状态的切换
表2. 模拟的页面状态及其对应操作
Page1 | Page0 | ||
擦除 | 接收数据 | 无效页 | |
擦除 | 无效状态:擦除两个页面并格式化Page0 | 擦除Page1并将Page0标记为VALID_PAGE | 使用Page0作为有效页面并擦除Page1 |
接收数据 | 擦除Page0并将Page1标记为VALID_PAGE | 无效状态:擦除两个页面并格式化Page0 | 使用Page0作为有效页面并将最近更新的数据传送到Page1,同时将将Page1标记为有效,擦除Page0 |
无效页 | 使用Page1作为有效页面并擦除Page0 | 使用Page1作为有效页面并将最近更新的数据传送到Page0,同时将将Page0标记为有效,擦除Page1 | 无效状态:擦除两个页面并格式化Page0 |
注:表中的"INVALID_STATE"表示当前页面状态组合不是有效的EEPROM模拟状态,需要通过擦除和格式化操作来纠正。
在EEPROM模拟中,维护两个页面的状态是非常重要的,以确保数据的完整性和系统的健壮性。表2展示了在不同页面状态下应采取的行动。例如,如果Page1是ERASED状态而Page0是RECEIVE_DATA状态,那么应该擦除Page1并将Page0标记为VALID_PAGE。如果两个页面都处于INVALID_STATE,则需要擦除两个页面并重新格式化Page0,以恢复到一个已知的初始状态。
通常,在使用这种方法时,用户无法提前知道变量更新的频率。 本文中描述的软件和实现使用了两个16 Kbytes的闪存存储器扇区来模拟EEPROM。
在实际应用中,EEPROM模拟的关键在于软件算法,它负责管理数据在两个闪存扇区之间的迁移和状态转换。用户在使用模拟的EEPROM时,通常不需要关心这些后台操作的细节,他们可以像使用真正的EEPROM一样读取和写入数据。软件需要处理扇区的擦除、数据的读写、以及在电源故障或系统重置情况下的数据恢复。
选择16 Kbytes的扇区用于模拟,是基于以下考虑:
- 数据量:16 Kbytes提供了足够的空间来存储大量的数据,同时保持了对单个字节或字的随机访问能力。
- 耐用性:通过在两个扇区之间轮换写入操作,可以减少单个扇区的写入次数,从而延长闪存的使用寿命。
- 性能:较大的扇区可以减少因频繁擦除和写入小量数据而引起的性能开销。
使用两个16 Kbytes的扇区意味着模拟的EEPROM将具有32 Kbytes的总存储容量,这对于大多数嵌入式应用来说是一个相当大的存储空间,可以存储大量的配置参数或中间数据。此外,使用两个扇区还提供了一种简单的磨损平衡机制,有助于提高系统的可靠性和闪存的耐用性。
每个变量元素由一个虚拟地址和一个要存储在闪存存储器中的值定义,以便后续检索或更新(在实现的软件中,虚拟地址和数据都是16位长)。当数据被修改时,与早期虚拟地址相关联的修改后的数据被存储在一个新的闪存存储器位置。数据检索返回最新的数据值。
图2. EEPROM变量格式
2.2 使用案例:
应用示例 以下示例展示了软件如何管理三个EEPROM变量(Var1、Var2和Var3),它们具有以下虚拟地址:
- Var1的虚拟地址:5555h
- Var2的虚拟地址:6666h
- Var3的虚拟地址:7777h
在EEPROM模拟中,每个变量都关联一个虚拟地址,这个地址是用户在读取或写入数据时使用的。
图3 数据更新流
2.3 EEPROM模拟软件描述
本节描述了使用由MCU固件库提供的Flash存储器驱动程序实现的EEPROM模拟驱动程序。 还提供了一个示例演示程序,用于演示和测试EEPROM模拟驱动程序,该程序使用在软件的main.c文件中声明的VirtAddVarTab[]表中定义的三个变量Var1、Var2和Var3。 该项目除了Flash存储器库源文件外,还包含三个源文件:
● eeprom.c:包含EEPROM模拟固件函数:
——EE_Init():初始化EEPROM。
——EE_Format():格式化EEPROM。
——EE_FindValidPage():查找有效的页面。
——EE_VerifyPageFullWriteVariable():验证页面是否已满,可以写入变量。
——EE_ReadVariable():读取变量。
——EE_PageTransfer():页面传输。
——EE_WriteVariable():写入变量。
● eeprom.h:包含函数原型和一些声明。您可以使用此文件根据应用程序需求调整以下参数:
——要使用的Flash扇区(默认:扇区2和扇区3)。
——设备电压范围(默认:范围4,2.7V至3.6V)。电压在2.1V至3.6V范围内。因此,如果你的应用中设备电压范围是1.8V至2.1V,你必须使用FLASH_ProgramByte()函数,并对固件进行相应的调整。
—— 要使用的变量数据数量(默认:3)
● main.c:这个应用程序是一个示例,它使用描述的例程来从EEPROM读写数据。
用户API定义 在eeprom.c文件中用于EEPROM模拟的函数集在下面的表格中进行了描述:
函数名称 | 描述 |
---|---|
EE_Init() | 如果在数据更新或扇区擦除/传输过程中发生断电,扇区头部可能会损坏。在这种情况下,EE_Init()函数将尝试将模拟的EEPROM恢复到已知的良好状态。在每次断电后访问模拟的EEPROM之前应该调用此函数。它不接受任何参数。该过程在第9页的表2中描述:模拟的页面可能的状态和相应的操作。 |
EE_Format() | 该函数擦除页面0和页面1,并向页面0写入一个VALID_PAGE头部。 |
EE_FindValidPage() | 该函数读取两个页面的头部,并返回有效页面的编号。传递的参数指示是否为了写入或读取操作寻找有效页面(READ_FROM_VALID_PAGE或WRITE_IN_VALID_PAGE)。 |
EE_VerifyPageFullWriteVariable() | 实现写入过程,该过程必须更新或创建变量的第一个实例。它包括在活动页面上找到第一个空位置(从后向前),并用传递的虚拟地址和变量数据填充它。如果活动页面已满,则返回PAGE_FULL值。此例程使用以下参数:虚拟地址:可以是三个已声明变量的虚拟地址之一(Var1、Var2或Var3);数据:要存储的变量的值。此函数在成功时返回FLASH_COMPLETE,如果没有足够的内存进行变量更新则返回PAGE_FULL,或者返回一个Flash存储器错误代码以指示操作失败(擦除或编程)。 |
EE_ReadVariable() | 该函数返回作为参数传递的虚拟地址对应的数据。只读取最后的更新。函数进入一个循环,在其中它读取变量条目,直到最后一个。如果没有找到变量的出现,则ReadStatus变量将返回值为“1”,否则将其重置为指示已找到变量,并将变量值返回在Read_data变量上。 |
EE_PageTransfer() | 将所有变量的最新值(带有相关虚拟地址的数据)从当前页面传输到新的活动页面。它首先确定活动页面,即要从其传输数据的页面。新页面的头部字段被定义并写入(新页面的状态被设置为RECEIVE_DATA,因为它正在接收数据的过程中)。当数据传输完成时,新页面的头部变为VALID_PAGE,旧页面被擦除,其头部变为ERASED。 |
EE_WriteVariable() | 用户应用程序调用此函数来更新一个变量。它使用EE_VerifyPageFullWriteVariable()和EE_PageTransfer()这两个已经描述过的例程。此函数首先尝试在活动页面上更新变量,如果页面已满,则调用EE_PageTransfer()将所有数据转移到新的活动页面,然后再次尝试写入变量。如果写入成功,函数返回FLASH_COMPLETE;如果在尝试写入后页面仍然满,则返回PAGE_FULL;如果在写入过程中发生Flash错误,则返回相应的错误代码。 |
注意:以下函数可用于访问模拟的EEPROM:
- EE_Init()
- EE_ReadVariable()
- EE_WriteVariable()
这些函数在本应用说明中提供的应用程序代码中使用。 图4显示了在EEPROM中更新变量条目的过程。
图4. 写变量流程图
关键特性
● 用户配置的模拟EEPROM大小:用户可以根据应用需求配置模拟EEPROM的大小,这提供了灵活性,允许存储不同数量的数据。
● 提高的闪存存储器耐用性:只有当页面满时才擦除,这种方法称为磨损平衡,可以减少Flash存储器的擦写次数,从而延长其使用寿命。
● 非易失性数据变量可以不频繁更新:由于Flash存储器的特性,非易失性数据可以在不需要频繁更新的情况下存储,适合用于存储配置参数或状态信息。
● 编程/擦除期间可以进行中断服务:在Flash存储器编程或擦除操作期间,系统可以响应中断,这意味着可以处理其他紧急任务,而不会影响数据的存储操作。
2.4 EEPROM模拟存储器占用空间
表5详细列出了EEPROM模拟驱动程序在Flash大小和RAM大小方面的占用空间。
表5. EEPROM模拟机制的存储器占用空间
机制 | Flash(字节) | SRAM |
---|---|---|
EEPROM模拟软件机制 | 984 | 6 |
注:基于一个32位变量(16位用于地址,16位用于数据)。使用的SRAM内存随着使用的变量数量增加而增加。
图5. EEPROM模拟的Flash存储器占用空间(机制和存储)
2.5 EEPROM模拟时序
本节描述了基于两个16 Kbyte EEPROM页面大小的EEPROM模拟驱动程序的时序参数。
所有时序测量都是在以下条件下进行的:
- 基于MCU硬件略有差异
- 在电压范围3(2.7 V至3.6 V)下
- 系统时钟为168 MHz,Flash预取禁用,缓存功能启用
- 从Flash执行
- 在室温下
表6列出了EEPROM的时序值。
表6. 在168 MHz系统时钟下的EEPROM模拟时序
操作 | EEPROM模拟时间 | ||
最小值 | 典型值 | 最大值 | |
---|---|---|---|
典型的变量写EEPROM操作 | 28 µs | - | 255 µs |
变量换页写EEPROM操作 | - | 237ms | - |
典型的变量读EEPROM操作 | 0.68s | - | 251 µs |
EEPROM第一次初始化 | 473ms | ||
典型的EEPROM初始化 | 237ms |
-
无页面交换的写入:最小值指的是在Flash扇区开始处对变量进行写操作的时间,而最大值指的是在Flash扇区末尾进行写操作的时间。最小值和最大值之间的差异是由于寻找空闲Flash地址以存储新数据所需的时间所导致的。
-
变量大小:使用的变量大小为32位(虚拟地址16位,数据16位)。
-
页面交换:当有效页面已满时进行页面交换。这包括将每个变量的最后存储数据转移到另一个空闲页面,并擦除已满的页面。
-
读取操作:最小值指的是对Flash扇区中第一个存储的变量进行读取操作的时间,而最大值指的是对最后一个变量(倒数第二个)进行读取操作的时间。最小值和最大值之间的差异是由于寻找最后存储的变量数据所需的时间所导致的。
-
EEPROM机制的首次运行:当EEPROM机制首次运行或处于无效状态时(有关更多详细信息,请参阅第9页的表2:模拟页面可能的状态和相应的操作),两个页面将被擦除,并且用于存储的页面将被标记为VALID_PAGE。
-
典型的EEPROM初始化:当存在有效页面时(EEPROM至少已初始化过一次),将执行典型的EEPROM初始化。在典型的EEPROM初始化期间,将擦除两个页面中的一个(有关更多详细信息,请参阅第9页的表2:模拟页面可能的状态和相应的操作)。
3 嵌入式应用方面
-
本节提供了如何在嵌入式应用中克服软件限制以及如何满足不同应用需求的建议。
3.1 数据粒度管理
-
在需要以字节、半字或字粒度更新非易失性存储数据的嵌入式应用中可以使用模拟的EEPROM。它通常取决于用户需求和闪存存储器架构(例如,存储的数据长度,写入访问)。
STM32F40x/STM32F41x片上闪存存储器允许根据所使用的电压范围进行8位、16位或字编程,如表7所述。
注:
- 在嵌入式系统中,数据粒度管理是指如何有效地存储和更新数据,这可能涉及到数据的写入单元大小(如字节、半字或字)。
- 闪存存储器的编程粒度可能会影响写入操作的性能和Flash的耐用性。
- MCU 的Flash存储器设计允许不同大小的数据编程,这为不同的应用场景提供了灵活性。
表7. 闪存编程函数
数据粒度 | 按字(32位) | 按半字(16位) | 按字节(8位) (1) |
---|---|---|---|
函数名称 | FLASH_ProgramWord | FLASH_ProgramHalfWord | FLASH_ProgramByte |
功能电压范围 | 2.7 V 至 3.6 V | 2.1 V 至 3.6 V | 所有设备供电电压范围 |
基于字节的编程:按字节写入提供了存储更多数据变量的可能性。
然而,当使用FLASH_ProgramByte()函数时,性能可能会降低。
我们建议您使用FLASH_ProgramHalfWord()函数。这个函数可以同时写入虚拟地址和数据作为一个半字(half-word)。
3.2 磨损均衡:闪存耐久性改进
在MCU的片上闪存中,每个扇区可以可靠地编程或擦除大约10,000次。
对于使用三个或四个以上页面来模拟EEPROM的写入密集型应用,建议实现磨损均衡算法来监控和分配页面之间的写周期数。
如果不使用磨损均衡算法,页面的使用速率将不同。包含长期数据的页面不会像包含频繁更新数据的页面那样经历那么多写周期。磨损均衡算法确保每个扇区都平均使用了所有可用的写周期。
3.2.1 磨损均衡实现示例
在此示例中,为了增强模拟EEPROM的容量,将使用四个扇区(扇区5作为Page0,扇区6作为Page1,扇区7作为Page2,扇区8作为Page3)。
磨损均衡算法的实现如下:当页面n满时,设备切换到页面n+1。页面n进行垃圾回收然后擦除。当轮到Page3满时,设备回到Page0,Page3进行垃圾回收然后擦除,依此类推(请参考图6)。
图6.使用四个页面的页面交换方案(磨损均衡)
在软件中,磨损均衡算法可以通过EE_FindValidPage()函数来实现(请参考表4)。
3.3 电源丢失时的页面头恢复
在变量更新、页面擦除或传输过程中,如果出现电源丢失,数据或页面头可能会出现损坏。
为了检测这种损坏并从其中恢复,实现了EE_Init()例程。它应该在上电后立即被调用。该例程的原理在本应用说明中有描述。该例程使用页面状态来检查完整性并在必要时执行修复。
在电源丢失后,EE_Init()例程用于检查页面头状态。有9种可能的状态组合,其中三种是无效的。表2:模拟页面可能的状态和电源上电时对应的操作在第9页显示了基于页面状态应采取的操作。
3.4 循环能力和页面分配
3.4.1 循环能力
一个编程/擦除周期包括一个或多个写访问和一个页面擦除操作。
当使用EEPROM技术时,每个字节可以编程和擦除有限次数,通常在10,000到100,000次之间。
然而,在嵌入式闪存存储器中,最小的擦除大小是扇区,且一个扇区上应用的编程/擦除周期次数就是该扇区可能的擦除周期数。MCU的电气特性保证每个扇区有10,000次编程/擦除周期。因此,模拟EEPROM的最大寿命由此最常被写入参数的更新速率所限制。
循环能力取决于用户想要处理的数据量/大小。在这个例子中,使用了两个扇区(每个16 Kbytes),并用16位数据进行编程。每个变量对应一个16位的虚拟地址,即每个变量占用一个字的存储空间。一个扇区可以存储16 Kbytes乘以闪存存储器的10,000次擦除周期,为模拟EEPROM内存中一个页面的寿命提供了总共160,000 Kbytes的数据存储容量。因此,如果使用两个页面进行模拟过程,可以在模拟EEPROM中存储320,000 Kbytes的数据。如果使用超过两个页面,这个数字将相应地乘以更多。
知道了存储变量的数据宽度,就可以计算在模拟EEPROM区域的寿命期间可以存储的变量总数。
3.4.2 Flash页面分配
EEPROM模拟应用所需的扇区大小和扇区数量可以根据系统寿命期间写入的数据量来选择。例如,一个16-Kbyte页面,具有10 Kbyte的擦除周期,可以用来在系统寿命期间写入最大160兆字节的数据。一个128-Kbyte页面可以用来在系统寿命期间写入最大1280兆字节的数据。
空闲变量空间可以按以下方式计算:
FreeVarSpace = (PageSize) / (VariableTotalSize) - [NbVar+1]
其中:
● PageSize:页面大小,以字节为单位(例如,16 Kbytes)
● NbVar:正在使用的变量数量(例如,10个变量)
● VariableTotalSize:存储一个变量所用的字节数(地址和数据)
——对于32位变量,VariableTotalSize = 8(32位数据 + 32位虚拟地址)
——对于16位变量,VariableTotalSize = 4(16位数据 + 16位虚拟地址)
——对于8位变量,VariableTotalSize = 2(8位数据 + 8位虚拟地址)
可以按以下方式估算在应用程序寿命期间保证可预测的Flash操作所需的页面数量:
所需页面数量: NbPages = NbWrites / (PageEraseCycles * FreeVarSpace)
其中:
● NbPages = 所需的页面数量
● NbWrites = 变量写入的总数
● PageEraseCycles = 页面的擦除周期数
注:如果变量是16位的,每个变量占用32位(16位数据,加上一个16位的虚拟地址),这意味着每次写入新数据时,每个变量都会使用4字节的闪存。每个16K字节(或128K字节)的页面在满之前可以容纳4096(或32768)次变量写入。
注:这个计算是一个稍微保守的估计。
3.4.3使用案例示例
为了设计一个应用,该应用每2分钟更新20个不同的变量,持续10年:
- 变量数量(NbVar)= 20
- 写入次数(NbWrites)= 10年 * 365天/年 * 24小时/天 * (60分钟/2分钟) * 变量数量(NbVar)= 大约5200万次写入
针对不同变量大小和地址宽度的情况,所需的页面数量如下:
● 如果变量是8位数据,带有8位虚拟地址,保证所有这些数据非易失性存储所需的页面数量为:
- 16 K字节的两页 或 - 128 K字节的两页
(注意:对于8位数据和8位地址,实际上每个变量只需要16位即2字节的存储空间,因此16 K字节页面可以容纳4096次写入,两个页面足够容纳约819万次写入,远超过所需的5200万次写入的三分之一,所以这个估计是保守的。)
● 如果变量是16位数据,带有16位虚拟地址,保证所有这些数据非易失性存储所需的页面数量为:
- 16 K字节的两页 或 - 128 K字节的两页
(注意:对于16位数据和16位地址,每个变量需要32位即4字节的存储空间,因此16 K字节页面可以容纳4096次写入,两个页面足够容纳约1638万次写入,这个数量也远大于所需的5200万次写入。)
● 如果变量是32位数据,带有32位虚拟地址,保证所有这些数据非易失性存储所需的页面数量为:
- 16 K字节的三页 或 - 128 K字节的两页
(注意:对于32位数据和32位地址,每个变量需要64位即8字节的存储空间,因此16 K字节页面可以容纳2048次写入,三个页面足够容纳约6144万次写入,这个数量超过了所需的5200万次写入。)
3.5 实时性考虑
提供的EEPROM仿真固件实现在内部Flash上运行,因此在执行需要Flash擦除或编程的操作(如EEPROM初始化、变量更新或页面擦除)时,对Flash的访问将被阻塞。结果是,应用程序代码不会执行,中断也无法得到服务。
这种行为对于许多应用来说可能是可以接受的,但对于有实时约束的应用,你需要从内部RAM运行关键进程。
在这种情况下:
-
将向量表重新定位到内部RAM。
-
从内部RAM执行所有关键进程和中断服务程序。编译器提供了一个关键字来声明函数为RAM函数;该函数在系统启动时从Flash复制到RAM,就像任何初始化的变量一样。重要的是要注意,对于RAM函数,所有使用的变量和调用的函数都应该在RAM中。
简而言之,对于实时系统,为了确保关键操作在Flash操作期间不会受到影响,你需要将关键代码段(包括中断服务程序)从Flash移至RAM中执行。这确保了即使在Flash被阻塞进行写操作的情况下,实时任务也能继续执行。同时,确保这些RAM函数所依赖的所有变量和函数也都位于RAM中。