首页 资讯 应用 高压 设计 行业 低压 电路图 关于

嵌入式

旗下栏目: PLC 嵌入式 单片机 DCS

OSAL之动态内存管理

嵌入式 | 发布时间:2017-10-04 | 人气: | #评论# |本文关键字:OSAL,动态内存管理
摘要:OSAL 的动态内存管理实现在 OSAL_Memory.c 与 OSAL_Memory.h 两个文件中。 OSAL 的对动态内存管理实际上是对动态内存对的管理。通过不断申请新内存与释放内存不需要的内内存空间来实现管理

OSAL的动态内存管理实现在OSAL_Memory.cOSAL_Memory.h两个文件中。OSAL的对动态内存管理实际上是对动态内存对的管理。通过不断申请新内存与释放内存不需要的内内存空间来实现管理,这种内存的分配策略能够减少内存的浪费,比较简单,适合小内存的管理,但是频繁的动态分配和释放,容易照成严重的内存碎片。TI的官方也提供了一个参考的文档《Heap_Memory_Management》对OSAL的动态管理进行了一定的说明。OSAL的动态内存分成三种:小块内存(small block),大块内存(big block)和长存内存(long-lived)。当申请小空间内存时,可以使用小块内存;当小块内存不够用时,则可以使用大块空间;而对于一些从程序开始申请空间后到程序结束都不会释放的空间就放在长存内存中。

1、定义内存管理结构

typedef struct {   unsigned len : 15;   unsigned inUse : 1;} osalMemHdrHdr_t;

这是一个结构体,它的bit0~bit14用来保存内存的长度,bit15则用来标注这段内存是否被使用。

OSAL之动态内存管理

 为了增加移植性,又对这个管理结构进行了进一步包装:

typedef union {  halDataAlign_t alignDummy;  uint16 val;  osalMemHdrHdr_t hdr;} osalMemHdr_t;

这是一个公用体,alignDummy虽然是uint8类型的结构,但是不同的处理器分配给uint8类型的空间大小是不一样。举个例子来说,对于851系列单片机来说,给uint8分配的是8位空间;而对于向32位的ARM系列处理器则实际上给uint8分配的空间为32(尽管其中24位空着)

OSAL之动态内存管理

 2、调整申请内存的大小宏操作

#define OSALMEM_ROUND(X)((((X)+OSALMEM_HDRSZ-1)/OSALMEM_HDRSZ)*OSALMEM_HDRSZ)

将申请的内存空间大小向下调整成OSALMEM_HDRSZ的整数倍。如:

X=OSALMEM_HDRSZ, 输出OSALMEM_HDRSZ;

X-OSALMEM_HDRSZ+1,输出OSALMEM_HDRSZ;

...

X=2*OSALMEM_HDRSZ-1,输出OSALMEM_HDRSZ;

X=2*OSALMEM_HDRSZ,输出2*OSALMEM_HDRSZ;

3、几种内存类型空间带下定义

(1)首部大小:OSALMEM_HDRSZ=2

#define OSALMEM_HDRSZ sizeof(osalMemHdr_t)

(2)堆总空间:MAXMEMHEAP=3072

这个空间大小在IAR编译的预编译宏定义区中定义。

(3)最小块大小:OSALMEM_MIN_BLKSZ=4

#define OSALMEM_MIN_BLKSZ (OSALMEM_ROUND((OSALMEM_HDRSZ*2))

(4)默认长存块大小:OSALMEM_LL_BLKSZ=456

#define OSALMEM_LL_BLKSZ (OSALMEM_ROUND(417) + (19 * OSALMEM_HDRSZ))

(5)小块大小:OSALMEM_SMALL_BLKSZ=16

#define OSALMEM_SMALL_BLKSZ (OSALMEM_ROUND(16))

(6)默认小块数量:OSALMEM_SMALL_BLKCNT=8

#define OSALMEM_SMALL_BLKCNT 8

(7)小块总空间:OSALMEM_SMALLBLK_BUCKET=16*8+456=584

#define OSALMEM_SMALLBLK_BUCKET ((OSALMEM_SMALL_BLKSZ * OSALMEM_SMALL_BLKCNT) + OSALMEM_LL_BLKSZ)

(8)大块空间:OSALMEM_BIGBLK_SZ=3072-584-2*2=2048

#define OSALMEM_BIGBLK_SZ (MAXMEMHEAP - OSALMEM_SMALLBLK_BUCKET - OSALMEM_HDRSZ*2)

4、三个内存位置索引宏定义

(1)区分块位置:OSALMEM_SMALLBLK_HDRCNT=292

#define OSALMEM_SMALLBLK_HDRCNT (OSALMEM_SMALLBLK_BUCKET / OSALMEM_HDRSZ)

这个位置放着一个类型为osalMemHdr_tinUse=1len=2的管理首部,它的主要目的就是将小块空间与大块空间隔离开来。

(2)大块起始位置:OSALMEM_BIGBLK_IDX=293

#define OSALMEM_BIGBLK_IDX (OSALMEM_SMALLBLK_HDRCNT + 1)

(3)堆空间结束位置:OSALMEM_LASTBLK_IDX=1535

#define OSALMEM_LASTBLK_IDX ((MAXMEMHEAP/OSALMEM_HDRSZ)-1)

5、定义堆空间及指向第一个空闲小块的指针

static osalMemHdr_t theHeap[MAXMEMHEAP / OSALMEM_HDRSZ];static osalMemHdr_t *ff1;

OSAL之动态内存管理

6、设计一个内存分析器

只有宏定义了OSALMEM_PROFILER才能使用这个内存的分析器,在代码中暂时忽略内存分析器相关的代码!

(1)定义三种内存空间状态

内存初始状态:

#define OSALMEM_INIT 'X'

内存分配状态:

#define OSALMEM_ALOC 'A'

内存释放状态:

#define OSALMEM_REIN 'F'

(2)五个分析变量

历史最多内存块数量:

static uint16 blkMax;

当前内存块数量:

static uint16 blkCnt;

当前空闲块数量:

static uint16 blkFree;

当前已分配空间大小:

static uint16 memAlo;

历史最多分配空间大小:

static uint16 memMax;

(3)五个记录表

内存大小分类:

static uint16 proCnt[OSALMEM_PROMAX] = {OSALMEM_SMALL_BLKSZ, 48, 112, 176, 192, 224, 256, 65535 };

当前内存用量:

static uint16 proCur[OSALMEM_PROMAX] = {0, 0, 0, 0, 0, 0, 0, 0};

最大内存用量记录:

static uint16 proMax[OSALMEM_PROMAX] = { 0, 0 ,0, 0, 0, 0, 0, 0};

内存都分配历史总量:

static uint16 proTot[OSALMEM_PROMAX] = { 0, 0, 0, 0, 0, 0, 0, 0};

小块不够用借用大块的次数:

static uint16 proSmallBlkMiss;

责任编辑:电气自动化网
首页 | 资讯 | 应用 | 高压 | 设计 | 行业 | 低压 | 电路图 | 关于

Copyright 2017-2018 电气自动化网 版权所有 辽ICP备17010593号-1

电脑版 | 移动版

Ctrl+D 将本页面保存为书签,全面了解最新资讯,方便快捷。