前言
所谓内存管理其实不过就是可以对内存进行动态分配、回收的方法,使得内存的使用效率更高,避免出现内存碎片化等问题。
我们在编写C语言程序时,一般都是用malloc
和free
函数来分配释放内存,因为我们编写的程序是在电脑上运行的,一般都不用考虑内存碎片化和内存不够等问题。但是我们在内存较小的单片机上遇到指针等需要动态分配内存的情况时,合理高效的使用珍贵的内存资源就显得尤为重要,因此需要进行内存管理,实现我们需要的malloc
和free
函数。
对于一款好的RTOS来说,内存管理更是必不可少的。
一、UCOSIII内存管理简介
UCOSIII将内存分为区和块,一个区中有固定大小的块,示意如下:
使用结构体os_mem
来保存内存的相关信息:
struct os_mem { /* MEMORY CONTROL BLOCK */
OS_OBJ_TYPE Type; /* Should be set to OS_OBJ_TYPE_MEM */
void *AddrPtr; /* Pointer to beginning of memory partition */
CPU_CHAR *NamePtr;
void *FreeListPtr; /* Pointer to list of free memory blocks */
OS_MEM_SIZE BlkSize; /* Size (in bytes) of each block of memory */
OS_MEM_QTY NbrMax; /* Total number of blocks in this partition */
OS_MEM_QTY NbrFree; /* Number of memory blocks remaining in this partition */
#if OS_CFG_DBG_EN > 0u
OS_MEM *DbgPrevPtr;
OS_MEM *DbgNextPtr;
#endif
};
Type
:为需要分配内存的类型
AddrPtr
:是存储区的起始地址
NamePtr
:指向存储区的名字
FreeListPtr
:指向当前空闲存储块的地址
BlkSize
:存储区中的存储块大小,单位为字节Byte
NbrMax
:最大的存储块数量,即存储块的总数
NbrFree
:当前空闲的存储块数量
创建好的存储区如下:
可以看出是使用链表的方法实现的,FreeListPtr
指向当前空闲的内存。
二、相关函数
2.1 存储区创建函数
创建存储区的函数基本参数如下:
void OSMemCreate (OS_MEM *p_mem,
CPU_CHAR *p_name,
void *p_addr,
OS_MEM_QTY n_blks,
OS_MEM_SIZE blk_size,
OS_ERR *p_err)
p_mem
:OS_MEM对象,需要用户定义
p_name
:存储区的名字,用户自取
p_addr
:存储区的基地址,即开始地址
n_blks
:存储块的总数量
blk_size
:单个存储块的大小
p_err
:返回的错误码
使用实例:
//创建一个存储分区
OSMemCreate((OS_MEM* )&INTERNAL_MEM,
(CPU_CHAR* )"Internal Mem",
(void* )&Internal_RamMemp[0][0],
(OS_MEM_QTY )INTERNAL_MEM_NUM,
(OS_MEM_SIZE)INTERNAL_MEMBLOCK_SIZE,
(OS_ERR* )&err);
2.2 内存申请函数
相当于malloc()
函数,申请内存,参数如下:
void *OSMemGet (OS_MEM *p_mem,
OS_ERR *p_err)
p_mem
:需要使用的内存区
p_err
:返回的错误码
2.3内存释放函数
相当于free()
函数,参数:
void OSMemPut (OS_MEM *p_mem,
void *p_blk,
OS_ERR *p_err)
p_mem
:释放后归属的内存区
p_blk
:需要释放的内存块
p_err
:返回的错误码
注意事项:
UCOSIII中的内存管理方法还是比较粗糙的,不可以申请任意大小的内存,申请对应大小的内存需要创建一个该大小的存储区。正点原子的例程是使用自己的内存管理方法。