您当前的位置:五五电子网电子知识电子知识资料解决方案一种嵌入式系统的内存分配方案 正文
一种嵌入式系统的内存分配方案

一种嵌入式系统的内存分配方案

点击数:7900 次   录入时间:03-04 11:45:20   整理:http://www.55dianzi.com   解决方案

www.55dianzi.com4.1 Intel 交换 机驱动程序中内存分配           在以Intel的交换芯片为基础的交换机方案中,因为采用的是软件地址学习的方式,需要在内存中维护许多数据,如MAC地址表的软拷贝、VLAN表、静态单播地址表、组播地址表等。这些表都是由一些树组成,每个树由一些固定尺寸的节点组成。一般每个节点几十个字节,每棵树的节点数是可增长的,少则几十,最多可到16K个节点。因此,很适合于采用该方案,具体的实现如下:      (1)缓冲池结构   BLOCkMemMgr typedef struct{ MEMSize data_cell_size; /*数据单元的尺寸*/ MEMSize block_size; /*块尺寸*/   /*下面的变量为预定义的每个管理器最多包含的块数,如64 MAX_BLOCKS_OF_MEM_SIZE*/ Unsigned short blocks_being_used;/*已使用的块数*/   Void mem_ptr[PAX_BLOCKS_OF_MEM_SIZE]; /*块数组*/   SLList free_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)缓冲池结构   typedef struct { ulong_t magic; /*用于一致性检测的特殊标记*/   Boolean localAlloc; /*内存是否在创建缓冲区时分配*/   SL_LIST freeList; /*空闲链表*/   Void store; /*缓冲区指向的内存指针*/   STATUS(*createFn)(void*,ulong_t argl); /*创建缓冲区时的回调函数指针*/ STATUS(*destroyFn)(void*,ulong_targl);/*释放缓冲区时的回调函数指针*/ Ulong_t argVal;/*回调函数的参数*/   } 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个例子很好地体现了它的优越性。

上一页  [1] [2] 


本文关键字:嵌入式  解决方案电子知识资料 - 解决方案