1. 引言
Cdma2000 1x移动通信系统的基站主处理机采用WindRiver公司VxWorks" title="VxWorks">VxWorks嵌入式实时操作系统,选用FLASH 存储器(以下简称FLASH)作为外部存储设备保存系统参数和业务数据。
FLASH与普通磁介质存储器最大的差异在于写操作方式不同,其写操作相对于普通磁盘是比较慢的过程,消耗掉大量的CPU资源。FLASH基于命令字的写操作方式导致的写入错误,虽然几率很小但实际上是存在的。而商用VxWorks操作系统提供的dosFs文件系统和专用TrueFFS文件系统对该情况处理不足,并且用户没有相应的源码,系统一旦出现写操作错误,将不可控制,降低了系统的可控性。所以,有必要对FLASH的存取操作加以改进或控制,并设计一套相对应的专用FLASH文件管理方案,满足系统可控性的要求。
2. 存取设计
FLASH写操作基于命令字方式完成,分为擦除(erase)和编程(program)两个阶段。由于FLASH的编程指令只能使“1”改为“0”,擦除指令只能使“0”改为“1”,而且,擦除操作不能在字节或任意数据区域进行,而必须是一个完整的扇区,所以向FLA
SH某位置写入数据时,要先擦除目标位置所在扇区的所有数据,然后才能进行编程操作。实际上,只须向特定的寄存器写入标准的指令序列,具体的擦除和编程过程就可由内部嵌入的算法执行。
2.1 设计思想
通常,FLASH写操作指令下达后,由驱动程序完成命令字的设置。此时,数据被临时存储于FLASH的锁存器中,但系统仍需要保持数据总线直到写入操作终止或完成才释放。
一个扇区的擦除是十几毫秒的时间,一个字节的写入是几微秒的时间,可以看到,数据总线的占用过程消耗了大量的CPU时间。这部分资源的节约对于嵌入式实时系统来说是必要的。操作系统完全可以在设置写操作命令字后释放数据总线,退出FLASH操作,把擦除/编程过程的CPU时间用来执行其他指令,等当前命令字执行完毕后,通过某个事件的触发,使CPU跳转回来设置下一个命令字。这就是改进FLASH操作过程的设计思想。
2.2 实现过程
触发事件选择和跳转周期长短的控制是问题解决的关键,即在一个命令字操作完成后,选用什么方式来触发下一个命令字操作。可以考虑的方式主要有扫描方式和中断方式。
通过扫描方式,当应用程序完成一次完整的处理周期时,扫描某个标志状态,判断FLASH写入操作是否进行完成。如果完成,则再次设置命令字进行操作。由于程序处理周期取决于应用层业务处理时间,这种方式会导致触发周期不固定。
采用中断方式,可以通过设置中断频率来控制触发周期。但必须选择合适的中断源,使其精度达到要求并且对系统没有额外的影响。由于基站系统采用外部GPS时钟,系统的单板时钟闲置,其精度对于FLASH操作是足够的,所以可以考虑选择CPU时钟中断。问题在于VxWorks对该中断是否有使用。实际上,VxWorks通过该时钟中断完成系统记数器,从而在其基础上实现系统定时器,看门狗定时器,任务分时调度等功能组件。因此,接管时钟中断,必须在修改时钟频率同时,保证操作系统所需的系统记数器频率不变。
VxWorks提供sysClkConnect()函数允许时钟中断发生时,根据指定参数挂接用户定义的中断处理程序,中断处理完成后由用户程序返回。VxWorks提供的usrClock()函数是系统缺省时钟中断处理函数,用来调用计数器函数tickAnnounce(),实现系统计数器的作用。时钟中断频率由SYS_CLK_RATE设定,缺省值是60。因此,我们在替换时钟中断处理函数时,需要包含操作系统的记数器函数tickAnnounce(),并通过分频的方法保证tickAnnounce()的调用和时钟频率修改前的调用频率是一致的,从而使操作系统计数器感觉不到时钟频率修改和中断处理函数被替换的区别。
当然,系统时钟频率的设置不能太高,通常时钟频率设置为60HZ(或100HZ),当频率超过600HZ时,会使内核调度用时比率偏高,而实际任务可用的CPU时间下降,处理器将花费大多数时间来处理时钟而使系统运行效率下降或不可用。
图1给出了具体的实现流程图。sysClkChange()是自定义的系统时钟频率调整控制函数,该函数根据入口参数设置系统时钟中断频率,选择挂接中断的处理函数flsClock()或usrClock()。自定义的中断处理函数的flsClock()通过调用usrClock()函数完成系统计数器功能。sysClkRateGet()和sysClkRateSet()函数是VxWorks提供的时钟频率设置函数。
flsClock()还需要负责实际的写入操作。首先检查上一次中断处理中的FLASH操作是否已经完成。如果没有完成,则返回,并记录返回次数,若返回次数超过了一定限度,即认为该片FLASH发生故障,向应用层发出FLASH故障告警;如果已经完成,则开始进行本次操作,即先确定操作的类型(擦除还是编程)和相关参数(包括目标扇区序号,目的地址,数据源地址等等),然后调用驱动程序提供的FLASH操作接口,完成命令字设置等操作。
3. 管理设计
在I/O系统基本结构中,应用程序可以通过符合标准I/O接口的文件系统调用设备驱动程序来操作设备,也可以直接与驱动程序连接来操作设备(VxWorks本身并不支持这种做法)。通常,采用文件系统来操作存取设备的方式,减少了驱动程序必须支持的I/O操作接口函数的数目,在VxWorks开发中得到广泛的应用。
VxWorks提供与MS-DOS兼容的dosFs文件系统供I/O接口调用,但dosFs文件系统本质上容易受到某种类型磁盘故障的影响,导致更新过程中数据结构不一致性,而且,dosFs文件系统是一个不考虑容错性能的文件系统,没有考虑FLASH操作的特殊性,对于底层驱动程序中FLASH命令字方式导致的写入错误无法处理。作为VxWorks的可选组
件,M-System公司为VxWorks定制的TrueFFS组件提供了面向FLASH的专用文件系统。
TrueFFS文件系统使用block-to-flash转换系统将闪存抽象为普通块设备。基于动态维护的映射图使FLASH索引成一系列连续块。进行数据写入时,如果目标块已写有数据,TrueFFS另找空闲区写入,待数据安全写入后,TrueFFS更新映射图,将该块指向写入的新FLASH地址。TrueFFS文件系统机制非常完善,但基站系统对FLASH功能要求比较单一,存储的数据文件类型和存储方式相对单一,TrueFFS文件系统并不能发挥其强大功能,反而降低了系统的性能。
3.1 设计思想
参考dosFs文件系统和TrueFFS文件系统的管理方法,选取其中重要功能重新设计,实现一个应用层可控的FLASH管理方案。把FLASH划分为管理区和数据区两部分进行组织管理。其中管理区存放文件管理信息,数据区存放数据文件。为了防止在修改管理区的过程中掉电,在存储区的两端设置双备份的管理区。
我们将FLASH最小管理单位定义为一个FLASH扇区(块)。进行FLASH操作之前,先将目标扇区内容备份到内存,在内存中修改完毕后再固化到FLASH。管理区和数据区占用的空间是扇区的整数倍,这样才不会在更新某些数据的同时,造成对已有数据的修改。对于比较小的文件,可能小于一个扇区的空间,导致FLASH空间的浪费,但避免了因为共享同一扇区造成不同文件操作之间的相互影响,降低数据被破坏的可能性,简化管理策略。
3.2 实现过程
根据文件管理方案,假定用户可修改的FLASH块数为512,其中前后两个管理区占用64块,数据区可用448块。FLASH管理区需要包含的内容如表1所示。
任何时刻,处于活动状态的管理区只有一个。在更新数据的时候,首先更新处于活动状态的管理区,然后写入数据文件,等待写入稳定后,更新另一个管理区,然后将另一个管理区置为当前活动状态,原先管理区置为非活动状态。这样可以保证在数据文件写入失败时,通过两个管理区管理信息的一致性来识别数据的有效性。
FLASH块列表的每个字节对应一个扇区的占用情况,1表示该扇区已分配,0表示该扇区未分配,0xff表示该扇区坏死,不能使用。
文件信息记录位置按照系统配置好的处理机数目采用固定顺序存放。更新任何一个数据文件之前,要更新该文件的信息记录,确定该文件操作状态,版本信息和存放位置。具体的组织结构如表2所示。
系统需要从FLASH读取数据时,首先比较两个FLASH管理区管理信息是否一致。如果一致,认为数据有效,直接读取;如果不一致,则说明存在FLASH操作异常,向系统操作维护控制台(OMC)告警,并通知应用程序请求向OMC下载写入新的数据文件。
当需要删除FLASH上数据文件时,只需将管理区中该文件操作状态置成“无效”,并将其占用的扇区置成“未分配”状态,然后更新FLASH管理区信息即可。
这里没有给出碎片收集和垃圾数据处理的机制,实际上,删除操作所实现的功能即有回收垃圾数据所在扇区的作用,并且由应用层控制,实现了系统可控性。对于FLASH中存在的碎片,由于我们采取的是以扇区为单元进行数据管理的,数据文件的存储空间是整数块,而且块列表可以不连续,所以不存在碎片的问题,从而就巧妙的避免了碎片收集的复杂性。
4. 总结
本文介绍的FLASH操作方法以及与之配套的文件管理方案,为系统运行节省了可观的时间,可以很好的解决了业务运行与数据备份之间对系统资源占用的矛盾,对于FLASH操作相对频繁和数据备份实时性要求较高的系统,都是适用的。
5. 参考文献
[1] WindRiver Inc. VxWorks Programmer's Guide 5.4 Edition 1[EB/OL].1999
[2] WindRiver Inc. Tornado User's Guide 2.2 [EB/OL].2002
[3] 陈智育 温彦军等.VxWorks程序开发实践[M].北京:人民邮电出版,2003-9-1.177-200.