VxWorks内存管理.docx

上传人:b****4 文档编号:12288787 上传时间:2023-04-17 格式:DOCX 页数:13 大小:153.38KB
下载 相关 举报
VxWorks内存管理.docx_第1页
第1页 / 共13页
VxWorks内存管理.docx_第2页
第2页 / 共13页
VxWorks内存管理.docx_第3页
第3页 / 共13页
VxWorks内存管理.docx_第4页
第4页 / 共13页
VxWorks内存管理.docx_第5页
第5页 / 共13页
点击查看更多>>
下载资源
资源描述

VxWorks内存管理.docx

《VxWorks内存管理.docx》由会员分享,可在线阅读,更多相关《VxWorks内存管理.docx(13页珍藏版)》请在冰豆网上搜索。

VxWorks内存管理.docx

VxWorks内存管理

VxWorks内存管理

一、嵌入式系统对内存管理的要求

(1)快速性

嵌入式操作系统的实时性要求内存分配过程要尽可能快。

因此不宜采用通用操作系统中完善但复杂的内存分配策略,一般没有段页式虚存管理机制,而是采用简单、快速的内存分配方案。

根据对实时性要求程度的不同,分配方案也有所不同。

VxWorks系统采用简单的“首次适应,立即聚合”方法。

(2)可靠性

为保证嵌入式操作系统可靠性,内存分配的请求必须得满足,分配失败可能会导致灾难性后果。

嵌入式操作系统应用于各种各样的场合中,在有些情况下,对可靠性要求极高。

在一些可靠性要求很高的嵌入式操作系统中,甚至不支持动态内存分配,只支持静态内存分配,所有的内存在系统启动时已分配好。

(3)高效性

内存分配要尽可能地减少浪费,并且要降低内存管理的开销。

不可能为了保证满足所有的内存分配请求而将内存配置得无限大。

一方面,潜入式系统对成本的要求使得内存在其中只是一种很有限的资源;另一方面,即使不考虑成本的因素,系统有限的空间和有限的板面积决定了可配置的内存容量是有限的。

实时嵌入式系统开发者通常需要根据系统的要求在RTOS提供的内存管理之上实现特定的内存管理。

二、静态分配与动态分配

静态分配是指在编译或链接时将程序所需的内存空间分配好,采用这种分配方案的程序段,其大小一般在编译时就能确定;而动态分配是指系统运行时根据需要动态地分配内存。

一般的嵌入式系统都支持静态分配,因为像中断向量表、操作系统映像这类的程序段,其程序大小在编译和链接时是可以确定的。

而是否支持动态分配主要基于两个方面的考虑:

首先是实时性和可靠性的要求,其次是成本的要求。

对于实时性和可靠性要求极高的系统(硬实时系统),不允许延时或者分配失败,必须采用静态分配方案,也就是在程序编译时所需要的内存都已经分配好了。

例如火星探测器上的嵌入式系统就必须采用静态分配的方案,在这样的应用场合,成本不是优先考虑的对象,实时性和可靠性才是必须保证的。

然而,仅仅采用静态分配,使系统失去了灵活性。

必须在设计阶段就预先知道所需要的内存并对之作出分配;必须在设计阶段就预先考虑到所有可能的情况;内存分配必须按照最坏情况进行最大的配置,而实际运行时可能只使用其中的一小部分,这样的分配方案会导致很大的浪费;而且在硬件平台不变的情况下,不可能灵活地为系统添加功能,从而使得系统的升级变得困难。

虽然动态内存分配会导致响应和执行时间不确定、内存碎片等问题,但是它的实现机制灵活,给程序实现带来极大的方便,有的应用环境中动态内存分配甚至最必不可少的。

比如,嵌入式系统中使用的网络协议栈,在特定的平台下,为了比较灵活地调整系统的功能,在系统中各个功能之间作出权衡,必须支持动态内存分配。

大多数的系统是硬实时系统和软实时系统的综合,也就是说,系统中的一部分任务有严格的时限要求,而另一部分只是要求完成得越快越好。

按照RMS(RateMonotonousScheduling)理论,这样的系统必须采用抢先式任务调度;而在这样的系统中,就可以采用动态内存分配来满足那一部分可靠性和实时性要求不那么高的任务。

采用动态内存分配的好处就是给设计者很大的灵活性,可以方便地将原来运行与非嵌入式操作系统的程序一直到嵌入式系统中。

大多数实时操作系统提供了动态内存分配接口,例如malloc和free函数。

三、VxWorks内存管理机制

在VxWorks中,内存管理功能用于向操作系统提供一致的地址映射功能和内存的分配、释放操作,在任务需要时为其分配内存空间,而在使用完毕之后释放空间。

