文献标识码: A
文章编号: 0258-7998(2014)11-0009-03
0 引言
在嵌入式系统设计中,经常需要存储一些关键参数,系统在复位或掉电后依赖于保存的这些参数才能正常运行。这些数据通常保存在EEPROM存储器中。随着半导体技术发展,基于Flash技术的单片机越来越多,片内集成的Flash容量也越来越大,处理器片内存储数据已经成为常规选择,不仅可以节约成本,也可以起到较好的保密作用。
保存数据需要考虑产品生命周期内存储器件的读写次数,EEPROM可以承受百万次数量级的擦除/写入操作,NOR Flash存储器擦写次数可达10万次。而微处理器片内集成的Flash相对独立存储器件擦除次数会可能更少,利用片内Flash存储关键参数具有一定风险。因此如何延长片内Flash使用寿命,成为一个研究热点。
本文针对基于Flash技术的嵌入式微处理器设计了一种关键参数容错存储方案,利用大容量Flash以及容错编码来确保数据的可靠以及延长Flash擦除和写操作寿命。本文首先介绍基于写均衡原理的Flash擦除设计,基于冗余存储和纠错编码的容错设计,集成写均衡的容错存储,最后在STM32F103硬件平台进行验证[1]。
1 片内Flash擦写延寿
参数保存的一般方式是为每个参数分配固定的存储地址,可以相互独立进行访问。由于Flash在进行写操作时需要先擦除数据所在的整个扇区,故对一个参数进行写操作便会造成对扇区内其他参数的擦除。由于擦除操作耗时较长,需要考虑对系统实时性的影响,而且为了避免丢失其他参数,对微处理器RAM容量也有一定的要求,至少能保存一个扇区数据内容。
通过在Flash上建立多个数据块,避免对Flash单个扇区的反复擦除,同时通过数据读写方法的设计和数据块的管理,避免对Flash扇区的不必要擦除,提高Flash的使用寿命,这就是写均衡算法的基本原理。
写均衡算法可以分为静态写均衡与动态写均衡两种类型。静态写均衡主要针对只读数据和极少被更新的数据,算法会强行搬移这些数据到擦写次数相对较多的的块中去。该类算法优点是可以有效增加可靠性和使用寿命,缺点是会造成写入数据的速度下降,而且可能会造成额外的不必要的擦除操作。动态写均衡则只限于未使用的空间和经常被更新的数据(即动态数据)。该类算法每次把要写入的数据写入到擦写次数最少的块中去,这样就达到了使写Flash各个块的擦写次数近似相等的目的。
动态写均衡算法用备用区块列表中的块替换旧的块。当系统准备改写某个数据块时,备用区块列表中的第一个块将被用于替换该块,该块将被擦除并放入备用区块列表。动态写均衡中区块和页的更新与回收只发生在空前或者被经常更新的数据占用的块上。如果系统持续对某个块写入数据,将频繁使用备用区块,不使用其它数据块。如果所有备用区块比其它块更早磨损,将会出现最差的情况。
具体实现时,首先根据嵌入式系统的应用需求和MCU内部数据Flash的容量大小,合理设置数据块大小和个数,将数据Flash的若干页面划分为多个数据块[2]。在每个数据块设置块状态字,反映数据块的存储历史时间,不同数据块存储数据不同运行时间的拷贝,当前数据块存储最新的数据拷贝;同时需要检查数据状态是否为下次数据存储擦除页面。
假设一个需要存储64 B参数的系统,每天需要更新参数1 000 次,而片内Flash可以承受10万次擦除/写入循环,即每个单元可以擦除并编程 100 000 次。那么如果不使用写均衡技术,100天就接近Flash的使用寿命。
而如图1所示,采用简单的写均衡处理,假设产品有10年生命周期,设页面大小为2 KB,由:
则n=12,即只需要12个2 KB页面,循环存储64 B参数,就可以满足10年产品生命周期内擦写次数要求。
2 片内Flash容错存储
关键参数容错存储的常规方法主要通过数据多次备份。例如常用的三模冗余(Triple Modular Redundancy,TMR)方法,即对需要保存的参数存储3次,读出时两两进行比较,以比较结果来决定记录结果正确与否。只有当至少两个记录结果相同时,系统才能以此为正确参数,否则给出出错信号。通过多次存储能有效地避免单次记录可能造成的错误,并能有效地弥补存储器因部分单元物理损坏而造成的数据记录结果错误,提高系统的可靠性。
读出操作需要校验数据有效性,有多种方法可以验证数据被正确写入,例如在完成写操作后,写入完成标志到数据块特定位置,这个标志可以用于在电源恢复后判断上次写入是否正常完成,如果没有就需要采取适当的操作。
2.1 数据多页冗余存储
由于片内Flash只能按页面擦除,对一个数据进行写操作同样会造成对页面内其他数据的擦除,对微处理器的RAM容量也有一定的要求,至少能保存读出一个页面数据。如果写入数据失败,会造成所写入数据的丢失,如果在擦除页面后发生掉电,便会造成页面内所有数据的丢失。为了解决这一问题,本文设计了多页冗余存储模式。该模式在进行存储写操作时,并非跟随上次存储地址在页面内连续存储,而是在另一个页面内执行写操作。这样不仅当前参数数据被完整保存,而之前的参数也被完整保存在不同的页面,可以根据需要选择相应页面数,这就是n′。
如图2所示,n′=16,第一次数据存储在Page0,而下次存储在Page1,依次存储在不同页面,而在需要执行擦除操作时,从时间距离上也是擦除最早存储地数据页面,例如当存储到Page15, 需要擦除地是最早存储的页面Page0。
2.2 数据冗余和编码纠错
参数的容错存储另一种重要方法是数据纠错编码和校验编码。读取数据后根据校验编码是否正确以判定有无错误。当发现错误时,按编码规则确定错误所在位置并予以纠正。实现时需要根据硬件平台设计合理的编码方式。
一种较为简单有效的冗余纠错校验编码如图3所示。P0为4 B原始数据,~P0为4 B补码,CRC32为前面12 B的循环校验码。
3 包含容错特性的写均衡设计
根据前面写均衡延长Flash擦除寿命以及数据冗余存储,编码纠错原理,结合两者设计包含容错特性的写均衡存储方案。如图4所示。根据微处理器的性能、实时性需求,可用于数据存储的Flash容量大小,选择合理的M、N(M为一个页面中可以存放的整个需要保存的参数表的个数,N为冗余个数)。
每个参数数据块包含所有需要保存的参数,以及重要参数的纠错编码,数据校验码,用于判断最新有效参数的数据块流水号,数据块写入标志。保存时,需要先完成纠错编码、校验编码,写入指定的当前存储地址。更新该地址指针,指向下一个存储地址,该地址为:
nParAddr=BaseAddr+n×(M×PARSIZE)+m×PARSIZE
(2)
式中:m=0,1,2…M-1,n=0,1,2…N-1。
4 功能验证
STM32系列单片机是一种典型的基于Flash技术的主流微处理器,其片内集成Flash容量从16 KB~1 MB不等,128 KB以下页面大小为1 KB,而128 KB以上页面大小为2 KB[3]。片内Flash都有IAP能力,不仅可以用来存储程序,也可以用于存储数据。
在一个基于STM32F103单片机的设备设计中,需要存储一组参数以及操作记录,参数总字节数56 B,采用容错存储,操作记录仅作为流水记录,在数据存储区循环记录。设计了一组函数实现容错存储:(1)存储结构初始化函数;(2)编码存储函数;(3)校验读操作函数。
初始化函数流程如图5所示。初始化函数实现系统加电或复位后的状态恢复,系统需要能够再次正确找到最新的参数数据块地址。函数在容错存储区,从后往前按块大小搜索数据标志并判断数据完整性,直到找到存储数据块,返回数据块地址。
读操作实现参数读取,数据校验纠错功能。由于STM32F103集成CRC32,因此选择CRC32作为检错函数,减少因增加校验算法带来的延迟。读函数根据数据块地址读取数据块,分别计算各自的CRC32校验码,使用CRC32校验算法再确认冗余存储的反相数据的正确性,校验正确则返回相应数据[4]。
编码存储函数实现数据存储功能,为了减少写操作次数,写之前比较要保存的数据与当前已经存储地参数是否有变化,无变化则直接返回,否则写入当前存储地址,并更新该地址到下一数据块地址。
为了测试系统参数储存设计,增加了流水日志方式存储每次参数存储的块地址。在测试过程中多次人为造成掉电复位,地址记录统计显示系统完好地恢复参数,参数写操作均匀地分布在容错数据区[5]。
5 结论
利用微处理器片内Flash存储系统参数,片内Flash存在必须按块擦除、写寿命有限的问题。通过合理设计写均衡算法,以空间换寿命,同时利用多块存储以及编码纠错实现容错储存,可以有效解决写寿命和可靠性问题。实际应用也证明,这种存储方式无论硬件设计还是系统成本都易于接受,可以保证参数在设计的生命周期许可范围内,确保系统有较强的容错能力,提高控制系统的运行可靠性。该方法对于需要保存参数的单片机系统,如智能仪表、运动控制等领域的系统具有较高的应用价值。
参考文献
[1] 郑文静,李明强,舒继武.Flash存储技术[J].计算机研究与发展,2010,47(4):716-726.
[2] 刘源杨,马建辉,庄汝科,等.基于嵌入式MCU数据Flash的数据存储及管理方法研究与实现[J].电子产品世界,2013(10):57-60.
[3] 李宁.基于MDK的STM32处理器开发应用[M].北京:北京航空航天大学出版社,2008.
[4] 康旺,张有光,金令旭,等.Flash存储中的纠错编码[J].北京航空航天大学学报,2012,38(9):1176-1180.
[5] 陈峰,尹寒.嵌入式系统中的Flash存储管理[J].单片机与嵌入式系统应用,2003(2):19-21,25.