您好, 欢迎来到1024商务网   [请登录]  [免费注册]  忘记密码
首页 新闻资讯 产品大全 企业 求购 品牌
企业 动态 用户在搜:盖板模具 礼堂椅 常熟车床 二手压路机 电动执行器 武汉复合板 光固化树脂 过热蒸汽发生器 义乌饰品 吊篮,懒人椅 洛阳压路机 配电网一体化测控终端 有线电视可变均衡器 
当前位置:首页 > 新闻资讯 > 垂直行业 > [行业技术文章]一种嵌入式系统的内存分配方案
[行业技术文章]一种嵌入式系统的内存分配方案
更新时间:2013-07-06 发布:www.1024sj.com

 1 嵌进式系统中对内存分配的要求

    ①快速性。

    嵌进式系统中对实时性的保证,要求内存分配进程要尽地快。是以在嵌进式系统中,不成能采用通用操作系统中复杂而完善的内存分配策略,一般都采用简单、快速的内存分配方案。固然,对实性要求的法式分歧,分配方案也有所分歧。例如,VxWorks采用简单的早匹配如立即聚合方式;VRTX中采用多个固定尺寸的binning方案。

    ②靠得住性。

    也就是内存分配的请求必需获得知足,若是分配失败可能会带来灾难性的后果。嵌进式系统运用的情况千变万化,其中有一些是对靠得住性要求极高的。好比,汽车的自动驾驶系统中,系统检测到行将撞车,若是由于内存分配失败而不能响应的操作,就会发生车毁人亡的事故,这是不能容忍的。

    ③高效性。

    内存分配要尽地少浪费。不成能为了保证知足所有的内存分配请求而将内存设置装备摆设得无限年夜。一方面,嵌进式系统对成本的要求使得内存在其中只是一种很有限的资本;另外一方面,即使不斟酌成本的身分,系统有限的空间和有限的板面积决议了可设置装备摆设的内存容是很限的。

    2 静态分配与动态分配

    事实运用使用静态分配仍是动态分配,一直是嵌进式系统设计中一个争辩不休的。固然,合适的谜底是对于分歧的系统采用分歧的方案。若是是系统对于实时性和靠得住性的要求极高(硬实时系统),不能容忍一点延时或一次分配失败,固然需要采用静态分配方案,也就是在法式编译时所需要的内存都已分配好了。

    例如,火星探测器上面的嵌进式系统就必需采用静态分配的方案。另外,WindRiver公司的一款门用于汽车电子和工自动化领域的实时操作系统OSEKWorks中就不支持内存的动态分配。在这样的运用场所,成本不支持内存的动态分配。在这样的运用场所,成本不是先斟酌的对象,实时性和靠得住性才是必需保证的。

    固然,采用静态分配一个不成避免的总是就是系统失往了灵活性,必需在设计阶段就预先知道所需要的内存并对之作出分配;必需在设计阶段就预先斟酌到所有可能的情况,由于一旦泛起没有斟酌到的情况,系统就没法处置。这样的分配方案必需致使很年夜的浪费,由于内存分配必需依照坏情况进行年夜的设置装备摆设,而现实上在运行中可能使用的只是其中的一小部门;而且在硬件平台不变的情况下,不成能灵活地为系统添加功能,从而使得系统的升级变得坚苦。

    年夜大都的系统是硬实时系统和软实时系统的综合。也就是说,系统中的一部门使命有严酷的时限要求,而另外一部门只是要求完成得越快越好。依照RMS(RateMonotoinScheduling)理论,这样的系统必需采用争先式使命调剂;而在这样的系统中,就能够采用动态内存分配来知足那一部门靠得住性和实时性要求不那末高的使命。

    采用动态内存分配的益处就是给设计者很年夜的灵活性,可以利便地将原来运行于非嵌进式操作系统的法式移植到嵌进式系统中,好比,许多嵌进式系统中使用的网络协议栈。若是必需采用静态内存分配,移植这样的协议栈就会坚苦得多。

    另外,采用动态内存分配可以使设计者在不改变基本的硬件平台的情况下,比力灵活地调整系统的功能,在系统中各个功能之间作出权衡。例如,可以在支持的VLAN数和支持的路由条目数之间作出调整,或分歧的版本支持分歧的协议。说到底,动态内存分配给了嵌进式系统的法式设计者在比力少的限制和较年夜的自由。是以,年夜大都实时操作系统提供了动态内存分配接口,例如malloc和free函数。

    3 RTOS提供的内存分配接口

    分歧的RTOS由于其分歧的定位,采用分歧的内存分配策略。例如VRTX中,采用类似于GNUC中由DougLea开发的内存分配方案,即Binning算法,系统内存被分成了一些固定尺寸的内存块的算法,系统内存被分成了一些固定尺寸的内存块的纠合。这类方式的点是查找速度快而且不会发生内存碎片。可是,它的错误谬误也很较着,就是容易造成浪费,由于内存块的尺寸只有有限个,分配时只能取较年夜的内存块来知足一个较小的需求,累积起来,浪费就很年夜了;而且操作系统经管这样一个内存分配表也是一个很年夜的负担。

    

    下面具体介绍一下我们经常使用的RTOS——美国风河公司(WindRiver)的VxWorks中采用的内存分配策略。VxWorks的前身就是VRTX,听说VxWorks的名称来自makevrtxwork。VxWorks的内存经管函数存在于2个库中;memPartLib(紧凑的内存分区经管器)和memLib(完整的内存分区经管器)。前者(memPartLib)提供的工具用于从内存分区中分配内存块。该库包括两类法式,一类是通用工具建立和经管内存分区并从这些分区中分配和经管内存块;另外一类是尺度的malloc/free法式提供与内存分区的接口。

    系统内存分区(其ID为memSysPartId是一个全局变)在内核初始化时由usrRoot挪用memInit建立。其起头地址为RAM中紧接着VxWorks的BSS段以后,年夜小为所有余暇内存,如图1所示。    

    当建立其它分区时,一般需要先挪用malloc从系统内存分区中分配一段内存才能建立。

    内存分区的结构界说为mem_part,包括1个对象标识表记标帜,1个双向链表经管余暇块,1个旌旗灯号庇护该分区及一些统计信息,如总尺寸、年夜块尺寸、调试选项、已分配的块数、已分配的尺寸等。其语句以下:

    typedefstructmem_part

    {OBJ_COREobjCore;/*对象标志*/

    DL-LISTfreeList;/*余暇链表*/

    SEMAPHOREsem;/*庇护分区的旌旗灯号*/

    

    UnsignedtotalWords;/*分区中字(WORD)数*/

    UnsignedminBlockWords;/*以字为单元的小块尺寸*/

    Unsignedoptions;/*选项,用于调试或统计*//*分配统计*/

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

    unsignedcurWorkdAllocated;/*当前分配的字数*/

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

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

    }PARTITION;

    一般系统中只有1个内存分区,即系统分区,所有使命所需要的内存直接挪用malloc从其中分配。分配采用First-Fit算法(注重这类算法容易致使年夜碎片),经由过程free释放的内存将被聚合以形成更年夜的余暇块。

    这就是VxWorks的内存分配机理。分配时可以要求一定的对齐花式。注重,分歧的CPU架构有分歧的对齐要求。为了化性能,malloc返回的指针是经过对齐的,为此的开销随构分歧而分歧。

    例如,68K为4字节对齐,开销8字节;SPARC为8字节对齐,开销12字节;MIPS为16字节对齐,开销12字节;I960为16字节对齐,开销16字节。MemLib库中提供了增强的内存分区经管工具,而且增加了一些接口,而且可以设置调试选项。

    可以检测2类毛病:①测验考试分配太年夜的内存;②释放内存时发现坏块。有4种毛病处置选项,当发生毛病时记实消息或挂起使命。

    可是,使用动态内存分配malloc/free时要注重到以下几方面的限制。①由于系统内存分区是一种临界资本,由旌旗灯号庇护,使用malloc会致使当前挪用挂起,是以它不能用于中断服务法式;②由于进行内存分配需要执行查找算法,其执行时间与系统当前的内存使用情况相关,是不肯定的,是以对于有划定时限的操作它是不适合的;③由于采用简单的早匹配算法,容易致使系统中存在年夜的内存碎片,下降内存使用效率和系统性能。

    针对这类情况,一般在系统设计时采用静态分配与动态分配相连系的方式。也就是对于重要的运用,在系统初始化时分配好所需要的内存。在系统运行进程中不再进行内存的分配/释放,这样就避免了因内存的分配释放带来的总是。而且在系统初始化,由于没有内存碎片,对于年夜的内存块的需求容易知足。对于其它的运用,在运行时进行动态内存分配。尤其是某些运用所要求的年夜固定尺寸的小内存块,这时候就能够采用一次分配屡次使用的内存分配方案。下面具体介绍这类内存分配方案及其运用场所。

    4 一次分配屡次使用的内存分配方案

    在嵌进式系统设计中,经常有一些类似于内存数据库的运用。这些运用的特点是在内存中经管一些树,好比以太网交换机中的MAC地址表、VLAN表等,或路由器中的路由表。这些树是由许多不异尺寸的节点组成的。这样,就能够每次分配一个年夜的缓冲池,好比包括多个内存单元的数组,每一个内存单元用于1个节点。我们用一个余暇链表来经管该数组中的余暇内存单元。每次法式需要分配内存以建立1个新的节点时,就从余暇链表中取1个单元给挪用者。法式删除节点并释放内存时,将释放的内存单元返还给余暇链表。若是链表中的余暇内存单元取空了,就再次挪用malloc从系统内存中分配一个年夜的内存块作为新的缓冲池。

    采用这样一种方案主要有以下点:①削减了malloc/free的挪用次数,从而下降了风险,削减了碎片;②由于从缓冲池中取一个内存单元是时间肯定的(固然,若是缓冲池耗尽从而需要重新挪用malloc分配除外),是以它可以用于严酷时限的场所从而保证实时性;③它给用户以自由来添加一些用于内存分配和释放的调试函数和一些统计功能,更好地监测系统中内存的使用情况。这类方案必然触及到一个缓冲池的结构。一般缓冲池的结构由以下几部门组成:单元尺寸、块尺寸(或单元数目)、缓冲池指针、余暇链表、用于统计和调试的参数等。对缓冲池的操作包括建立缓冲池、释放缓冲池、从缓冲池中分配1个内存单元、释放内存单元回缓冲池等。下面举2个例子说明一下该方案的具体使用情况。

    4.1 Intel交换机驱动法式中内存分配

    在以Intel的交换芯片为根蒂根基的交换机方案中,由于采用的是软件地址学习的方式,需要在内存中维护许大都据,如MAC地址表的软拷贝、VLAN表、静态单播地址表、组播地址表等。这些表都是由一些树组成,每一个树由一些固

    定尺寸的节点组成。一般每一个节点几十个字节,每棵树的节点数是可增加的,少则几十,多可到16K个节点。是以,很适合于采用该方案,具体的实现以下:

    (1)缓冲池结构

    BlockMemMgrtypedefstruct{MemSizedata_cell_size;/*数据单元的尺寸*/MemSizeblock_size;/*块尺寸*/

    /*下面的变为预界说的每一个经管器多包括的块数,如64MAX_BLOCKS_OF_MEM_SIZE*/Unsignedshortblocks_being_used;/*已使用的块数*/

    Voidmem_ptr[PAX_BLOCKS_OF_MEM_SIZE];/*块数组*/

    SLListfree_data_cells_list;/*余暇链表*/

    }BlockMemMgr;

    结构中的参数包括:单元尺寸、块尺寸、已用块数、所有块的地址、余暇链表(单向链表)。

    (2)缓冲池的经管函数

    ◆block_mem_create:建立块内存经管器,参数包括内存指针(如为NULL,暗示自己分配)、块尺寸、单元尺寸、返回经管器指针。进程以下:

    ①检验参数正当性。

    ②单元尺寸4字节对齐,计较每一个块中的单元数。对内存指针进行4字节对齐或分配内存指针。

    ③初始化结构BlockMemMgr,包括单元尺寸和块尺寸。设置第1个内存块的指针。若是内存是外来的,设置块已用标志(已用为0),暗示不能增加块;否则,已用块数设为1。

    ④建立余暇链表,将块内所有单元添加到链表中,后一个单元处于链表的前面。⑤返回BlockMemMgr。

    ◆block_mem_destroy:解构一个块内存经管器,释放它所分配的所有内存,挪用者负责外部内存的释放。参数为BlockMemMgr。返回成功失败标志。

    ①参数正当性检测。

    ②删除单向链表(设链表指针为NULL)。

    ③若是块是动态分配的,释放它们。

    ④释放结构BlockMemMgr。

    ◆block_malloc:从块内存经管器中分配1个单元⑤释放结构BlockMemMgr

    ◆block_malloc:从块内存经管器中分配1个单元。参数为BlockMemMgr,返回数据单元指针。

    ①参数正当性检测。

    ②判断余暇链表是否为空(是否为NULL)。若是为空,判断是否可以动态分配块,若是不能,返回失败;若是可以动态分配块,则分配1个块,执行与block_mem_create一样的操作。

    ③从余暇链表中分配第1个单元,返回其指针。注重这里有一个小技巧,即数据单元在余暇时其中寄存余暇链表的节点信息,而分配后则寄存数据内容。

    ◆block_free:释放1个数据单元,返回块内存经管器。当心不要对1个单元释放2次。参数为BlockMemMgr和单元指针。

    ①参数正当性检测。

    ②地址比力,判断数据单元属于哪一个块。

    ③判断数据单元的内容是否为余暇链表节点信息(也就是块内某单元的地址),从而肯定是否为2次释放。

    ④将该数据单元插进到余暇链表的前面。

    ⑤援用该单元的指针设为NULL。

    内存经管代码遵照以下约定:

    ①经管的内存是现实可写的内存;

    ②分配内存是4字节或32位对齐;

    ③block_malloc、bloc

    k_free在中断级挪用是部门平安的,除非BLOCK中已没有余暇CELL,需要重新挪用malloc分配新的BLOCK(而malloc和free就不是平安的,由于其中使用了旌旗灯号和搜索算法,容易引发中断服务法式阻塞)。固然,block_mem_create和block_mem_destroy必需在进程级挪用。

    4.2 TMS中的内存分配

    TMS是WindRiver公司为可经管式交换机推出的开发包。它用用IDB来经管各类协议的数据,好比STP和GVRP等。为了支持IDB,它建立了自己的缓冲池经管方案,法式在bufPoolLib.c中。该法式包括用于缓冲池经管的函数,这些函数允许从1个池中分配固定数目和年夜小的缓冲区。经由过程预先分配一定数目固定年夜小的缓冲区,避免了频频的小的内存块分配/释放相联系关系的内存碎片和浪费。既然它从1个单一的块中分配缓冲池,也比对每个缓冲区执行1次分配有更高的空间效率。模块对每一个缓冲区加上1个标识表记标帜(MAGIC),释放时会检查标识表记标帜。模块给用户提供分配和释放操作界说回调函数的能

    力。这样可以做到自动的对象建立息争构,同时允许由多个缓冲池分配的成员组成的对象做为1个单一的实体删除。这类似于C++中自动的对象构建息争构,不外是用C语言而且没有仓库分配的负担。模块既允许从仓库中分配缓冲池(经由过程calloc),也能够在用户分配的空间中建立它们。模块用1个单向链表来维护未分配的缓冲区,但不跟踪已分配的缓冲区。模块其实不是使命平安的,用户需要用旌旗灯号时来庇护缓冲池。

    (1)缓冲池结构

    typedefstruct{ulong_tmagic;/*用于一致性检测的特殊标识表记标帜*/

    BooleanlocalAlloc;/*内存是否在建立缓冲区时分配*/

    SL_LISTfreeList;/*余暇链表*/

    Voidstore;/*缓冲区指向的内存指针*/

    STATUS(*createFn)(void*,ulong_targl);/*建立缓冲区时的回调函数指针*/STATUS(*destroyFn)(void*,ulong_targl);/*释放缓冲区时的回调函数指针*/Ulong_targVal;/*回调函数的参数*/

    }buf_pool_t;

    结构中的参数包括检查标识表记标帜MAGIC、是否当地分配、余暇链表、内存指针、建立缓冲池的回调函数指针、释放时的回调函数指针、回调函数参数。

    (2)相关函数

    ◆BufPoolInitializeStorage:分配和初始化存储区。参数包括存储区地址(如为NULL,则当地分配)、缓冲区年夜小、缓冲区个数。

    ①凭据缓冲区年夜小和个数获得所需的内存年夜小。

    ②若是指针为NULL,则挪用calloc分配内存。设置当地分配标志。

    ③初始化内存为0。

    ④初始化指针。分配的内存块前面为缓冲池结构buf_pool_t。现实的存储区紧随其后。Buf_pool_t包括参数检查标识表记标帜、是否当地分配、存储区地址、分配时回调函数、释放时回调函数、回调函数变。此时只设置存储区指针。

    ◆BufPoolCreate:建立缓冲池。参数为内存制止。缓冲区尺寸和个数,建立时回调函数、释放时回调函数、回调函数参数。①尺寸对齐。②挪用bufPoolInitializeStorage初始化内存区和buf_pool_t结构。③用传进参数填充buf_pool_t结构。④将缓冲区添加到余暇链表中,后的缓冲区在前面。

    ◆BufPoolDestroy:删除缓冲池。参数为buf_pool_t指针。①检查缓冲池结构中的MAGIC字段是否被个性。②若是是当地分配的则翻放内存区。

    ◆BufPoolAlloc:从缓冲池中分配一个缓冲区,参数为缓冲池结构指针。若是存在余暇缓冲区,则从余暇链表中除并提供给挪用者,执行建立时回调函数。若是回调函数返回毛病,则将缓冲区返还给余暇链表。①检查缓冲池结构中的MAGIC标识表记标帜是否无缺。②从余暇链表中掏出头一个节点。③若是节点不为空,清空节点,以其地址为参数挪用回调函数。④若是回调函数返回毛病,则将节点还给余暇链表。⑤返回获得余暇缓冲区地址。

    ◆BufPoolFree:将缓冲区返回给缓冲池。若是界说了回调函数,将在回还缓冲之间挪用回调函数。参数为缓冲池结构缓和冲区指针。①缓冲池MAGIC标识表记标帜是否无缺。②若是界说回调函数、挪用之。若是返回毛病,则设置毛病号。③将缓冲区添加到余暇链表中头部。注重该函数有2点:①回调函数返回毛病,照样回还缓冲区。②没有检查缓冲区是否二次释放,这一点与Intel的驱动法式分歧。另外,TMS的缓冲池没有BLOCK要领,不需要判断哪一个CELL属于哪一个BLOCK,简化了操作。

    5 小结

    许多嵌进式运用在RTOS提供的malloc/free的根蒂根基上编写自己的内存经管方案。编写这样的内存经管方案,目的无非有两个:一是削减对malloc/free的依赖,从而避免由之带来的内存碎片、时间不肯定等总是;另外一个是增强法式的查错能力,送还内存使用毛病。对于在嵌进式系统中普遍存在的数据库类型的内存需求,即分配多个固定尺寸的内存单元的要求,“一闪分配,屡次使用”的方案无疑是一种很好的解决之道。文中介绍的2个例子很好地体现了它的越性。