在嵌入式系统的开发过程中,设计者需要对系统的内存分配非常熟悉:

在生成操作系统映像时,必须正确设置目标系统的内存容量;在开发应用程序时,必须考虑内存如何分配并时刻注意可用内存数,此外还要保证程序和内核之间不互相侵犯。

VxWorks5.x中,在目标板上有两个内存池(MemmoryPool)用于动态内存分配:

系统内存池(SystemMemoryPool)和WDB内存池。

对于VxWorks上程序的设计者来说,需要关注的是系统内存池的动态内存管理机制。

嵌入式系统的动态内存管理实际上就是需要尽量避免动态分配和释放内存,以最大程度地保证系统的稳定性。

1、VxWorks的内存布局

 如上图所示,VxWorks5.x的内存按照装载的内容不同从内存得低地址开始依次分为低端内存区、VxWorks内存区、WDB内存池、系统内存池和用户保留区五部分。

各部分在内存中的位置由一些宏参数来决定,内存区域的划分及相关参数的定义与CPU的体系结构相关,这里只介绍VxWorks5.x典型内存布局。

整个目标板内存的起始地址是LOCAL_MEM_LOCAL_ADRS,大小是LOCAL_MEM_SIZE,sysPhysMemTop()一般返回内存的物理最高地址。

各部分的内容及参数如下:

(1)低端内存区

在低端内存区中通常包含了中断向量表、bootline(系统引导配置)和exceptionmessage(异常信息)等信息。

LOCAL_MEM_LOCAL_ADRS是低端内存区的起始地址,典型设置是0。

RAM_LOW_ADRS是低端内存区最高地址。

(2)VxWorks区

VxWorks区存放VxWorksimage(操作系统映像),其中依次是VxWorksimage的Text段、Data段和BSS段。

由RAM_LOW_ADRS和FREE_MEM_ADRS决定该区的大小和位置。

(3)系统内存池

系统内存池用于动态内存的分配(如malloc())、任务的堆栈和控制块及VxWorks运行时需要的内存。

这部分内存有VxWorks管理,开销位于目标板上。

系统内存池在系统启动时初始化,它的大小是整个内存减去其他区的大小。

在启动后可以通过函数memAddToPool()向系统内存池中增加内存。

SysMemTop()返回系统内存池(SystemMemoryPool)的最高地址。

(4)WDB内存池

又叫TargetServer内存池,是在目标板上为Tornado工具(如WindDebugger)保留的一个内存池,主要用于动态下载目标模块、传送参数等。

这个内存池由TargetServer管理,管理的开销位于宿主机。

TargetServer内存池必要时(如TargetServer内存池中内存不够)可以从系统内存池中分配内存。

其起始地址是WDB_POOL_BASE,通常等于FREE_RAM_ADRS,初始大小由WDB_POOL_SIZE定义,默认值是系统内存池的1/16,在installDir/target/config/all/configAll.h中定义:

#defineWDB_POOL_SIZE((sysMemTop()-FREE_RAM_ADRS)/16)

系统中不一定包含TargetServer内存池.只有当系统配置中包含组件INCLUDE_WDB时才需要TargetServer内存池。

(5)用户保留区

用户保留区是用户为特定应用程序保留的内存。

该区的大小由USER_RESERVED_MEM决定,默认值为0。

以上所涉及的大部分宏定义和函数在目标板的BSP或configAll.h中定义。

2、管理内存分区的数据结构:

mem_part

系统初始化时创建系统内存分区,管理整个系统内存池中的内存。

用户也可以使用memPartLib库的函数实现自己的分区。

用于分区中内存管理的数据结构是在memPartLib.h中定义的mem_part,包含对象标记、保护该分区的信号量、一些分配统计信心(如当前分配的块数)及分区总所有的空闲内存快形成的一个双向链表freeList。

具体定义如下:

typedefstructmem_part

{

OBJ_COREobjCore;/*对象标志*/

DL_LISTfreeList;/*空闲链表*/

SEMAPHOREsem;/*保护分区的信号量*/

unsignedtotalWords;/*分区中字(Word)数*/

unsignedminBlockWords;/*以字为单位的最小块尺寸*/

unsignedoptions;/*选项,用于调试或统计*/

/*分配统计信息*/

unsignedcurBlocksAllocated;/*当前分配的块数*/

unsignedcurWordsAllocated;/*当前分配的块数*/

unsignedcumBlocksAllocated;/*累积分配的块数*/

unsignedcumWordsAllocated;/*累积分配的字数*/

}PARTITION;

3、动态内存分配

