ABB DI818(3BSE069052R1)
1. 实时系统内存分配
实时系统分为硬实时系统和软实时系统。硬实时系统是指系统中各任务不仅要执行无误而且要做到准时;软实时系统是指系统中各任务运行的越快越好,并不要求限定某一任务必须在多长时间内完成。
可以看出动态内存分配是***不能用于硬实时系统的,因为动态分配具有时间不确定性(分配时间与内存块数量有关),而且动态分配可能产生分配不成功的情况。所以对于硬实时系统,只能采用静态内存分配方式。静态分配是指在编译或链接时将程序所需的内存空间分配好,这样不会出现分配失败的情况。
其实对于大多数实时系统而言,内存分配都是采用两种方式的结合,即动静结合的分配方式。
2. 动静结合内存分配的一种实现
对于整个内存,把它分为4个部分,即中断向量区、系统映射区、系统内存区和用户内存区。如图1所示。
其中中断向量表和系统映射区在编译时已经设定好,即采用静态分区的方式。剩下的两个部分可以按用户要求配置。
2.1 系统内存区分区
对于整个系统内存区,还需要要进行分区操作,使它产生多个分区,每个分区中内存块的大小相等,各个分区之间内存块大小不等。这样来满足多种内存申请需求。
2.1.1 系统分区类结构定义
系统建立了一个内存块结构,它由一个指向下一个内存块的指针构成,因为系统使用单向链表来管理空闲内存块,所以必须用每个内存块的这个指针来让所有的空闲内存块连成一个链表。

图1 内存划分示意图
结构如下:
struct memblock
{
void * next;
};
对于内存分区,采用面向对象的方式,这样减少了全局变量的使用,同时提高了可操作性。系统建立了内存分区类结构。它包含了该分区的信号量、内存区的起始地址、内存块大小、内存块数量、空闲内存块数量、空闲内存块链表和链表尾部等。类结构定义如下:
class mempartition
{
private:
semphore s; //控制该内存分区的信号量
public:
long *start; //块起始位置
void *freeulist; //空闲内存块链表
void *tail; //空闲内存块链表尾部
int unitsize; //内存块大小
short unitnum; //内存块数量
short freeunum; //空闲内存块数量
mempartition(); //初始化链表、信号量
void *GetUnit(); //获取内存块
void PutUnit(void *); //释放内存块
};
因为每个内存分区都是多任务共享的,每次只能有一个任务或中断服务程序进入该内存分区,所以需要设置信号量来管理它,当然也可以采用关中断的方式,关中断可能导致中断响应延迟等问题,所以没有采用这种方式。
通过Partition_Create()函数创建一个内存分区,函数定义为
int Partition_Create(mempartition *mp,unsigned int unum,unsigned int usize);
mp为创建的内存分区,unum为该分区中内存块数量,usize为内存块大小。函数流程图如图2所示。
对于块内存的申请,采用c语言提供的malloc函数从内存中申请。这对于程序设计者而言提供了极大的方便,对于系统分区不适合嵌入式应用(该实时系统设计应用于嵌入式设备中)需求的情况下,可以删除该分区另外再建立。不过这样做的情况应该尽可能少,因为多次调用malloc/free会产生较多的内存碎片。在做设计时,应该尽可能预先设定好分区数量和各个分区中内存块的数量和大小,尽管系统提供了重建分区的功能。
每个块内存的***部分存储该分区对象,其后才是各个内存块。在内存块空闲时,其内部存储了下一个节点的的指针。分配以后,该信息丢失,直接分配给申请者,这样省掉了存储每个内存块信息额外的RAM开销。内存释放时,直接加到该分区空闲内存链表的尾部,同时设定下一个节点内存块信息为NULL。这样在多次分配与释放后,内存块的位置会发生比较大的变化。
系统设置了一个全局链表 mempartion **partition_list 来存储所有的内存分区指针,该链表的长度可以动态定义。也就是说分区的数量可以动态定义。链表中的分区需要进行排序,排序的标准是每个分区中内存块的大小,内存块小的分区排在前面,内存块大的排在后面。因为分区采用***适配的算法,排序以后可以减少内存浪费。
6216BZ10000
6220BZ10701
6220BZ10721
6224NZ10800
6225BZ10000
6226BZ10000
6226NZ10400
6227BZ10100
6227BZ10200
6228BZ10000
6229BZ10100
6229BZ10200
6230BP10710
6230BP10720
6230BP10730
6230BP10810
6230BP10820
6230BP10830
6230FP10800
6231BP10810
6231BP10830
6231BP10910
6231BP10920
6231BP10930
6232BP10710
6232BP10720
6232BP10730
6232BP10810
6232BP10820
6232BP10830
6233BP10810
6233BP10820
6233BP10830
6233BP10910
6233BP10920
6233BP10930
6234BP10910
6234BP10920
6234BP10930
6235BP10810
6235BP10820
6235BP10830
6235BP10910
6235BP10920
6235BP10930
6236BP10810
6236BP10820
6236BP10830
6236BP10920
6236BP10930
6240BP10411
6240BP10412
6240BP10421
6240BP10422
6240BP10431
6240BP10432
6240BP10811
6240BP10812
6240BP10821
6240BP10822
6240BP10831
6240BP10832
6241BP10411
6241BP10421
6241BP10431
6241BP10812
6241BP10822
6241BP10832
6245BP10710
6245BP10720
6245BP10730
6246BP10810
6246BP10811
6246BP10820
6246BP10821
6246BP10830
6246BP10831
6247BP10710
6247BP10720
6247BP10730
6248BP10811
6248BP10812
6248BP10821
6248BP10822
6248BP10831
6248BP10832
6252NA10700
6252NB10300
6252NB10700
6253BZ10000
6254BZ10000
6303BZ10000A
1750NZ10001A
2001AZ10101B
2001FP17000A
2001NZ10801B
2001NZ10801C
2001PZ10103A
2002AZ10101A
2002AZ10101B
2002PZ10102A
2003AZ10101A
2004AP10100A
2004AP10110A
2004AP10140A
2004PZ10103C
2005AP21100A
2005AP21110A
2009AZ10220B
2010PZ10000A
2011AZ10100A
2011PZ10103A
2012AZ10101B
2030NZ10000A
2032NZ10000B
2034NZ10000A
2050RZ21102 MODCELL 2050R
2050RZ23002A
2050RZ23102 MODCELL 2050R
2050RZ23102A MODCELL 2050
2050RZ24101 MODCELL 2050R
