




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、13 Sept. 2008Confidential内存的动态分配内存的动态分配内存的动态分配内存的动态分配目标:本章旨在介绍内存的数据结构及操作,通过本章的学习,应该掌握如下知识: uC/OS-II对内存的分区及分块 描述内存块的数据结构-内存控制块 内存控制块与内存分区之间的关系 对内存的操作1 1 内存控制块内存控制块p uC/OS-II对内存进行两级管理:把连续内存分成若干个分区,每个分区又分成若干个大小相等的内存块来进行管理。p 操作系统以分区为单位来管理动态内存,而任务以内存块为单位来获得和释放动态内存。p 内存分区及内存块的使用情况由内存控制块来记录。p 应用程序在运行中为了某种特
2、殊需要,经常需要临时获得一些内存空间。因此作为比较完善的操作系统,必须具有动态分配内存的能力。p 能否合理、有效的对内存进行分配和管理,是衡量一个操作系统品质的指标之一。特别对于实时操作系统,应该保证系统在动态分配内存时,它的执行时间必须是可确定的。uC/OS-II改进了ANSI C用来动态分配和释放内存的函数malloc()和free(),使他们可以对大小固定的内存进行操作,从而使函数malloc()和free()执行时间成为可确定的,满足了实时操作系统的要求。在ANSI C中可以用malloc()和free()两个函数动态地分配内存和释放内存。但是,在嵌入式实时操作系统中,多次这样做会把原
3、来很大的一块连续内存区域,逐渐地分割成许多非常小而且彼此又不相邻的内存区域,也就是内存碎片。由于这些碎片的大量存在,使得程序到后来连非常小的内存也分配不到1.1 可动态分配内存的划分 在内存中划分一个内存分区与内存块的方法:INT16U IntMemBuf510;M 注意:上面这个定义只是在内存中划分出了分区及内存块的区域,还不是一个真正的可以动态分配的内存区! 只有当把内存控制块与分区关联起来之后,系统才能对其进行相应的管理和控制。它才是一个真正的动态内存区。内存块1内存块2内存块3 内存块5一个内存分区图1 内存控制块与内存分区和内存块的关系1-没有控制块时的分区内存uC/OS-II要求同
4、一个分区中内存块的字节数必须相等,而且每个分区与该分区内存块的数据类型必须相同。1.2 内存控制块OS_MEM的结构4 内存控制块的结构:typedef structvoid *OSMemAddr;/ 内存分区的指针(指向分区的起始地址)void *OSMemFreeList;/ 内存控制块链表的指针INT32U OSMemBlkSize;/ 内存块的长度INT32U OSMemNBlks;/ 分区内内存块的数目INT32U OSMemNFree;/ 分区内当前可分配的内存块数目OS_MEM;下一个内存块的指针内存块1下一个内存块的指针内存块2下一个内存块的指针内存块n内存内存分区OSMemA
5、ddrOSMemFreeListOSMemBlkSizeOSMemNBlksOSMemNFree内存控制块OS_MEM0图2 内存控制块与内存分区和内存块的关系2-有控制块时的分区从图中可知,内存控制块的内存分区指针OSMemAddr指向了内存分区,内存分区中的各个内存块又组成了一个单向链表,内存控制块的链表指针OSMemFreeList就指向了这个单向链表的头。1.3 空内存控制块链表OSMemAddrOSMemFreeListOSMemBlkSizeOSMemNBlksOSMemNFreeOSMemAddrOSMemFreeListOSMemBlkSizeOSMemNBlksOSMemNF
6、reeOSMemAddrOSMemFreeListOSMemBlkSizeOSMemNBlksOSMemNFree0共OS_MAX_MEM_PART个内存分区OSMemFreeList图3 空内存控制块链表q uC/OS-II初始化时,会调用内存初始化函数OS_MemInit()定义并初始化一个空内存控制块链表。q 每当应用程序需要创建一个内存分区时,系统就会从空内存控制块链表中摘取一个控制块,而把链表的头指针OSMemFreeList指向下一个空内存控制块;而每当应用程序释放一个内存分区时,则会把该分区对应的内存控制块归还给空内存控制块链表。在OS-CFG.H中定义的常数2 2 动态内存的管
7、理动态内存的管理 创建动态内存分区OS_MEM *OSMemCreate(void *addr,/ 内存分区的起始地址INT32U nblks,/ 分区中内存块的数目INT32U blksize,/ 每个内存块的字节数INT8U *err/ 错误信息 );进入 Addr != NULL?yesno*err=OS_MEM_INVALID_ADDR 返回空指针NULL nblks 1?yesno*err=OS_MEM_INVALID_BLKS 返回空指针NULL blksize = sizeof(void*)?yesno*err=OS_MEM_INVALID_SIZE 返回空指针NULL OSMe
8、mFreeList!= NULL?yesno*err=OS_MEM_INVALID_PART 返回空指针NULL 自空内存控制块链表 取一个空内存控制块 将分区中的所有内存 块链接为单向链表 在内存控制块中 填写刚建立分区的信息 返回内存控制块指针pmem返回图4 函数OSMemCreate()流程图分区的内存块至少有2块每个内存块的空间得至少能存放一个指针例1建立一个含有50个内存块并且每块的长度为64字节的内存分区。试写出主要代码。OS_MEM*CommTxBuffer;/ 定义内存分区指针INT8UCommTxPart5064;/ 定义分区和内存块INT8Uerr;void main(v
9、oid)INT8Uerr;OsInit();CommTxBuffer = OSMemCreate(CommTxPart,/ 内存分区的首地址50,/ 分区内内存块的数目64,/ 每个内存块的长度*err );OSStart(); 请求获得一个内存块void * OSMemGet(OS_MEM *pmem,/ 内存分区的指针INT8U *err/ 错误信息 );2 动态内存的管理(续)进入 pmem != NULL?yesno*err=OS_MEM_INVALID_PMEM 返回空指针NULL pmem-OSNMemFree0?yesno*err=OS_MEM_NO_FREE_BLKS 返回空指
10、针NULLPblk=pmem-OSMemFreeList 调整区内的内存块链表 pmem-OSMemNFree- *err=OS_NO_ERR 返回分配给应用程序 的内存块指针pblk图5 函数OSSemGet()流程图内存分区尚存在未被分配的内存块将内存块链表的第一个块的指针OSMemFrereList赋给了指针pblk使指针OSMemFrereList指向新的链表头例2在例1的基础上写出任务MyTask请求一个内存块的代码。OS_MEM*CommTxBuffer;/ 定义内存分区指针INT8UCommTxPart5064;/ 定义分区和内存块INT8Uerr;INT8U*BlkPtr;/
11、定义内存块指针void main(void)INT8Uerr;OsInit();CommTxBuffer = OSMemCreate(CommTxPart,50,64,*err);OSStart();void MyTask( (void *)pdata )for(;)BlkPtr = OSMemGet(CommTxBuffer,&err); 需要注意的是:应用程序在调用函数OSMemGet()时,应该事先知道该分区中内存块的大小,并且在使用该内存块时不能超其长度,否则会引起灾难性的后果。当应用程序不再需要该内存块时,必须及时将其释放。 释放一个内存块INT8U OSMemPut(OS_MEM
12、*pmem,/ 内存所属内存分区的指针void *pblk/ 待释放内存块的指针 );2 动态内存的管理(续)进入 pmem != NULL?yesno返回OS_MEM_INVALID_PMEM pblk != NULL?yesno返回OS_MEM_INVALID_PBLK链表头指针OSMemFreeList 指向释放的内存块Pmem-OSMemNFree+ 返回OS_NO_ERR图6 函数OSSemPut()流程图需要注意的是,在调用函数OSMemPut()时,一定要确保把该内存块释放到它原来所属的内存分区中,否则会引起灾难性后果。对例2中任务MyTask使用的内存块进行释放 查询一个内存分
13、区的状态INT8U OSMemQuery( OS_MEM *pmem,/ 待查询的内存控制块的指针 OS_MEM_DATA *pdata/ 存放分区状态信息的结构的指针 );2 动态内存的管理(续)typedef struct void *OSAddr; / 内存分区的指针 void *OSFreeList; / 分区内内存块链表的头指针 INT32U OSBlkSize; / 内存块的长度 INT32U OSNBlks; / 分区内内存块的数目 INT32U OSNFree; / 分区内空闲内存块的数目 INT32U OSNUsed; / 已被分配的内存块的数目 OS_MEM_DATA;OS_MEM_DATA结构如下:例3 设计一个含有3个任务的应用程序,这3个任务分别是MyTask、YouTask和HerTask。在应用程序中创建一个动态内存分区,该分区有8个内存块,每个内存块的长度为6个字节。应用程序的任务YouTask和HerTask都在任务运行后请求一个内存块,随后就释放它。任务MyTask也在任务运行后请求一个内存块,但是要在任务MyTask运行6次后,才释放它所申请的内存块。 为了了解内存分区变化的情况,编写代码来观察分区头指针和已被使用内存块的个数。练习1 设计一个有两个任务的应用程序,其中一个任务用来进行两个随机数的加法运
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年区块链工程师职业能力测试卷:区块链技术在身份认证与隐私保护中的应用试题
- 2025年美容师初级技能水平测试卷:美容师产品知识与应用案例分析应用解析试题
- 2025年统计学专业期末考试题库-统计与决策方法解析与应用试题
- 项目招投标标准合同范本
- 绿色建筑设计申报材料填写指南
- 幼儿语言发展测评量表及使用指南
- IPQC质量管理绩效考核细则范本
- 2025年消防安全隐患排查培训考试题库与解析
- 2025年医保知识考试题库及答案:医保信息化平台操作案例分析试题型(初级+中级)
- 2025年医保改革试题及答案:医保政策调整对医疗资源优化配置的影响试题
- 2025年全运会知识竞赛试题及答案
- 2025年陕西清水川能源股份有限公司招聘笔试参考题库含答案解析
- 《光伏逆变器用长寿命级CD297S型铝电解电容器》
- 《公路软土地基处治工程技术规范》(DB45T 1972-2019)
- 工余安健环知识培训
- 云南省石林县鹿阜中学七年级地理上册 第一章 第四节 地球的公转教案 (新版)商务星球版
- 《路遥人生》读书分享课件
- 以青春之名励青春之志
- 小学数学新旧知识关联
- 第9课 共同弘扬中华传统美德 《中华民族大团结》(初中 精讲课件)
- 万夫一力天下无敌 课件-2023-2024学年高一上学期增强班级凝聚力主题班会
评论
0/150
提交评论