




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、嵌入式实时操作系统嵌入式实时操作系统C/OS-C/OS-教程教程 第九章第九章 内存管理内存管理第第 9 9 章章 内存管理内存管理一、内存管理基本原理二、四个内存管理函数 本章主要内容嵌入式实时操作系统嵌入式实时操作系统C/OS-C/OS-教程教程 第九章第九章 内存管理内存管理9.1 概述 9.1.1 基本原理一构建新型内存管理方法的原因 在内存管理方面,ANSI C本身就提供了malloc()和free()两个函数用于动态地分配内存和释放内存。 但是C/OS-II为什么不直接利用这两个函数,而要另外构建内存管理方法呢?主要原因在于:(1 1)内存碎片问题:)内存碎片问题:当应用程序反复调
2、用malloc()和free()函数进行内存的分配与释放时,可能会将原来一块很大且连续的内存区域,逐渐分割成许多细小而彼此不相邻的内存区域,产生我们通常说的内存碎片。当内存碎片大量存在时,最后应用程序可能连一块很小的内存也无法分配到;(2 2)执行时间不确定的问题:)执行时间不确定的问题:由于内存管理算法的原因,malloc()和free()函数的执行时间是不确定的,因此不适合作实时操作系统函数应用。嵌入式实时操作系统嵌入式实时操作系统C/OS-C/OS-教程教程 第九章第九章 内存管理内存管理二、解决方案1. 1. 采用两个技术:(1 1)内存分区分块技术:)内存分区分块技术:把连续大块的内
3、存分成内存分区,每个分区又分成整数个大小相同的内存块;(2 2)内存指针描述和链接技术:内存指针描述和链接技术:用指针表示每个分区和内存块的地址,并用指针把同一分区中的每个内存块链接成起来,形成逻辑上的连续内存空间。构建了C/OS-II的内存管理方法。2.2. 执行时间问题:执行时间问题:由于C/OS-II每个内存块的大小是固定的,而且一次只能分配或释放一个内存块,这就使得每次的分配或释放都可以通过使用一条指针来实现的。这就解决了内存管理上执行时间不确定的问题。分区2图图9.1 内存分区内存分区 块内存分区分区103.3. 内存碎片问题:内存碎片问题:分配内存时,可以从不同的内存分区中得到大小
4、不同的内存块。当释放时,规定:内存块需要用指针链接回到它以前所属于的内存分区。这样一来,经过多次反复分配和释放后,分区中的自由内存块在物理空间上可能不再连续,但逻辑空间却始终都是连续的。嵌入式实时操作系统嵌入式实时操作系统C/OS-C/OS-教程教程 第九章第九章 内存管理内存管理9.1.2 内存管理函数C/OS-C/OS-提供了提供了4 4种内存管理的函数,函数所属文件是种内存管理的函数,函数所属文件是OS_MEM.COS_MEM.C。表表9.1 9.1 内存管理函数一览表内存管理函数一览表函数函数功能功能调用者调用者OSMemCreate()OSMemCreate()建立内存分区建立内存分
5、区任务或者启动代码任务或者启动代码OSMemGetOSMemGet() ()获取一个内存块获取一个内存块任务或者中断任务或者中断OSMemPutOSMemPut() ()释放一个内存块释放一个内存块任务或者中断任务或者中断OSMemQueryOSMemQuery() ()查询内存分区的状态查询内存分区的状态任务或者中断任务或者中断9.1.3 内存管理函数配置常量表表9.2 9.2 信号量函数配置常量一览表信号量函数配置常量一览表函数函数配置常量配置常量说明说明系统配置系统配置OS_MEM_ENOS_MEM_EN该常量为该常量为0 0时,屏蔽所有信号量函数时,屏蔽所有信号量函数OS_MAX_ME
6、M_PARTOS_MAX_MEM_PART定义最大内存分区数,至少为定义最大内存分区数,至少为2 2。OSMemCreate()OSMemCreate()内存管理必然包含这内存管理必然包含这3 3个函数,所以个函数,所以它们没有单独的配置常量。它们没有单独的配置常量。OSMemGetOSMemGet() ()OSSemPutOSSemPut() ()OSMemQueryOSMemQuery() ()OS_MEM_QUERY_ENOS_MEM_QUERY_EN嵌入式实时操作系统嵌入式实时操作系统C/OS-C/OS-教程教程 第九章第九章 内存管理内存管理9.1.4 内存控制块一、内存控制块数据结
7、构 内存控制块(MCB:memory control blocks)是用于实现内存管理、跟踪每一个内存分区的数据结构,定义如程序清单9.1所示,每个内存分区都有它自己的内存控制块。程序清单程序清单9.1 内存控制块的数据结构内存控制块的数据结构typedef struct void *OSMemAddr;/ 是指向内存分区起始地址的指针。它在建立/ 内存分区时被初始化, 此后不能更改。 void *OSMemFreeList;/ 在空闲内存控制块链表中,是指向下一个空/ 闲内存控制块的指针;在已建立的内存分区/ 中,是指向第一个空闲内存块的指针。 INT32U OSMemBlkSize;/ 内
8、存分区中内存块的大小,由用户在建立内/ 存分区时指定 INT32U OSMemNBlks;/ 内存分区中总的内存块数量,由用户在建立/ 内存分区时指定 INT32U OSMemNFree; / 内存分区中当前可以使用的空闲内存块数量 OS_MEM;嵌入式实时操作系统嵌入式实时操作系统C/OS-C/OS-教程教程 第九章第九章 内存管理内存管理二、应用前提 如果要使用C/OS-II中的内存管理,要做如下工作:1.需要将OS_CFG.H文件中将配置OS_MEM_EN设置为1;2.然后还要设置OS_MAX_MEM_PART常量,其值至少是2,它定义了系统中的最大分区数。这样,在启动时C/OS-II就
9、会通过OSInit()调用OSMemInit()来实现对内存管理器的初始化,该初始化主要建立一个如图9.2所示的空闲内存控制块链表其中OSMemFreeList指针的作用是将空闲内存控制块链接成空闲内存控制块链表。 图图9.2 空闲内存控制块链表空闲内存控制块链表 OSMemAddrOSMemFreeListOSMemBlkSizeOSMemNBlksOSMemNFreeOSMemAddrOSMemFreeListOSMemBlkSizeOSMemNBlksOSMemNFreeOSMemAddrOSMemFreeListOSMemBlkSizeOSMemNBlksOSMemNFreeOSMem
10、FreeList0OS_MAX_MEM_PART嵌入式实时操作系统嵌入式实时操作系统C/OS-C/OS-教程教程 第九章第九章 内存管理内存管理9.2 建立内存分区,OSMemCreate() 9.2.1 函数原型OS_MEM *OSMemCreate( void *addr,INT32U nblks,INT32U blksize,INT8U *err) reentrant一一功能:功能:OSMemCreate()函数用于建立并初始化一块内存分区。要函数用于建立并初始化一块内存分区。要使用内存管理函数,必先调用使用内存管理函数,必先调用OSMemCreate()函数建立内存分区。函数建立内存分
11、区。一个内存分区包含数量和大小都确定的内存块,应用程序可以分一个内存分区包含数量和大小都确定的内存块,应用程序可以分配这些内存块,并在用完后释放回内存分区。配这些内存块,并在用完后释放回内存分区。二二函数参数函数参数 1.addr 建立的内存分区的起始地址。内存分区可以使用静态数建立的内存分区的起始地址。内存分区可以使用静态数组或在初始化时使用组或在初始化时使用malloc()函数建立;函数建立;2.nblks 内存块的数量。每一个内存分区最少需要定义内存块的数量。每一个内存分区最少需要定义2个内存个内存块;块;3.blksize 每个内存块的大小,最少应该能够容纳一个指针;每个内存块的大小,
12、最少应该能够容纳一个指针;4.err 指向错误代码的变量的指针。指向错误代码的变量的指针。嵌入式实时操作系统嵌入式实时操作系统C/OS-C/OS-教程教程 第九章第九章 内存管理内存管理4.err 指向错误代码的变量的指针。指向错误代码的变量的指针。OSMemCreate()函数返回的错误代码可能有以下几种:函数返回的错误代码可能有以下几种:OS_NO_ERR 内存分区建立成功;内存分区建立成功;OS_MEM_INVALID_ADDR 参数参数addr为空指针,非法;为空指针,非法;OS_MEM_INVALID_PART 没有空闲的内存分区;没有空闲的内存分区;OS_MEM_INVALID_B
13、LKS 没有为每一个内存分区建立至少没有为每一个内存分区建立至少两个内存块;两个内存块;OS_MEM_INVALID_SIZE 内存块太小,不能容纳一个指针内存块太小,不能容纳一个指针变量。变量。三三调用者:调用者:任务或者启动代码。任务或者启动代码。四四配置常量:配置常量:没有单独的配置常量。没有单独的配置常量。9.2.2 返回值1.如果建立成功,如果建立成功,OSMemCreate()函数返回指向内存控制块的指针;函数返回指向内存控制块的指针;2.若没有空闲内存分区,说明建立不成功,若没有空闲内存分区,说明建立不成功,OSMemCreate()函数返回函数返回空指针。空指针。 嵌入式实时操
14、作系统嵌入式实时操作系统C/OS-C/OS-教程教程 第九章第九章 内存管理内存管理9.2.3 原理与实现一OSMemCreate()函数基本原理:从空闲内存控制块链表中去一个内存控制块,根据参数addr、nblks和blksize构建如图9.3所示的空闲内存块单向链表,并根据这3个参数填写内存控制块中的5个参数,最后返回指向内存控制块的指针。以后针对内存的管理操作都可以通过这个指针来完成。OSMemAddr = addrOSMemFreeList= addrOSMemBlkSize = blkSizeOSMemNBlks = nblksOSMemNFree = nblks内存分区0pmem二
15、函数运行完毕后,内存控制块所对应的内存分区与分区中的内存块之间的关系如图9.3所示。三程序一旦运行,经过多次分配与 释放内存块后,同一分区内的内存块的链接顺序会有很大变化,但这并不影响使用,也不增加时间开销。图9.3 OSMemCretae() 建立的内存分区 嵌入式实时操作系统嵌入式实时操作系统C/OS-C/OS-教程教程 第九章第九章 内存管理内存管理OS_MEM *MemBuf; / 定义一个内存控制块指针INT8U buffer5016; / 定义一个内存分区数组, / 含50个内存块,每块16个字节void main (void) INT8U err;OSInit();. MemBu
16、f = OSMemCreate(buffer,50,16,&err);.OSStart();9.2.4 应用范例 OSMemCreate()函数应用范例如程序清单9.3所示:建立一个含有50个内存块、每个内存块16字节的内存分区。程序清单程序清单9.3 OSMemCreate()应用范例应用范例嵌入式实时操作系统嵌入式实时操作系统C/OS-C/OS-教程教程 第九章第九章 内存管理内存管理9.3 获取内存块,OSMemGet() 9.3.1 函数原型void *OSMemGet(OS_MEM *pmem,INT8U *err) reentrant一一功能:功能:OSMemGet()OSMemG
17、et()函数用于从已经建立的内存分区中申请获函数用于从已经建立的内存分区中申请获取一个内存块。函数的调用者可以是任务或者中断,没有单取一个内存块。函数的调用者可以是任务或者中断,没有单独的配置常量。独的配置常量。二二参数参数1. 1.pmempmem 指向内存控制块的指针,它是调用指向内存控制块的指针,它是调用OSMemCreateOSMemCreate() ()函数建函数建立内存分区时的返回值。立内存分区时的返回值。2.2.errerr 指向包含错误代码的变量的指针,错误代码有以下几种:指向包含错误代码的变量的指针,错误代码有以下几种: OS_NO_ERROS_NO_ERR 成功得到一个内存
18、块;成功得到一个内存块; OS_MEM_NO_FREE_BLKSOS_MEM_NO_FREE_BLKS 内存分区中已经没有空闲内存块;内存分区中已经没有空闲内存块; OS_MEM_INVALID_PMEM OS_MEM_INVALID_PMEM pmempmem是空指针。是空指针。9.3.2 返回值1. 1.如果获取成功,如果获取成功,OSMemGetOSMemGet() ()函数返回指向内存区块的指针;函数返回指向内存区块的指针;2.2.如果没有空间分配给内存块,函数返回空指针。如果没有空间分配给内存块,函数返回空指针。嵌入式实时操作系统嵌入式实时操作系统C/OS-C/OS-教程教程 第九章
19、第九章 内存管理内存管理9.3.3 原理与实现 OSMemGet()函数基本原理:从参数pmem指定的内存分区中抽取第一个空闲的内存块。如果这个空闲内存块可用,则调整OSMemFreeList指针,使其指向空闲内存块链表中的下一个空闲内存块,并返回所获取的内存块指针;如果不可用,则返回空指针。9.3.4 应用要点1.调用OSMemGet()函数申请获取内存块时,用户必须知道内存分区中内存块的大小,使用时不能超过容量。例如,如果一个内存分区内的每个内存块为64字节,那么,应用程序最多只能使用内存块中的64字节;2.用户在使用完内存块后应该及时释放,且必须重新放回它原先所属的内存分区中去;3.函数
20、可以反复多次调用;4.如果暂时没有内存块可用,函数不会等待,而是立即返回NULL指针,所以可在中断中调用。 嵌入式实时操作系统嵌入式实时操作系统C/OS-C/OS-教程教程 第九章第九章 内存管理内存管理程序清单程序清单9.5 OSMemGet()应用范例应用范例OS_MEM *MemBuf; / 定义一个内存控制块指针void Task (void *ppdata) reentrant INT8U *msg; ppdata = ppdata;for (;) msg = OSMemGet(MemBuf,&err);if (msg != (INT8U *)0) . / 内存块已经分配 9.3.5
21、 应用范例嵌入式实时操作系统嵌入式实时操作系统C/OS-C/OS-教程教程 第九章第九章 内存管理内存管理9.4 释放内存块,OSMemPut() 9.4.1 函数原型,OSMemPut()INT8U OSMemPut( OS_MEM *pmem,void *pblk) reentrant一一功能:功能:OSMemPutOSMemPut() ()函数用于释放一个内存块。函数用于释放一个内存块。二二配置常量:配置常量:没有单独的配置常量。没有单独的配置常量。三三调用者:调用者:任务或者中断。任务或者中断。四四函数参数函数参数1. 1.pmempmem 指向内存控制块的指针,它是调用指向内存控制块
22、的指针,它是调用OSMemCreateOSMemCreate() ()函数建立内存分区时函数建立内存分区时的返回值;的返回值;2.2.pblkpblk 指向将要被释放的内存块的指针。指向将要被释放的内存块的指针。嵌入式实时操作系统嵌入式实时操作系统C/OS-C/OS-教程教程 第九章第九章 内存管理内存管理9.4.2 返回值 OSMemPut()函数的返回值有如下几种:1.OS_NO_ERR 内存块释放成功;2.OS_MEM_FULL 内存分区已满,不能再接受释放的内存块。这种情况说明用户程序出现了错误,释放的内存块多于用OSMemGet()函数得到的内存块;3.OS_MEM_INVALID_
23、PMEM pmem是空指针;4.OS_MEM_INVALID_PBLK pblk是空指针。9.4.3 原理与实现 OSMemPut()函数基本原理:通过检查参数pmem指定的内存分区是否已满,来确定是否可以释放内存块。如果已满,说明系统在分配和释放内存时出现了错误,无法释放。如果未满,则将参数pblk指定的内存块插入到参数pmem指定的空闲内存块链表的最前面,成功释放。 嵌入式实时操作系统嵌入式实时操作系统C/OS-C/OS-教程教程 第九章第九章 内存管理内存管理9.4.4 应用要点1.如果一个内存块已经不再使用,必须及时释放它,以备其它应用程序使用;2.释放内存块时,必须放回到原先申请的内
24、存分区中,不能错放,否则可能导致系统崩溃。 例如:从每个内存块是32字节的内存分区中申请了一个内存块,用完后就不能把它返回给每个内存块是64字节的内存分区。应用程序以后申请64字节分区中的内存块时,可能会只得到32字节的可用空间,而得不到64字节的内存块。嵌入式实时操作系统嵌入式实时操作系统C/OS-C/OS-教程教程 第九章第九章 内存管理内存管理程序清单程序清单9.7 OSMemPut()应用范例应用范例OS_MEM *MemBuf; / 定义一个内存控制块指针INT8U *MemMsg; / 定义一个内存块指针void Task (void *ppdata) reentrant INT8
25、U err; ppdata = ppdata;for (;) err = OSMemPut(MemBuf,(void *)MemMsg); if (err = = OS_NO_ERR) 应用程序; . 9.4.5 应用范例嵌入式实时操作系统嵌入式实时操作系统C/OS-C/OS-教程教程 第九章第九章 内存管理内存管理9.5 查询内存分区的状态,OSMemQuery() 9.5.1 函数原型INT8U OSMemQuery(OS_MEM *pmem,OS_MEM_DATA *ppdata) reentrant一一功能功能:OSMemQueryOSMemQuery() ()函数用于查询指定内存分区
26、中的有关信息,函数用于查询指定内存分区中的有关信息,函数使用了一个新的数据结构函数使用了一个新的数据结构OS_MEM_DATAOS_MEM_DATA来复制来复制OS_MEMOS_MEM结构中的信息,并比结构中的信息,并比OS_MEMOS_MEM多一个成员,其数据结构如程序清多一个成员,其数据结构如程序清单单9.89.8所示。所示。二二调用者调用者:可以是任务,也可以是中断。:可以是任务,也可以是中断。三三配置常量配置常量:OS_MEM_QUERY_ENOS_MEM_QUERY_EN。四四函数参数函数参数1. 1.pmempmem 指向内存控制块的指针,它是调用指向内存控制块的指针,它是调用OSMemCreateOSMemCreate() ()函数建立内存分区时的返回值。函数建立内存分区时的返回值。2.2.ppdatappdata 指向指向OS_MEM_DATAOS_MEM_DATA数据结构的指针,它比数据结构的指针,它比OS_MEMOS_MEM多一个成员。多一个成员。嵌入式实时操作系统嵌入式实时操作系统C/OS-C/OS-教程教程 第九章第九章 内存管理内存管理程序清单程序清单9.8 OS_MEM_DATA9.8 OS_MEM_DATA数据结构
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 姜堰市电梯安全管理人员能力鉴定试卷库以及答案
- 贵州中专考试题库及答案
- 电梯维修考试题库及答案
- 科技行业前沿知识试题
- 制药行业生产质量控制手册
- 智能家居品牌宣传策略与实践操作指导
- 髋外旋偏瘫患者的护理
- 人教版八年级下册8.1 牛顿第一定律第1课时教学设计
- 建立企业内外部品牌传播致性计划
- 主管年度行动计划书
- “燕园元培杯”2023-2024学年全国中学生地球科学奥林匹克竞赛决赛试题详解
- 消防队伍廉洁警示教育
- 总体概述:施工组织总体设想、方案针对性及施工段划分
- 涉密和非涉密计算机保密管理制度
- 2025年吉林司法警官职业学院单招职业倾向性考试题库含答案
- 2025年开封大学单招职业适应性考试题库带答案
- 国际合作与中外合拍片的发展现状
- 2025年河南经贸职业学院单招职业技能测试题库完整版
- 统编版语文二年级下册第三单元 复习课件
- 《excel学习讲义》课件
- 《老挝英文介绍》课件
评论
0/150
提交评论