VxWorks中的动态内存分配采用最先匹配(First-Fit)算法(如下图所示),即从空闲链表中查找内存块,然后从高地址开始查找,当找到第一个满足分配请求的空闲内存块时,就分配所需内存并修改该空闲块的大小。

空闲块的剩余部分仍然保留在空闲链表中。

当从大的内存块中分配出新的内存块时,需要将新内存块头部的一块空间(称为“块头”)用来保存分配、回收和合并等操作的信息,因此,实际占用的内存大小是分配请求的内存大小与块头开销之和。

分配函数malloc()返回的地址是分配请求所获可用内存的起始地址,为优化性能,malloc()会自动对齐边界,分配的内存的起始地址和大小都是边界之的整数倍,因此有可能造成内部碎片。

块头的开销与处理器的体系结构有关,对于X86体系结构来说,,块头的开销是8字节,通常这部分会被自动以4字节边界对齐,以减少出现碎片的可能并优化性能。

FirstFit

∙firstfit

Aplacementstrategywhichselectsthefirstspaceonthefreelistwhichislargeenough.

最先匹配是一种从空闲链表中选择第一个足够大的空间的分配策略。

∙FirstFit-allocatefromthefirstfreeareaonthelistwhichisbigenough.

最先匹配-分配链表上第一个足够大的空闲区域。

∙Asnewareasarefreed,thenewareaisputatthebeginningofthelist.

当新区域释放时,把新区域放在链表的开始。

∙Asnewrequestsarereceived,thelistisscanneduntilalargeenoughfreeareaisfound.

当接收到新的请求时,查找链表直到找到足够大的空闲区域。

4、动态内存释放

内存释放时,根据块头中的信息判断相邻的内存块是否空闲,如果相邻内存块空闲,将进行内存块合并,并修改空闲块长度;否则就把新释放的内存插入到空闲链表中。

这里,空闲链表采用的是双链表的数据结构,它将紧临块头的8个字节(2个指针长度)用来存放双链表的指针,指向其他的空闲块(如下图所示)。

VxWorks5.x不会主动地回收内存,所有由malloc()分配的内存必须显式调用free()进行释放,以避免内存溢出。

5、常用库函数及其应用的介绍

VxWorks5.x提供的内存管理函数库有三个:

核心内存管理库memPartLib、扩展内存管理库memLib和共享内存管理库smMemLib,前两个库中的函数较为常用。

5.1、动态内存的申请和释放

如下表所示,VxWorks提供了多种分配和释放内存的函数,以满足不同的要求。

其中基本的分配与释放函数是memPartAlloc()和memPartFree(),其他函数是在这两个函数的基础上实现的。

malloc()和free()是最常用的函数,用来动态分配和释放系统内存分区中的内存。

malloc()只分配内存,对其中的内容不做初始化,free()也不改变所释放内存块中的内容。

任务编程分配的内存即使在任务退出时也不会自动释放,因此需要显式调用释放内存的函数(如free())。

在此释放已释放了的内存会导致系统报错。

使用虚拟内存技术时,因为内存是分页的,分配内存应使用valloc(),以确保获得的内存是从页边界开始。

在没有添加MMU支持库时,valloc()分配会失败,返回NULL。

分配内存的函数在分配成功是会返回内存块的起始地址,调用失败或没有足够内存是会返回NULL。

 

动态内存分配和释放函数

函数名

所属库

功能描述

malloc()

memPartLib

从系统内存分区中分配指定大小的内存,与ANSIC兼容

Free()

memPartLib

释放由malloc()或calloc()分配的内存块

calloc()

memLib

为一组元素分配内存,与ANSIC兼容

cfree()

memLib

释放由calloc()分配的内存块

valloc()

memLib

从系统内存分区中分配指定大小的内存,并确保所分配的内存是从页边界开始的

realloc()

memLib

为指定的块重新分配内存,新分配的内存可能不在原位置上,但可以保留原内存块中的内容.与ANSIC兼容

memalign()

memLib

从系统内存分区中分配内存,并确保内存块的起始地址是指定aligment参数的整数倍

memPartAlignedAlloc()

memPartLib

从指定内存分区中分配内存,并确保内存块的起始地址是指定aligment参数的整数倍

memPartRealloc()

memLib

从指定的分区中重新分配内存,并保留原来内存块的内容

memPartAlloc()

memPartLib

从指定内存分区中分配内存

memPartFree()

memPartLib

释放指定分区中的内存

5.2、内存分区

VxWorks5.x允许用户建立并管理自己的内存分区(MemoryPartition),并提供相应的函数,如下表所示:

内存分区操作函数

函数名

所属库