返回列表 | 打印本页
上一篇:[行业技术文章]ADSS光缆在电力通信网中的应用    下一篇:[行业技术文章]智能建筑电气设备安装技术
猜你喜欢
·[行业技术文章]煤粉高效洁净燃烧及分配技术 ·[行业技术文章]锅炉FSSS系统静态调试方案
·[行业技术文章]基于嵌入式MODEM的漏电监测系统 ·[行业技术文章]6~10kV系统接地补偿的必要性及补偿方案
·[行业技术文章]一种想不到的窃电方法 ·[行业技术文章]一种实用的光纤差动通讯方法
·[行业技术文章]一种易被忽视的窃电方法 ·[行业技术文章]葫芦岛市馈线自动化系统方案
·[行业技术文章]基于嵌入式PLC芯片组的多路模拟量PLC的
 
同类推荐
·电能质量信息化管理体系
·虚拟仪器快速应用PCIExpress总线技术
·变压器有载分接开关带电滤油装置的应
·五金行业的位发展需要靠什么
·[行业技术文章]全国条碳纤维复合芯铝
·[行业技术文章]配电自动化实用化关键
·[行业技术文章]国产电能表常见故障分
·[行业技术文章]百万千瓦级汽轮机选型
·[行业技术文章]球磨机料位监控与制粉
·美国汽油供应紧缺继续推涨欧美原油期
关于我们 - 广告服务 - 使用手册 - 联系我们 - 法律声明 - 友情链接 - 删除或修改信息 - 网站地图
本站信息由会员自主添加,如涉及隐私等,网站不承担任何责任!如发现侵权违规等问题请发邮件至XXX#qq.com(#用@代替)或在线留言联系删除。
版权所有 1024商务网 浙ICP备12020213号-1 客服QQ: 微信号: