UCOS-II的动态内存管理
来源:互联网 发布:网络施工分成协议书 编辑:程序博客网 时间:2024/05/16 06:35
近来学习了UCOS-II嵌入式操作系统,感慨颇多。
首先是系统麻雀虽小,五脏俱全,然后是不管讲的如何简单,都应该看一下代码。
下面将相关的东西总结一下:
UCOS对内存进行两级管理,即将连续的内存空间分成若干个内存分区,一个内存分区里面又有若干个大小相等的内存块。操作系统对内存分区为单位对内存进行管理,任务以内存块为单位来获得和释放动态内存。而内存分区和内存块的使用情况则是通过内存控制块来进行记录。
内存控制块:
typedef struct os_mem { void *OSMemAddr;//当前内存分区的起始地址 void *OSMemFreeList;//**内存块和内存分区的链表指针** INT32U OSMemBlkSize;//当前内存分区的内存块大小 INT32U OSMemNBlks;//当前内存分区中内存块的数目 INT32U OSMemNFree;//当前内存分区中未被使用的内存块数目 } OS_MEM;
上述的指针OSMemFreeList需要特别注意一下。
首先系统在ucos_ii.h中已经声明了如下相关内容:
extern OS_MEM *OSMemFreeList;//内存分区链表头指针 extern OS_MEM OSMemTbl[OS_MAX_MEM_PART];//内存分区数组
然后动态内存分配主要涉及以下这些函数:
- OS_MemInit(void)
- OS_MEM *OSMemCreate (void *addr,INT32U nblks,INT32U blksize,INT8U *perr)
- void *OSMemGet (OS_MEM *pmem,INT8U *perr)
- INT8U OSMemPut (OS_MEM *pmem,void *pblk)
这些函数分别涉及了动态内存的初始化,内存分区的创建,内存块的申请和释放
下面逐个进行讲解:
1.OS_MemInit(void)
通过这个函数,系统将上面的所有空内存控制块连接成为一个链表,OSMemFreeList指向链表头(这是个结构体指针,不要和该结构体的成员混淆,因为两者名字相同)。
执行完效果图如下:
2.OS_MEM *OSMemCreate (void *addr,INT32U nblks,INT32U blksize,INT8U *perr)
该函数分配一个内存分区,并且将里面的内存块建立成一个链表。
OS_MEM *pmem; INT8U *pblk; void **plink; pmem = OSMemFreeList; if (OSMemFreeList != (OS_MEM *)0) { OSMemFreeList = (OS_MEM *)OSMemFreeList->OSMemFreeList; } plink = (void **)addr; pblk = (INT8U *)addr; loops = nblks - 1; for (i = 0u; i < loops; i++) { pblk += blksize; *plink = (void *)pblk; plink = (void **)pblk; }//这一段是对内存块建立链表的过程,如果不太懂得话请看一下我前面的指针和指针的指针的讲解 *plink = (void *)0; pmem->OSMemAddr = addr; pmem->OSMemFreeList = addr; pmem->OSMemNFree = nblks; pmem->OSMemNBlks = nblks; pmem->OSMemBlkSize = blksize; *perr = OS_ERR_NONE; return (pmem);
操作完成后效果如下所示:
每一个内存块的起始地址对应的内存空间中存放了下一个内存块的地址。
使用实例:
OSMemCreate (&A,6,8,&perr);
这样类似创建了一个A[6][8] 矩阵的内存分区,该内存分区里面有6个内存块,每个内存块的大小为8.
3. void *OSMemGet (OS_MEM *pmem,INT8U *perr)
if (pmem->OSMemNFree > 0u) { pblk = pmem->OSMemFreeList; pmem->OSMemFreeList = *(void **)pblk; pmem->OSMemNFree--; }
这个函数用于从前面生成的内存分区中取得一个内存块。
由上图可以看出,在创建了内存分区之后,该分区内存控制块结构体的OSMemAddr和OSMemFreeList 都指向分区的起始地址,而且每个内存块的首地址中都存放了下一个内存块的地址,因此上述OSMemFreeList 也就是内存块链表的头指针。在申请一个内存块时首先取得未被分配的内存块链的首个内存块地址(即OSMemFreeList 指向的地址 ),然后在将该地址中存放的内容–也就是下个内存块的起始地址赋给OSMemFreeList,最后将可用的内存块数量减一。
4. INT8U OSMemPut (OS_MEM *pmem,void *pblk)
*(void **)pblk = pmem->OSMemFreeList; pmem->OSMemFreeList = pblk; pmem->OSMemNFree++;
这个函数用于释放一个内存块到其所属的内存分区中,与上述的申请操作正好相反。首先将待释放的内存块的首地址对应的内存空间中存放进下一个内存块的地址,然后将OSMemFreeList 指向该内存块,最后将可用内存块数目加一。
- UCOS-II的动态内存管理
- uCos-II内存管理
- UCOS-II内存管理
- uCOS-II中的内存管理--C语言构建完整的微型动态内存管理机制
- UCOS-II内存池管理
- uCos的内存管理
- uCos的内存管理
- uCos的内存管理
- uCos的内存管理
- uCos的内存管理
- ucos-ii示例7:内存管理测试
- ucos-ii中内存块的建立
- UCOS-II任务管理
- UCOS-II时间管理
- ucos II 内核学习之七:内存管理
- 用Buddy算法来改进uCos-ii内存管理方案
- ucos II 内核学习之七:内存管理
- 用Buddy算法来改进uCos-ii内存管理方案
- ps_3_0 does not allow textures or samplers to be members of compound types
- HDU 2870 Largest Submatrix (求最大子矩阵变形,可变值)枚举每种情况
- android 全屏对话框
- 基于rails的schedule网站开发(15):学习如何测试
- igs08核心站
- UCOS-II的动态内存管理
- 数字下变频的一种新型设计方法
- Android看门狗
- 浅谈Linux内存管理机制
- 蓝桥杯学习笔记——世纪末的星期
- Java课程设计-学籍信息管理系统
- eclipse 安装 markplace出现org.eclipse.equinox.p2.discovery.feature.feature.group错误
- .vimrc 的一些配置 (等待更新
- HDU1166(线段树做法)