功能描述

memPartCreate()

memPartLib

创建内存分区

memPartAddToPool()

memPartLib

向指定内存分区中增加内存

memPartAlignedAlloc()

memPartLib

从指定分区中分配内存,并确保该内存块的起始地址在特定的边界上

每个分区又各自的分区ID。

ID实际是指向分区内存管理数据结构mem_part的指针,定义在memLib.h中。

typedefstructmem_part*PART_ID;

三、VxWorks的虚拟内存接口

1、MMU

在支持虚地址存储体系的系统结构中,CPU使用虚拟地址,主存访问使用物理地址,如下图所示。

主存需要以一定规则划分为多个存储页,并用页表描述存储页的虚拟地址、对应的物理地址及相关属性。

此类体系结构中必然包含内存管理单元MMU(MemoryManagementUnit)。

MMU的实现因体系结构而异,其主要功能是:

以存储页(MemoryPage)为基本单元,将虚拟地址翻译为物理地址、提供内存访问权限和控制存储页Cache支持。

页表实现虚拟地址与物理地址一一对应。

当两个也的虚拟地址连续而其对应的物理地址不连续时(在物理上两个页不连续),由于CPU执行虚拟地址,因此从CPU看起来是连续的。

这样就可以将本来连续的代码或数据放入不连续的物理页中,而且允许在需要时才将代码或数据调入主存的某一页中。

这就是虚拟地址存储体系带来的最大好处。

2、VxWorks对虚拟内存的支持

VxWorks5.x提供两级虚拟内存支持(VirtualMemorySupport):

基本级(BasicLevel)和完整级(FullLevel)。

后者需要购买可选组件VxVMI。

在VxWorks5.x中有关虚拟内存的配置包括两个部分。

第一部分是对VxWorks虚拟内支持级别和保护的配置,下表列出了这些选项。

VxWorks虚拟内存配置常量

组件

描述

INCLUDE_MMU_BASIC

基本及虚拟内存支持,不需要组件VxVMI

INCLUDE_MMU_FULL

完整级虚拟内存支持,需要组件VxVMI

INCLUDE_PROTECT_TEXT

写保护text段,需要组件VxVMI

INCLUDE_PROTECT_VEC_TABLE

写保护异常向量表,需要组件VxVMI

以上配置一般在BSP的config.h中完成。

第二部分是内存页表的划分和属性配置。

配置包括BSP的config.h中的VM_PAGE_SIZE和sysLib.c中的sysPhysMemDesc。

VM_PAGE_SIZE定义了CPU默认的页的大小。

需参照CPU手册的MMU部分定义该值。

sysPhysMemDesc用于初始化MMU的TLB表,它是以PHYS_MEM_DESC为元素的常量数组。

PHYS_MEM_DESC在vmLib.h中定义,用于部分内存的虚拟地址到物理地址的映射:

typedefstructphes_mem_desc

{

voidvirtualAddr;/*虚拟内存的物理地址*/

void*physicalAddr;/*虚拟地址*/

UNITlen;/*这部分的大小*/

UNITinitialStateMask;

UNITinitialState;/*设置这部分内存的初始状态*/

}PHYS_MEM_DESC;

sysPhysMemDesc中的值需要根据系统的实际配置进行修改。

sysPhysMemDesc中定义的内存地址必须页对齐,且必须跨越完整的页。

也就是说PHYS_MEM_DESC结构中的前三个域的值必须能被VM_PAGE_SIZE整除,否则会导致VxWorks初始化失败。

3、VxWorks基本级虚拟内存

基本级虚拟内存库vmBaseLib提供了系统中所需最低限度的MMU支持,其主要目的是为创建Cache-safe缓冲区提供支持。

四、总结

通过查看资料,结合自己在项目中所接触到的X86架构体系下VxWorks的内存管理部分的BSP代码,得到一些自己对VxWorks下的内存管理的理解:

VxWorks系统支持静态分配和动态分配相合的内存分配,像低端内存区和VxWorks区采用静态分配,其大小在config.h文件中已定义,在编译和链接时(makefile文件和Mkbootrom.mak文件)可以确定操作系统映像这类的程序段的大小,从而保证VxWorks的实时性和稳定性。

VxWorks下的内存管理主要是对动态内存的管理,就是要尽量避免动态分配和释放内存,以最大限度地保证系统的稳定性。

在X86平台下开发PCI设备驱动程序,如果采用Memory方式访问设备(如XR17D158、RTL8139),经常在初始化PCI设备的时候要用到VxWorks支持的基本级虚拟内存(INCLUDE_MMU_BASIC)。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 工程科技 > 能源化工

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1