《EmbeddedCodeStorage_web》一文中介绍了一些通用的嵌入式代码存储方式,尽管本文的重点是要详细讨论有关基于Balanced XIP方式的嵌入式代码存储。但在讨论anced XIP之前,我们不妨顺着作者的思路来回顾一下目前最为常用的一些嵌入式代码存储方式。<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
eXecute-In-Place(XIP)、Fully Shadowed和Demand Paging是三种目前广为使用的代码存储方式,或者更确切的理解,应该称之为代码运行方式,他们又分别是怎样的一种运行方式呢?
首先说eXecute-In-Place(XIP),非得要译成中文就叫它“就地执行”。它的意思和它的名字一样,表示代码可以在当前的存储器中执行。网络上搜到一段关于XIP定义的论述,如下:
XIP即就地执行的意思,操作系统内核直接在Flash中运行,不需要拷贝到RAM。但是,Flash的存储器访问周期要比RAM大得多,在使用XIP技术后可能会降低程序的运行速度,不过由于CPU的指令预取机制以及Cache机制,实际使用起来并不会明显降低应用程序的运行速度。XIP的原理很简单,即指操作系统或应用程序直接从非易失性存储器中执行。就当前的技术来说,这里的非易失性存储器特指NOR型Flash,因为只有N0R型的Flash才可以随机存取。
除了硬件提供支持以外,XIP还需要软件的支持。操作系统内核和应用程序在运行时,它在内存中的映像可以分为三个部分:代码段、数据段和堆栈段。代码段对应于执行程序中的Text Section,其中包括运行代码和只读数据,这个段在内存中一般被标记为只读。数据段对应于运行文件中的Data Section和BSS Section,其中存放的是各种数据(经过初始化的和未经初始化的)和静态变量,而堆栈段存放的则用于保存函数调用和局部变量。从以上分析可知,程序运行时在内存的映像分为两类:一类是只读的,如代码段;另一类是可写的,如数据段。而Flash虽然是可写的,但并不能像写普通RAM一样进行。因此,当程序在Flash中运行时,我们仍然需要把部分可写的数据段放在RAM 中。
XIP是一种能够直接在闪速存储器中执行代码而无须装载到RAM中执行的机制。这样减少了内核从闪速存储器拷贝到RAM的时间,并采用非压缩映像减少了内核自解压的时间。由于闪速存储器访问速度低于RAM,采用XIP技术的同时,根据硬件环境对闪速存储器和RAM使用量进行平衡。
可见XIP方式主要是应用在NOR闪存上,而并不适合NAND闪存,最主要原因在于NOR闪存读取速度快一些。这样的应用在ARM、DSP系统中比比皆是。一个NAND FLASH做代码存储器,外加一些SRAM或者SDRAM作为数据存储器。其实51单片机的应用也与此类似,尽管一般的应用中无需外扩存储器,单片机内部自带了ROM和RAM,但是它的运行机制也和XIP有着异曲同工之妙,代码是从ROM里运行,数据变量大多在RAM上存储。
XIP方式的一个主要局限性上文也提到了,就是NOR闪存的读取速度,它无论如何也比不上RAM。但是在很大应用中,其实CPU对代码的执行速度要求也不是那么苛刻,况且XIP方式相对于Fully Shadowed和Demand Paging方式是最省闪存空间的应用。
再说Fully Shadowed方式,中文也可译为“完全映射”。嵌入式系统程序运行时,将所有的代码从非易失存储器(Flash、ROM等)复制到RAM中运行。这种应用也蛮多的,它的好处在于充分依托于RAM在运行代码时速度上的优势,而它的劣势在于需要的RAM存储空间比FLASH的存储空间(代码大小)还要大。此外,这种启动方式在上电后还必须等待一段时间,直到数据装载完成才能正常运行代码,而代码越大,这个等待时间也会越长。
Demand Paging方式,即“按需分页”。它在代码运行时只复制部分代码到RAM中。这种方法对RAM中的页进行导入/导出管理,如果访问位于虚存中但不在物理RAM中会产生页错误,这时才将代码和数据映射到RAM中。之所以提出按需分页的代码运行方式,这里打一个简单的比方,我们手头的PC机,在装好XP操作系统后至少也应该有3GB的存储空间,再加上随便装一些应用程序,4-5个GB那算小的了。如果在每次开机时PC机要把这些代码都从硬盘预载入内存中,那么我估计咱们的PC机都跑不起来。
所以,按需分页解决了上述问题,它在PC机启动时只装载部分最频繁使用的代码到内存中。而其他应用程序只在用户希望运行时才进行实在装载,这个装载过程就是用户能够感受到的延时。它相比于完全映射方式大大减少了RAM的存储空间。
《EmbeddedCodeStorage_web》文章中介绍的Balanced XIP并不是什么新鲜玩意,它只不过是在前面提到的三种基本代码启动方式的基础上取长补短,对各方面做了一些平衡。
话说回来,具体问题具体分析,并不是任何一个嵌入式应用都可以套用上面的某一个代码运行方法。也许设计者在对自己的处理器所需要达到的速度、功耗等性能要求做一些评估后再做决定似乎更稳妥一些。
文章评论(0条评论)
登录后参与讨论