1实时嵌入式操作系统艾云峰aiyunfeng@gmail.comCollegeofComputing&CommunicationEngineeringReal-timeEmbeddedOperatingSystem2主要内容1.什么是实时嵌入式操作系统的“内存管理”?2.实时嵌入式操作系统的内存管理3.UC/OS-II的内存管理介绍3什么是实时嵌入式操作系统的“内存管理”?嵌入式系统开发模式建立映象文件的过程映象文件的组成映象文件在目标机上的运行内存的管理!!4嵌入式系统开发模式注:参见Real-TimeConceptesforEmbeddedSystems5映象文件的产生6嵌入式映象文件的组成(1)-C程序内存布局正文段这是由CPU执行的机器指令部分初始化数据段通常将此段称为数据段,它包含了程序中赋初值的变量。例如,C程序中任何函数之外的说明:intmaxcount=99;使此变量以初值存放在初始化数据段中非初始化数据段通常将此段称为bss段,在程序开始执行之前,内核将此段初始化为0。函数外的说明:longsum[1000];使此变量存放在非初始化数据段中栈自动变量以及每次函数调用时所需保存的信息都存放在此段中。每次函数调用时,其返回地址、以及调用者的环境信息(例如某些机器寄存器)都存放在栈中。然后,新被调用的函数在栈上为其自动和临时变量分配存储空间堆通常在堆中进行动态存储分配。由于历史上形成的惯例,堆位于非初始化数据段顶和栈底之间7嵌入式映象文件(C)的组成(2).text代码段属性:只读.data初始化的数据段属性:读写.bss未初始化的数据段,内容是空的属性:读写,不占文件大小8映象文件的执行(1)-内存模型9映象文件的执行(2)-直接从ROM上执行设备只有有限的内存资源,程序映象要从ROM直接运行映象此处是必须是bin格式.text开头一小段代码完成.data段和.bss段的自我复制链接器提供符号,指出.data和.bss在映象中的相对起始和终止地址,从而可以完成拷贝工作栈用来传递函数调用期间的函数参数,局部变量10映象文件的执行(3)-装载器把映象从ROM中装载到RAM中运行装载器映象是一个可执行机器码格式可执行映象可以是bin格式;也可以是其它格式,但装载器要抽取必要的信息进行初始化11内存的分配:两个例子静态分配的例子OS_STKTaskStk[N_TASKS][TASK_STK_SIZE];voidmain(void){OSInit();OSTaskCreate();//函数OSStart();}OS_EXTINT8UOSTaskCtr;//全局变量如果动态分配呢?Windows下,动态申请:StructListNode*node;Node=(StructListNode*)malloc(sizeof(StructListNode))实时嵌入式操作系统中呢?提供对于堆的管理;提供类似malloc、free等的函数12主要内容1.什么是实时嵌入式操作系统的“内存管理”?2.实时嵌入式操作系统的内存管理3.UC/OS-II的内存管理介绍13内存管理定义内存管理是操作系统的中心任务之一,内存管理模块通常是操作系统内核的一部分。其主要任务是组织内存以容纳内核和各待执行进程,跟踪当前内存使用状况,在需要时为进程分配内存,其使用完毕后释放并回收内存内存管理主要包括内存分配和回收:根据需要,给系统中的任务分配内存;内存保护:禁止任务访问已分配给其它任务的内存:内存映射:将外设的板上寄存器映射到内存地址空间;内存文件系统:在内存中实现简单的文件系统,形成RAM磁盘。14嵌入式操作系统内存管理的特性(1)实时性从实时性的角度出发,要求内存分配过程要尽可能地快。因此,在嵌入式系统中,不可能采用通用操作系统的一些复杂而完善的内存分配策略,一般没有段页式的虚存管理机制;而是采用简单、快速的内存分配方案,其分配方案也因程序对实时性的要求而异。15嵌入式操作系统内存管理的特性(2)可靠性嵌入式系统应用的环境千变万化,在有些特定情况下,对系统的可靠性要求极高,内存分配的请求必须得到满足,如果分配失败则可能会带来灾难性的后果。比如,飞机的燃油检测系统。在飞机飞行过程中,如果燃料发生泄漏,系统应该立即检测到,并发出相应的警报等待飞行员及时处理。如果因为内存分配失败而不能相应地操作,就可能发生机毁人亡的事故。16嵌入式操作系统内存管理的特性(3)高效性内存分配要尽可能地减少浪费。不可能为了保证满足所有的内存分配请求而将内存配置得很大。一方面,嵌入式系统对成本的要求使得内存在其中只是一种很有限的资源;另一方面,即使不考虑成本的因素,系统硬件环境有限的空间和有限的板面积决定了可配置的内存容量是很有限的。17嵌入式操作系统内存管理策略内存管理策略大致可分为静态分配和动态分配两大类。静态分配的可用内存大小在编译时确定。系统初始化阶段预先分配好固定数量的内存,用于存放所有需使用的对象和数据结构。程序运行过程中能且只能使用这些内存。动态分配的内存在程序运行时根据需要向系统申请后获得,只有在需要的时候.才分配或归还。由于嵌入式系统的特殊性,开发人员必须在编译内核和开发应用时都参与系统的内存管理18静态分配静态内存分配是在系统启动时就将任务需要的所有内存分配给任务.任务在运行过程中不能再要求分配内存。这意味着系统必须给所有的数据结构分配足够的内存来满足应用的最大需求.而且程序员需要在系统开始运行前计算任务的最大内存需求这种方法适用于简单的、内存需求高度可预测的实时嵌入式系统,静态分配尤其适用于实时应用和高安全系统。19静态分配分析-优点静态内存分配在程序执行前进行,效率较高编译时可精确预估系统内存需求状况所有分配动作所需时间固定且很小分配的内存一般不归还外部碎片很少程序易测试,可靠性高20静态分配分析-缺点静态分配必须考虑可能发生的最坏情况,因此往往分配比实际用量更多的内存预先分配内存也增加了系统的启动时间这些均会降低系统的可用性。要求在程序执行前就知道所需的内存类型和数量,显然缺少灵活性。21动态分配动态内存分配是任务在运行时才向系统申请内存块来存放数据和代码及与其它任务进行通信和同步;一旦任务不再需要某块内存.就可以释放它.以供其它任务申请使用这种方法适合于任务的内存需求在执行期间可能会发生变化的系统程序初始化完成后,程序代码、程序数据和系统堆栈占据了一部分物理内存,RTOS或内核典型的使用其余的物理内存进行动态内存分配,此内存区域称为堆22动态分配分析-优点动态内存分配可以节省程序员的设计时间,最主要的是可以大大节省内存,提高内存的利用率避免分配不被使用的内存,降低内存总体需求;改善设计质量,使系统更易编写、扩展和维护:运行时间分配内存减少了系统的启动时间具有灵活性23动态分配分析-缺点动态内存管理需要额外区块头部的开销内存分配和归还需花费处理器时间典型情况和最坏情况下的内存需求难以估计内存耗尽的处理会增加代码的复杂度易造成内存碎片,增加内存的额外开销和不可预测性24动态分配内存带来的问题:内存碎片碎片是动态内存分配、尤其是直接在系统堆中分配的不分区方式的主要问题有两种碎片,一种是数据结构未用完它所分配到的内存块而产生的“内部碎片”,另一种是两个已分配数据块之间的内存由于太小而无法用于存储任何东西造成的“外部碎片”25内存碎片描述26固定尺寸内存池方法(1)一种动态管理内存的方法固定尺寸内存池使用的数据结构控制块:通常内存管理设施维护保留内存区域堆的内部信息,成为控制块(controlblock)。典型的,这些内部信息包括用作内存分配的物理内存块的起始地址用这个物理内存块的全部尺寸分配表,指示已用的内部内存区域、空闲的内存和每个空闲区域的尺寸27固定尺寸内存池方法(2)-内存的组织把可使用的内存空间划分未各种尺寸的内存池,相同内存池中所有内存块具有同样的尺寸内存池按大小排列,链接成一个单链表28固定尺寸内存池方法(3)-分配与释放分配通过查询内存池链表,可以发现满足分配要求的最合适尺寸的内存池,再检查该内存池的控制结构,找到第一个合适的块尺寸一个成功的分配导致从内存池中移走一个项回放把内存块回放到合适的内存池中每次分配或回放都是从列表的开头获得内存块或者返回内存,因此操作是常数时间29固定尺寸内存池方法(4)-分配的策略基本的动态内存分配方法有最先匹配法和最佳匹配法最先匹配法选择第一个大于等于内存分配要求的空闲块。这种方法的内存访问时间短.但内存块会越来越小.为了满足较大的内存分配请求.必须进行内存回收和合并最佳匹配法比较所有满足分配要求的空闲块后将其中最小的块分配出去。这种方法可以满足任务更多的内存需求.但是增加了时间开销,并且长时间运行后.将出现大量很小的空闲块无法重用Knuth研究了最先匹配法和最佳匹配法.在实践中总结出最先匹配法一般会优于最佳匹配法30静态分配与动态分配的比较(1)一般的嵌入式系统都支持静态分配,因为像中断向量表、操作系统映像这类的程序段,其程序大小在编译和链接时是可以确定的。而是否支持动态分配主要基于两个方面的考虑:首先是实时性和可靠性的要求;其次是成本的要求。对于实时性和可靠性要求极高的系统(硬实时系统),不允许延时或者分配失败,必须采用静态内存分配,如航天器上的嵌入式系统多采用静态内存分配。31静态分配与动态分配的比较(2)仅仅采用静态分配,使系统失去了灵活性,必须在设计阶段就预先知道所需要的内存并对之作出分配;必须在设计阶段就预先考虑到所有可能的情况,因为一旦出现没有考虑到的情况,正在运行的系统就无法处理。这样的分配方案必然导致很大的浪费,因为内存分配必须按照最坏情况进行最大的配置,而实际运行时很可能只使用其中的一小部分;而且在硬件平台不变的情况下,不可能灵活地为系统添加功能,从而使得系统的升级变得困难。32静态分配与动态分配的比较(3)虽然动态内存分配会导致响应和执行时间不确定、内存碎片等问题,但是它的实现机制灵活,给程序实现带来极大的方便。33静态分配与动态分配的比较(4)大多数的系统是硬实时和软实时的综合。系统中的一部分任务有严格的时限要求,而另一部分只是要求完成得越快越好按照RMS(RateMonotonousScheduling)理论,这样的系统必须采用抢先式任务调度;而在这样的系统中,就可以采用动态内存分配来满足部分对可靠性和实时性要求不高的任务。采用动态内存分配的最大好处就是给设计者很大的灵活性,可以方便地将原来运行于非嵌入式操作系统的程序移植到嵌入式系统中34内存分配函数的分类永久堵塞内存分配函数时限堵塞内存分配函数永不堵塞内存分配函数35实现阻塞内存分配函数的必要性实现阻塞分配内存函数的必要性许多嵌入式系统中,任务竞争有限的可使用内存,通常内存耗尽只是暂时的现象。对某些任务,如果调用malloc函数内存分配失败(malloc不允许阻塞),该任务则必须重新调用malloc函数申请内存分配,这是耗时的操作。如果,把malloc定义成允许延时分配的函数(即可延时一段时间等待空闲内存的产生),则任务可以选择等待内存变成可用的,而不是整个失败或回溯例子:以太网上网络收发,由于接受任务经常接收突发到达的数据包而使用了大量的内存。发送任务申请内存时可使用堵塞分配函数36堵塞内存分配函数的实现缓冲池空闲块37主要内容1.什么是实时嵌入式操作系统的“内存管理”?2.实时嵌入式操作系统的内存管理3.UC/OS-II的内存管理介绍38UC/OS-II内存管理机制(1)UC/OS-II把连续的大块内存按分区来管理。每个分区中包含有整数个大小相同的内存块在UC/OS-II中可以有多个内存分区。用户的应用程序就可以从不同的内存分区中得到不同大小的内存块特定的内存块在释放时必须重新放回它以前所属于的内存分区39UC/OS-II内存管理机制(2)内存控制块为了便于内存的管理,在UC/OS-II中使用内存控制块的数据结构来跟踪每