- 常用嵌入式存储器
嵌入式系统中的存储器主要包括随机存储器 (RAM) 、只读存储器(ROM) 、和非易失存储器(包括flash和NVRAM)。
ROM、FIash和NVRAM是嵌入式系统中的外部存储器,其内容在系统掉电的情况下依然存在,因此适合存放启动代码、配置信息等。
绝大部分指令的执行和所有数据的修改则是在RAM中完成,RAM就是通常所说的内部存储器,简称内存。
在任何一个计算机系统中,内存是必不可少的。
ROM主要用于存放VxWorks的引导映像BootRom,
- 由于ROM中代码的调试不方便,更新引导程序是需要更换ROM芯片,导致成本增高,因此在目前的嵌入式系统中已经很少使用。
Flash也称闪存,同样可以存放VxWorks的引导映像。
- 通过仿真器,可以反复、快速擦写flash中的内容,也可以调试flash中代码的运行。在VxWorks的支撑下,用户还可以使用自己的程序对flash进行读写访问。
- VxWorks中提供了flash文件系统,即TrueFFS的驱动。通过TFFS,用户可以把flash的全部或部分空间创建为-个TFFS设备,通过加载合适的文件系统(如DosFs)实现在该设备上目录和文件的操作。
- 用户可以在flash中以文件的形式保存配置信息和日志信息,存放运行是需要动态加载的应用程序模块,通过文件传输协议方便的在线升级BootImage、VxWorks映像和应用程序模块。
- 由于大部分嵌入式系统没有类似计算机的硬盘,因此,flash的存在就显得尤为重要。
内存RAM包括动态存储器DRAM和静态存储器SRAM,SRAM主要用作高速缓存Cache。通常提到的内存,除非特别指明,都是指DRAM,也称主内存。
- 绝大部分指今的执行和所有数据的修改都是在内存中完成的
- 对嵌入式系统来说,对内存管理提出了更高的要求
- VxWorks内存布局
- VxWorks采用单一实地址模式 (flat模式)。
- VxWorks的内存空间被静态地划分成多个区域用与不同的应用 -- 静态分配。
2.1 Bootrom运行时的内存分布
2.2 VxWorks运行时的内存布局
3. USER RESERVED MEM
- 如果应用程序在运行时出现致命性错误导致系统死机或某些任务被挂起,应用程序可以在出现这些错误之前.把一些合适的调试信息写入到其中。
- 系统热启动之后,根据这块内存中保留的调试信息,可大致判断问题的原因所在。
- 其中可划出一块专用内存分区供某些用户应用程序使用.使得这个模块中所有内存的电请和释放操作仅限于该内存分区中.从而减少内存碎片.降低系统内存管理的负担.使得对内存的操作更加快速、简便和安全
·这种静态划分为系统提供了最好的可靠性与实时性
- 如可以通过修改USER RESERVED MEM 分配内存满足应用程序的特殊请求。
- 用对于那些对实时性和可靠性要求极高的需求只能采用静态分配方式。
采用静态划分也必然会使系统失去灵活性
- 因此必须在设计阶段考虑所有可能的情况并对所有的需求做出相应的空间分配,一旦出现没有考虑到的情况系统就无法处理此外静态分配方式,也必然导致很大的浪费
- 必须按照最坏情况进行最大的配置而在实际运行中可能只用到其中的一小部分。
4.应用
在VxWorks系统中,如何“隐藏”一定大小的内存空间?
在usrConfig.c文件中的usrInit0)中调用了kernelInitO)函数,VxWorks系统内存总和将完全由系统进行控制,而这个总和是由kernelInit函数的第3和第4个参数决定的。第3个参数是VxWorks映像的结束地址,第4个参数是sysMemTop的返回值。
因此,可以如下方式“隐藏”一块内存区域:
- 在BSP的config.h中定义USER RESERVED MEM如:
#define USER RESERVED MEM OX200000
- 在usrCofig.c中,把kernelInit由原来的
kernelInit( (FUNCPTR) usrRoot, ROOT_STACK_SIZE,
(char*)MEM_POOL_START_ADRS,
sysMenTop (),
ISR_STACK_SIZE,INT_LOCK LEVEL):
改为:
kernelInit( (FUNCPTR) usrRoot, ROOT_STACK_SIZE,
(char*)MEM_POOL_START_ADRS
sysMenTop () - USER RESERVED MEM,
ISR_STACK_SIZE,INT_LOCK LEVEL):
5. VxWorks中主要涉及到的内存单元概念
- 内存分区(memory partition)-
- 内存池(memory pool)-
- 内存块(memory block)
内存分区包含分区自身的描述信息(一个结构体)和一个或多个内存池,描述信息保存在系统内存分区中,而内存池就是该分区实际拥有的内存空间。
- 内存池是一块连续的内存区域,包含一个或多个内存块,通过函数memPartAlloc和memPartFree来申请和释放。
- 内存分区在刚创建完毕时,只有一个内存池,用户程序可在稍后往该分区中添加别的内存池。
- 在一个内存分区中,内存池之间的地址不一定是连续的。
每个内存块都有一个内存块头来描述自己,内存块头结构体BLOCK HDR如下定义:
VxWorks在启动过程中会创建一个包含系统内存池(system memory pool) 的系统内存分区(system memory partition) ,操作系统和通常的大部分用户应用程序对内存的操作,都发生在系统内存池内一动态分配的对象
- 该系统内存分区的ID 为memSysPartId ,是一个全局变量,关于它的定义在memLib.h 中。
- 它是在内核初始化kerelInitO) 时,由usrRoot0) (包含在usrConfig.c 中)调用memInit 创建。
- 所有任务所需要的内存可以直接调用malloc 从其中分配,调用free释放内存。
内存管理方式
需要对空闲内存块进行合适的管理,系统在经过多次内存分配和释放操作之后,可能存在多个空闲的内存块,后续的内存操作必须能够检测到这块内存,从而根据一定的算法选择一个合适的内存块。
空闲块通常有可用表和自用链两种方法管理,VxWorks采用自由链管理内存空闲块
用户也可以从USER RESERVED MEM划出-块专用内存分区供某些用户应用程序使用一动态分配的对象,可以自拟内存管理方法,如
- 将该内存区分为若干个内存池。
- 每个内存池中的内存块大小固定。
- 以固定大小分配各申请者。
自由链
自由链是利用每个空闲内存块的开始几个单元存放本空闲块的大小及下个空闲块的开始地址管理程序可以通过链首指针可以检索到所有的空闲块。
采用自由链管理空闲块,空闲内存块的查询工作量较大,但由于自由链指针利用的是空闲块自身的单元,所以不必占用额外的内存块·自由链没有大小的限制,容易添加和删除节点。VxWorks采用自由链管理内存空闲块。