嵌入式实时操作系统分析_第1页
嵌入式实时操作系统分析_第2页
嵌入式实时操作系统分析_第3页
嵌入式实时操作系统分析_第4页
嵌入式实时操作系统分析_第5页
已阅读5页,还剩113页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

主要内容嵌入式操作系统C/OS-Ⅱ简介C/OS-Ⅱ内核结构C/OS-Ⅱ任务管理C/OS-Ⅱ时间管理C/OS-Ⅱ任务通信与同步1现在是1页\一共有118页\编辑于星期五为什么需要操作系统2现在是2页\一共有118页\编辑于星期五硬件抽象层的引入

嵌入式实时系统自底向上包含三个部分硬件环境嵌入式实时操作系统——RTOS嵌入式实时应用程序由于嵌入式系统应用的硬件环境差异较大新增加的中间层位于操作系统和硬件之间,包含了系统中与硬件相关的大部分功能,隐蔽了底层硬件的多样性

3现在是3页\一共有118页\编辑于星期五

嵌入式系统的体系结构4现在是4页\一共有118页\编辑于星期五HAL简介硬件抽象层(HAL)是体系结构相关的底层程序处理系统启动、硬件初始化以及中断与异常硬件抽象层对内核其它部分提供统一的调用接口HAL可以提供BSP规范,提供跨平台可移植性

5现在是5页\一共有118页\编辑于星期五硬件抽象层接口定义和代码设计特点

硬件抽象层具有与硬件密切相关性硬件抽象层具有与操作系统无关性接口定义的功能应包含硬件或系统所需硬件支持的所有功能接口定义简单明了,太多接口函数会增加软件模拟的复杂性具有可测性的接口设计有利于系统的软硬件测试和集成6现在是6页\一共有118页\编辑于星期五HAL设计目标支持多种的国际主流嵌入式芯片支持数字电视机顶盒、智能手机、数字化音视频、数字仪表等数字化产品中常见外设的驱动基于甚高端通讯设备的硬件抽象层,能够支持多CPU体系结构(SMP),以及基于网络元素NE的甚高端通讯设备基于智能手机的硬件抽象层,能够支持以IntelPCA体系结构为内核的智能手机、以IntelEIA体系结构为内核的智能手机,以及以Motorola的88000系列为内核的PDA基于IC卡的汇编级硬件抽象层,能够支持数字电视条件接收CA的8/16/32位CPUIC设计和机器码级汇编抽象层7现在是7页\一共有118页\编辑于星期五通用操作系统和嵌入式(实时)操作系统通用操作系统:Windows/NT/XP、Linux、UNIX等,用于PC机、服务器,嵌入式(实时)操作系统:用于嵌入式设备的操作系统,具有通用操作系统的基本特点,又具有系统实时性、硬件的相关依赖性、软件固态化以及应用的专用性等特点;嵌入式(实时)操作系统通常包括与硬件相关的底层驱动软件、系统内核、设备驱动接口、通信协议、图形界面、标准化浏览器Browser等;嵌入式(实时)操作系统的重要指标:实时性(中断响应时间、任务切换时间等)、尺寸(可裁剪性)、可扩展性(内核、中间件)8现在是8页\一共有118页\编辑于星期五嵌入式操作系统的发展操作系统内核应用程序驱动程序和固件操作系统内核文件系统驱动程序和固件APIGUI应用程序操作系统内核文件系统驱动程序和固件APIGUI应用程序通信协议库函数80年代初期80年代中期-90年代中期90年代末期-21世纪9现在是9页\一共有118页\编辑于星期五常见的嵌入式操作系统

实时嵌入式操作系统的种类繁多,大体上可分为两种,商用型和免费型。商用型的实操作系统功能稳定、可靠,有完善的技术支持和售后服务,但往往价格昂贵,如Vxworks、QNX、WinCE、PalmOS等。免费型的实时操作系统在价格方面具有优势,目前主要有Linux,μC/OS是一种源码开放的商业RTOS10现在是10页\一共有118页\编辑于星期五学习嵌入式操作系统

学习一种实时操作系统RTOS,如C/OS-Ⅱ,掌握实时系统的概念和设计方法嵌入式系统以应用为中心,要选择“适用”的操作系统嵌入式Linux自己尝试“写”RTOS11现在是11页\一共有118页\编辑于星期五RTOS在嵌入式系统中的位置嵌入式硬件平台BSPKERNELFSTCP/IP设备驱动设备I/O调试工具其它组件应用RTOSC/C++12现在是12页\一共有118页\编辑于星期五主要内容嵌入式操作系统C/OS-Ⅱ简介C/OS-Ⅱ内核结构C/OS-Ⅱ任务管理C/OS-Ⅱ时间管理C/OS-Ⅱ任务通信与同步13现在是13页\一共有118页\编辑于星期五C/OS简介

1、C/OS——MicroControllerOS,微控制器操作系统2、C/OS简介美国人JeanLabrosse1992年完成应用面覆盖了诸多领域,如照相机、医疗器械、音响设备、发动机控制、高速公路电话系统、自动提款机等1998年C/OS-II,目前的版本C/OS-IIV2.61,2.722000年,得到美国航空管理局(FAA)的认证,可以用于飞行器中网站www.ucos-II.com()14现在是14页\一共有118页\编辑于星期五公开源代码可移植性(Portable)

绝大部分C/OS-II的源码是用移植性很强的ANSIC写的。和微处理器硬件相关的那部分是用汇编语言写的。汇编语言写的部分已经压到最低限度,使得C/OS-II便于移植到其他微处理器上。C/OS-II可以在绝大多数8位、16位、32位以至64位微处理器、微控制器、数字信号处理器(DSP)上运行。可固化(ROMable)

C/OS-II是为嵌入式应用而设计的,这就意味着,只要用户有固化手段(C编译、连接、下载和固化),C/OS-II可以嵌入到用户的产品中成为产品的一部分。可裁剪(Scalable)

可以只使用C/OS-II中应用程序需要的那些系统服务。也就是说某产品可以只使用很少几个C/OS-II调用,而另一个产品则使用了几乎所有C/OS-II的功能,这样可以减少产品中的C/OS-II所需的存储器空间(RAM和ROM)。这种可剪裁性是靠条件编译实现的。C/OS的性能特点(一)15现在是15页\一共有118页\编辑于星期五占先式(Preemptive)多任务

C/OS-II可以管理64个任务,然而,目前这一版本保留8个给系统。应用程序最多可以有56个任务可确定性

全部C/OS-II的函数调用与服务的执行时间具有可确定性。任务栈

每个任务有自己单独的栈,C/OS-II允许每个任务有不同的栈空间,以便压低应用程序对RAM的需求。系统服务

C/OS-II提供很多系统服务,例如邮箱、消息队列、信号量、块大小固定的内存的申请与释放、时间相关函数等。中断管理

中断可以使正在执行的任务暂时挂起,如果优先级更高的任务被该中断唤醒,则高优先级的任务在中断嵌套全部退出后立即执行,中断嵌套层数可达255层。稳定性与可靠性C/OS的性能特点(二)16现在是16页\一共有118页\编辑于星期五µC/OS-II图籍描述了µC/OS-II内部的工作原理随书的CD中包含了源代码工业界最清晰的源代码除英文版外,有中文和韩文版ChineseKoreanEnglishISBN1-57820-103-9美国CMPBOOKISBN7-81077-290-2北京航空航天大学出版社ISBN89-951540-5-517现在是17页\一共有118页\编辑于星期五µC/OS-II的各种商业应用全世界有数百种产品在应用:Avionics(航空电子设备)MedicalCellphonesRoutersandswitchesHigh-endaudioequipmentWashingmachinesanddryersUPS(UninterruptiblePowerSupplies)IndustrialcontrollersGPSNavigationSystemsMicrowaveRadiosInstrumentationPoint-of-saleterminals更多18现在是18页\一共有118页\编辑于星期五µC/OS-II提供的系统服务信号量带互斥机制的信号量减少优先级倒置的问题事件标志消息信箱消息队列内存管理时钟管理任务管理19现在是19页\一共有118页\编辑于星期五主要内容嵌入式操作系统C/OS-Ⅱ简介C/OS-Ⅱ内核结构C/OS-Ⅱ任务管理C/OS-Ⅱ时间管理C/OS-Ⅱ任务通信与同步20现在是20页\一共有118页\编辑于星期五C/OS-II的文件结构21现在是21页\一共有118页\编辑于星期五内核结构任务管理时间管理任务之间通信与同步C/OS的移植C/OS-II分析22现在是22页\一共有118页\编辑于星期五当处理临界段代码时,须关中断,处理完毕后,再开中断关中断时间是实时内核最重要的指标之一。它影响用户系统对实时事件的相应特性。在实际应用中,关中断的时间很大程度上取决于微处理器的结构和编译器生成的代码质量微处理器通常具有关中断/开中断操作。C编译器须具有某种机制,能够在c中直接实现关中断/开中断操作C源代码中插入汇编语言的语句,易实现关中断/开中断操作关中断/开中断操作作为语言的扩展部分,直接从C语言中可以关中断/开中断C/OS-II开关中断的方法23现在是23页\一共有118页\编辑于星期五C/OS-II开关中断的方法(续1)C/OS-II定义了两个宏调用来开关中断:OS_ENTER_CRITICAL()(禁止中断的宏)

OS_EXIT_CRITICAL()(启用中断的宏)通常成对出现上述宏定义取决于使用的微处理器。在文件OS_CPU.H有相应的宏定义在C/OS-II中,每种微处理器都有自己的OS_CPU.H文件24现在是24页\一共有118页\编辑于星期五C/OS-II开关中断的方法(续2){..OS_ENTER_CRITICAL();/*C/OS-II临界段代码*/

OS_EXIT_CRITICAL();..}如果在所有挂起类(PEND)调用之前,如:调用OSTimeDel()(挂起时间)功能函数之前关中断,会出现什么现象?通常,调用C/OS-II功能函数时,中断总应当是开放的。25现在是25页\一共有118页\编辑于星期五C/OS-II开关中断的方法(续3)OS_ENTER_CRITICAL()及OS_EXIT_CRITICAL()可以用3种不同的方法实现具体方法取决于用户打算移植到的处理器的性能及所用的C编译器用定义(#define)常数OS_CRITICAL_METHOD可以选择具体使用哪种方法该常数在与CPU类型有关的移植文件OS_CPU.H中定义

26现在是26页\一共有118页\编辑于星期五OS_CRITICAL_METHOD==1用最简单的方式来实现2个宏调用用处理器指令关中断,完成OS_ENTER_CRITICAL()用开中断指令完成OS_EXIT_CRITICAL()问题:如果调用C/OS-II功能函数时,中断是关掉的,则从C/OS-II函数返回时,中断就打开了若调用C/OS-II功能函数之前已将中断关掉,那么用户往往希望从C/OS-II函数返回时,中断仍然是关着的。这时,这种方法就不妥当。对特定的处理器,这种办法是唯一的选择C/OS-II中采用了3种开关中断的方法27现在是27页\一共有118页\编辑于星期五C/OS-II中采用了3种开关中断的方法(续1)OS_CRITICAL_METHOD==2在堆栈中保存中断的开/关状态,然后再关中断实现OS_ENTER_CRITICAL()时,先在堆栈中保存中断的开/关状态,然后再关中断实现OS_EXIT_CRITICAL()时,从堆栈中弹出原来中断的开/关状态利用这种机制,不论用户在调用C/OS-II功能函数之前中断是开或关,函数的进入和返回状态都得到了保护。即:调用前中断的开/关状态,在调用之后保持不变28现在是28页\一共有118页\编辑于星期五C/OS-II中采用了3种开关中断的方法(续2)OS_CRITICAL_METHOD==3把当前处理器的状态字(PSW)保存在C函数的局部变量中(如OS_CPU_SR)关中断时保存,开中断时恢复29现在是29页\一共有118页\编辑于星期五C/OS-II中采用了3种开关中断的方法(续3)VoidSome_uCOS_II_Service(arguments){OS_CPU_SRcpu_sr;cpu_sr=get_processor_psw();disable_interrupts();/*临界段代码*/set_processor_psw(cpu_sr);}30现在是30页\一共有118页\编辑于星期五任务(task)

典型的任务:一个无限循环voidmytask(void*pdata){for(;;){dosomething;waiting;dosomething;}}31现在是31页\一共有118页\编辑于星期五TaskStructurevoidYourTask(void*pdata) (1){for(;;){ (2)/*用户代码*/

调用uC/OS-II的某种系统服务:OSMboxPend();OSQPend();OSSemPend();OSTaskDel(OS_PRIO_SELF);OSTaskSuspend(OS_PRIO_SELF);OSTimeDly();OSTimeDlyHMSM();/*用户代码*/}}32现在是32页\一共有118页\编辑于星期五

用户应用程序的一般结构“用户任务”代码形式上很像C函数,但他不是函数!“任务”不能被主函数main()或其他函数调用,只能被主函数或已激活任务创建。任务的运行由操作系统调度管理。33现在是33页\一共有118页\编辑于星期五voidMyTask1(void*pdata){……}voidMyTask2(void*pdata){……}voidmain(){……OSInit();……

OSTaskCreate(MyTask1,……);

OSTaskCreate(MyTask2,……);……OSStart();……}34现在是34页\一共有118页\编辑于星期五OSTaskCreate()函数原型:

INT8UOSTaskCreate( void(*task)(void*pd),

//指向任务的指针

void*pdata,

//传递给任务的参数

OS_STK*ptos,

//任务堆栈栈顶的指针

INT8Uprio

//任务的优先级别

)35现在是35页\一共有118页\编辑于星期五OSTaskCreate()函数使用举例:定义任务task_Avoidtask_A(void*pdata){……;

//任务初始化部分while(1){……;//任务功能代码}}在系统“创建”任务task_Avoidmain(void){OSInit();//系统初始化部分

……

OSTaskCreate(task_A,void*0,&MystackTop,8);OSStart();}36现在是36页\一共有118页\编辑于星期五任务的基本概念系统任务空闲任务(OSTaskIdel())统计任务(OSTaskStat())原型:voidOSTaskIdel(void*pdata)原型:voidOSTaskStat(void*pdata)37现在是37页\一共有118页\编辑于星期五空闲任务(OSTaskIdel())使用说明:1、uC/OS-II规定用户程序中必须使用OSTaskIdel。2、该任务不能用软件删除。3、该任务是uC/OS-II初始化时自动创建,其任务优先 级固定为最低级,用户也可修改该任务的业务。4、目的----使CPU在没有用户任务可执行时也有事可 做。38现在是38页\一共有118页\编辑于星期五统计任务(OSTaskStat())使用说明:1、功能完成用户任务CPU使用率的统计,结果以百分 比的形式存放在变量OSCPUsage中。2、该任务用户可选择使用。OS_CFG.H文件中的常数 OS_TASK_STAT_EN设置为1,使能该函数。3、用户在OS_CFG.H中使能该任务后,系统自动创建 该任务,但在用户使用统计数据前必须调用系统 函数OSStatInit()先进行初始化。4、该任务固定拥有次末任务优先级。39现在是39页\一共有118页\编辑于星期五任务的优先权和优先级别uC/OS-II的每个任务都必须有唯一的优先级。uC/OS-II最多可以管理64个优先级别分配给64个任务。uC/OS-II中用一个8b的整型数来表示优先级别,数字越小,优先级越高,prio=0的任务优先级最高。uC/OS-II中使用任务的优先级(prio)作为任务句柄。用户通过修改OS_CFG.H中的宏定义常数OS_LOWEST_PRIO的值,约定本用户系统的最大优先级数。40现在是40页\一共有118页\编辑于星期五任务堆栈堆栈----FIFO访问原则组织的连续存储器。任务堆栈在uC/OS-II中的应用:任务堆栈是任务的三大组成部分之一。保存CPU寄存器现场(R0~R12、LR、SPSR等)。本Task的私有数据。41现在是41页\一共有118页\编辑于星期五任务堆栈的创建-----在创建任务的同时,任务堆栈即被创建。举例:#defineMyTaskStkSize64OS_STKMyTaskStk[MyTaskStkSize]//在OS_CPU.H中定义OS_STK…… //typedefINT32UOS_STKINT8UOSTaskCreate( void(*task)(void*pd),//指向任务的指针 void*pdata, //传递给任务的参数

MyTaskStk[MyTaskStkSize-1]

//任务堆栈栈顶的指针 INT8Uprio //任务的优先级别 )42现在是42页\一共有118页\编辑于星期五任务堆栈的使用注意事项__存在两种堆栈形式递增堆栈----进栈操作向大地址方向发展。递减堆栈----进栈操作向小地址方向发展。OSTaskCreate( ……

&MyTaskStk[StkSize-1], …… )OSTaskCreate( ……

&MyTaskStk[0], …… )备注:利用条件编译技术和OS_CPU.H中的宏定义常数OS_STK_GROWTH编写易移植用户系统;“1”---递减堆栈forARMCPU。43现在是43页\一共有118页\编辑于星期五任务完成后的自我删除当任务完成后,任务可以自我删除任务代码并非真的删除了,系统只是简单地不再理会这个任务这个任务的代码也不会再运行了,即使任务调用了OSTaskDel(),这个任务也绝不会返回voidYourTask(void*pdata){/*用户代码*/OSTaskDel(OS_PRIO_SELF);}44现在是44页\一共有118页\编辑于星期五任务状态在任一给定的时刻,任务的状态一定是以下五种状态之一:睡眠态(taskdormant)就绪态(taskready)运行态(taskrunning)等待状态(taskwaiting)中断服务态(ISRrunning)45现在是45页\一共有118页\编辑于星期五睡眠态(taskdormant)指任务驻留在程序空间(ROM或RAM),还没有交给系统来管理的状态任务交给系统通过调用以下函数之一来实现:OSTaskCreate()OSTaskCreateExt()告知系统:任务的起始地址任务建立时,用户给任务赋予的优先级任务要使用的栈空间大小等46现在是46页\一共有118页\编辑于星期五就绪态(taskready)任务一旦创建就进入就绪态,准备运行任务的创建可以是在多任务开始之前,也可以动态地由一个运行着的任务创建若刚创建任务的优先级高于创建它的任务的优先级,它将立即获得cpu的使用权任务可通过OSTaskDel()返回睡眠态;或调用该函数让另一个任务进入睡眠态47现在是47页\一共有118页\编辑于星期五运行态(taskrunning)就绪的任务只有当所有优先级高于它的任务都转为等待状态,或被删除后,才能进入运行态任何时刻只有一个任务处于运行态调用OSStart()可以启动多任务。该函数只能在启动时调用一次OSStart()运行用户初始化代码中已经建立的、进入就绪态的优先级最高的任务48现在是48页\一共有118页\编辑于星期五等待状态(taskwaiting)正在运行的任务可以通过下面的调用进入等待状态。延迟时间到,立即强制执行任务切换,让下一个优先级最高、并进入就绪态的任务执行。OSTimeDly()OSTimeDlyHMSM()等待时间过去后,系统服务(内部)函数OSTimeTick()使延迟了的任务进入就绪态用户无需在应用程序代码中调用这个函数49现在是49页\一共有118页\编辑于星期五等待状态(续)正在运行的任务可能需要通过调用函数等待某一事件发生。如果该事件并未发生,任务就进入等待状态OSFlagPend();OSMutexPend()OSSemPend();OSMboxPend()当事件发生或等待超时,被挂起的任务就进入就绪态50现在是50页\一共有118页\编辑于星期五中断服务态(ISRrunning)正在执行的任务是可以被中断的,除非该任务将中断关闭,或系统将中断关闭。被中断的任务便进入了中断服务态响应中断后,正在运行的任务被挂起,中断服务子程序控制了CPU的使用权51现在是51页\一共有118页\编辑于星期五中断服务态(ISRrunning)中断服务子程序可能会报告一个或多个事件的发生,而使一个或多个任务进入就绪态上述情况下,从中断服务子程序返回之前,C/OS–II

要判定:被中断的任务是否还是就绪态任务中优先级最高的如果中断服务子程序使另一个优先级更高的任务进入了就绪态,则新进入就绪态的这个优先级更高的任务将得以运行;否则,原来被中断了的任务将继续运行。52现在是52页\一共有118页\编辑于星期五任务状态当所有的任务都在等待时间发生或等待延迟时间结束时,C/OS–II执行被称为空闲任务(IdleTask)的内部函数,即:OSTaskIdle()53现在是53页\一共有118页\编辑于星期五任务状态任务的CPU使用权被剥夺中断恢复任务54现在是54页\一共有118页\编辑于星期五任务控制块(TCB)任务控制块OS_TCB是一个数据结构,保存该任务的相关参数,包括任务堆栈指针、状态、优先级、任务表位置、任务链表指针等所有的任务控制块分为两条链表:空闲链表使用链表当任务的CPU使用权被剥夺时,系统用它来保存该任务的状态全部驻留在RAM中空任务控制块链表----未被分配的TCB链OSTCBFreeList。任务控制块链表----已分配的TCB链OSTCBList。55现在是55页\一共有118页\编辑于星期五

µC/OS-II任务控制块.typedefstructos_tcb{OS_STK*OSTCBStkPtr(当前任务堆栈栈顶指针);#ifOS_TASK_CREATE_EXT_EN>0void*OSTCBExtPtr;(指向用户定义的任务控制块扩展)

OS_STK*OSTCBStkBottom;(指向任务堆栈栈底指针)INT32UOSTCBStkSize;(存有栈中可容纳的指针元数目)INT16UOSTCBOpt;INT16UOSTCBId;(存储任务的识别码ID,备用)#endifstructos_tcb*OSTCBNext;(任务控制块OS-TCB双向链表的后链接)structos_tcb*OSTCBPrev;(任务控制块OS-TCB双向链表的前链接)#if(OS_Q_EN&&(OS_MAX_QS>=2))||OS_MBOX_EN||OS_SEM_ENOS_EVENT*OSTCBEventPtr;(指向事件控制块的指针)#endif56现在是56页\一共有118页\编辑于星期五#if(OS_Q_EN&&(OS_MAX_QS>=2))||OS_MBOX_ENvoid*OSTCBMsg;(指向传递给任务的消息的指针)#endifINT16UOSTCBDly;INT8UOSTCBStat;(任务的状态字)INT8UOSTCBPrio;(任务的优先级)INT8UOSTCBX;INT8UOSTCBY;INT8UOSTCBBitX;INT8UOSTCBBitY;#ifOS_TASK_DEL_ENBOOLEANOSTCBDelReq;#endif}OS_TCB;57现在是57页\一共有118页\编辑于星期五任务控制块及任务控制块链表任务控制块链表空任务块链表是在uC/OS-II初始化(OSInit())时系统自建的,用户可依据目标系统的实际需求,设定其链表长度。OS_CFG.H文件中的宏常数OS_MAX_TASKS----用于定义最大用户任务数。UCOS_II.H文件中的宏常数OS_N_SYS_TASKS----用于约定系统任务数,其值固定为2。当应用程序调用函数OSTaskCreate()创建一个任务时,这个函数会调用系统函数OSTCBInit()来为任务控制块进行初始化。这个函数首先为被创建任务从空任务控制块链表获取一个任务控制块,然后用任务的属性对任务控制块各个成员进行赋值,最后再把这个任务控制块链入到任务控制块链表的头部。当进行系统初始化时,初始化函数会按用户提供的任务数为系统创建具有相应数量的任务控制块并把它们链接为一个链表。由于这些任务控制块还没有对应的任务,故这个链表叫做空任务块链表。即相当于是一些空白的身份证。58现在是58页\一共有118页\编辑于星期五空任务列表所有的任务控制块都被放置在任务控制块列表数组OSTCBTbl[]中系统初始化时,所有任务控制块被链接成空任务控制块的单向链表任务建立后,空任务控制块指针OSTCBFreeList指向的任务控制块就赋给了该任务,然后OSTCBFreeList的值调整为指向链表中的下一个空任务控制块任务一旦被删除,任务控制块就还给空任务链表59现在是59页\一共有118页\编辑于星期五uC/OS-II中提供了系统函数OSTaskDel(),用于删除一个任务----实质就是将该任务的TCB从“任务控制块列表”移到了“空任务控制块列表”。任务控制块及任务控制块链表《任务控制块》就相当于是一个任务的身份证,没有任务控制块的任务是不能被系统承认和管理。

任务控制块链表60现在是60页\一共有118页\编辑于星期五61现在是61页\一共有118页\编辑于星期五任务控制块及任务控制块链表任务控制块链表其他相关系统管理变量OSTCBPrioTbl[]:OS_TCB*数据类型的数组,以Prio为下标存放已使能的TCB指针。用于加速TCB的访问。OSTCBCur:全局系统变量,指向当前正在运行的任务的TCB。OSTCBFreeList、OSTCBListOSTCBTbl[]----OSInit()建立的任务控制块数组OSTCBPrioTbl[]----任务控制块优先级数组OSTCBCur62现在是62页\一共有118页\编辑于星期五任务控制块链表空任务控制块链表63现在是63页\一共有118页\编辑于星期五任务级的任务调度--OSSchedC/OS是占先式实时多任务内核,优先级最高的任务一旦准备就绪,则拥有CPU的所有权即开始投入运行。C/OS中不支持时间片轮转法,每个任务的优先级要求不一样且是唯一的。因此,任务调度就是:查找准备就绪的最高优先级的任务并进行上下文切换。C/OS任务调度所花的时间为常数,与应用程序中建立的任务数无关。64现在是64页\一共有118页\编辑于星期五就绪表根据就绪表确定最高优先级两个关键:优先级数分解为高三位和低三位分别确定高优先级有着小的优先级号

65现在是65页\一共有118页\编辑于星期五根据优先级找到任务在就绪任务表中的位置每个就绪的任务都放入就绪表中(readylist)中,就绪表用两个变量表示:OSRdyGrp、OSRdyTbl[]OSRdyGrp1207654300XXXYYY任务优先级2017654310891514131211181617232221201926242531302928273432333938373635424041474645444350484955545352515856576362616059[0][1][2][3][4][5][6][7]OSRdyTbl[7]XY优先级最低任务(空闲任务)优先级最高任务任务优先级号0000110000101001122166现在是66页\一共有118页\编辑于星期五采用查表法确定高优先级任务

查表法具有确定的时间,增加了系统的可预测性,C/OS–II中所有的系统调用时间都是确定的High3=OSUnMapTbl[OSRdyGrp];Low3=OSUnMapTbl[OSRdyTbl[High3]];Prio=(High3<<3)+Low3;OSRdyGrp1207654300XXXYYY任务优先级2017654310891514131211181617232221201926242531302928273432333938373635424041474645444350484955545352515856576362616059[0][1][2][3][4][5][6][7]OSRdyTbl[7]XY67现在是67页\一共有118页\编辑于星期五TaskschedulervoidOSSched(void){INT8Uy;OS_ENTER_CRITICAL();(禁止中断的宏)

if((OSLockNesting=0)&&(OSIntNesting=0))(如果调用来自中断服务程序,或者至少调用了一次给任务调度上锁函数,任务调度函数将退出,不做调度){ y=OSUnMapTbl[OSRdyGrp];(否则,调度找出进入就绪态且优先级最高的任务,就绪任务表相应的位置位) OSPrioHighRdy=(INT8U)((y<<3)+OSUnMapTbl[OSRdyTbl[y]])if(OSPrioHighRdy!=OSPrioCur){(优先级最高的任务是否是当前正在运行的任务,若是不调度) OSTCBHighRdy=OSTCBPrioTbl[OSPrioHighRdy];(若不是,为了实现任务切换,指向优先级最高的任务控制块) OSCtxSwCtr++;(统计计数,跟踪任务切换次数)

OS_TASK_SW();(任务切换)

}}OS_EXIT_CRITICAL();(开放中断的宏)

}68现在是68页\一共有118页\编辑于星期五voidOSSchedLock(void){if(OSRunning==TRUE){OS_ENTER_CRITICAL();if(OSLockNesting<255){OSLockNesting++;}OS_EXIT_CRITICAL();}}给调度器上锁69现在是69页\一共有118页\编辑于星期五给调度器开锁voidOSSchedUnlock(void){if(OSRunning==TRUE){OS_ENTER_CRITICAL();if(OSLockNesting>0){OSLockNesting--;if((OSLockNesting==0)&&(OSIntNesting==0)){OS_EXIT_CRITICAL();OSSched(); }else{OS_EXIT_CRITICAL();}}else{OS_EXIT_CRITICAL();}}}70现在是70页\一共有118页\编辑于星期五任务切换将被挂起的任务寄存器入栈将较高优先级任务的寄存器出栈71现在是71页\一共有118页\编辑于星期五任务级的任务切换OS_TASK_SW()OS_TASK_SW()是宏调用,含有微处理器的软中断指令。因为,系统假定任务切换是靠中断级代码完成的。OS_TASK_SW()将处理器相关的软件中断机制封装起来,便于操作系统移植72现在是72页\一共有118页\编辑于星期五调用OS_TASK_SW()前的数据结构低优先级任务OS_TCBOSTCBCur(1)存贮器低地址存贮器高地址堆栈方向SPR1R2R3R4PCPSW存贮器低地址存贮器高地址高优先级任务(切换后运行的任务)OS_TCBOSTCBHighRdy(3)(2)CPU(4)(5)PSWPCR1R2R3R4即将被挂起任务的栈顶(即将被挂起任务)指向即将运行的任务的栈顶73现在是73页\一共有118页\编辑于星期五保存当前CPU寄存器的值低优先级任务OS_TCBOSTCBCurPSWPCR1R2R3R4存贮器低地址存贮器高地址堆栈方向SPR1R2R3R4PCPSWPSWPCR1R2R3R4存贮器低地址存贮器高地址高优先级任务OS_TCBOSTCBHighRdy(2)CPU(1)(3)(3)74现在是74页\一共有118页\编辑于星期五重新装入要运行的任务低优先级任务OS_TCBOSTCBCurPSWPCR1R2R3R4存贮器低地址存贮器高地址堆栈方向SPR1R2R3R4PCPSWPSWPCR1R2R3R4存贮器低地址存贮器高地址高优先级任务OS_TCBOSTCBHighRdyOSTCBCur(1)(2)CPU(4)(4)(1)(3)(3)(4)复制75现在是75页\一共有118页\编辑于星期五任务切换OS_TASK_SW()的代码VoidOSCtxSw(void){将R1,R2,R3及R4推入当前堆栈;OSTCBCurOSTCBStkPtr=SP;OSTCBCur=OSTCBHighRdy;SP=OSTCBHighRdyOSTCBSTKPtr;将R4,R3,R2及R1从新堆栈中弹出;执行中断返回指令;}76现在是76页\一共有118页\编辑于星期五C/OS-II中的中断中断:由于某种事件的发生,而导致程序流程的改变。产生中断的事件称为中断源。CPU响应中断的条件:至少有一个中断源向CPU发出中断信号;系统允许中断,且对此中断信号未予屏蔽中断类型:硬件中断外部中断陷井中断现场控制量的中断77现在是77页\一共有118页\编辑于星期五C/OS-II中的中断服务子程序用户中断服务子程序:保存全部CPU寄存器;调用OSIntEnter()或OSIntNesting直接加1;if(OSIntNesting==1){OSTCBCur->OSTCBStkPtr=SP;}清中断源;重新开中断;执行用户代码做中断服务;调用OSIntExit();恢复所有CPU寄存器;执行中断返回指令;78现在是78页\一共有118页\编辑于星期五中断服务79现在是79页\一共有118页\编辑于星期五80现在是80页\一共有118页\编辑于星期五Searchforhighestpriority–similartoschedulerHalfcontextswitchisdonebyinterruptresponse–i.e.registerssaved81现在是81页\一共有118页\编辑于星期五中断与时钟节拍时钟节拍(时钟滴答)Tick,是一种定时器中断,可通过编程方式实现时钟节拍是一种特殊的中断,操作系统的心脏。首先32位的整数OSTime加一。对任务列表进行扫描,判断是否有延时任务应该处于准备就绪状态,最后进行上下文切换。82现在是82页\一共有118页\编辑于星期五时钟节拍中断服务子程序VoidOSTickISR(void){保存处理器寄存器的值;调用OSIntEnter(),或是将OSIntNesting加1if(OSIntNesting==1){OSTCBCur->OSTCBStkPtr=SP;}调用OSTimeTick();发出中断设备的中断;重新允许中断(可选用)调用OSIntExit();恢复处理器寄存器的值;执行中断返回指令;}83现在是83页\一共有118页\编辑于星期五voidOSTimeTick(void){OS_TCB*ptcb;OSTimeTickHook(); (1)ptcb=OSTCBList; (2)while(ptcb->OSTCBPrio!=OS_IDLE_PRIO){ (3)OS_ENTER_CRITICAL();if(ptcb->OSTCBDly!=0){if(--ptcb->OSTCBDly==0){if(!(ptcb->OSTCBStat&OS_STAT_SUSPEND)){ (4)OSRdyGrp|=ptcb->OSTCBBitY; (5)OSRdyTbl[ptcb->OSTCBY]|=ptcb->OSTCBBitX;}else{ptcb->OSTCBDly=1;}}}ptcb=ptcb->OSTCBNext;OS_EXIT_CRITICAL();}OS_ENTER_CRITICAL(); (6)OSTime++; (7)OS_EXIT_CRITICAL();}时钟节拍函数OSTimeTick()84现在是84页\一共有118页\编辑于星期五系统总要建立一个空闲任务,该任务在没有其它任务进入就绪状态时投入运行空闲任务永远设为最低优先级空闲任务不可能被应用软件删除voidOSTaskIdle(void*pdata){pdata=pdata;for(;;){OS_ENTER_CRITICAL();OSIdleCtr++;OS_EXIT_CRITICAL();}}空闲任务OSTaskIdle()85现在是85页\一共有118页\编辑于星期五C/OS-II初始化首先调用系统初始化函数OSIint()。OSIint()初始化μC/OS-Ⅱ所有的变量和数据结构(见OS_CORE.C)。OSInit()建立空闲任务idletask,这个任务总是处于就绪态的。空闲任务OSTaskIdle()的优先级总是设成最低,即OS_LOWEST_PRIO。如果统计任务允许OS_TASK_STAT_EN和任务建立扩展允许都设为1,则OSInit()还得建立统计任务OSTaskStat()并且让其进入就绪态。OSTaskStat的优先级总是设为OS_LOWEST_PRIO-1空闲和统计任务的任务控制块(OS_TCBs)是用双向链表链接在一起的。OSTCBList指向这个链表的起始处。当建立一个任务时,这个任务总是被放在这个链表的起始处。86现在是86页\一共有118页\编辑于星期五调用OSInit()之后的数据结构

87现在是87页\一共有118页\编辑于星期五空闲缓冲区88现在是88页\一共有118页\编辑于星期五μC/OS-Ⅱ的启动voidmain(void){OSInit();/*初始化uC/OS-II*/..通过调用OSTaskCreate()或OSTaskCreateExt()创建至少一个任务;..OSStart();/*开始多任务调度!OSStart()永远不会返回*/}89现在是89页\一共有118页\编辑于星期五启动多任务voidOSStart(void){INT8Uy;INT8Ux;if(OSRunning==FALSE){y=OSUnMapTbl[OSRdyGrp];x=OSUnMapTbl[OSRdyTbl[y]];OSPrioHighRdy=(INT8U)((y<<3)+x);OSPrioCur=OSPrioHighRdy;OSTCBHighRdy=OSTCBPrioTbl[OSPrioHighRdy]; OSTCBCur=OSTCBHighRdy;OSStartHighRdy(); }}90现在是90页\一共有118页\编辑于星期五关于OSStartHighRdy

voidOSStartHighRdy(void){调用用户定义的OSTaskSwHook();OSRunning=TRUE;得到将要恢复运行任务的堆栈指针:Stackpointer=OSTCBHighRdyOSTCBStkPtr从新任务堆栈中恢复处理器的所有寄存器;执行中断返回指令;}91现在是91页\一共有118页\编辑于星期五调用OSStart()之后的数据结构

92现在是92页\一共有118页\编辑于星期五主要内容嵌入式操作系统C/OS-Ⅱ简介C/OS-Ⅱ内核结构C/OS-Ⅱ任务管理C/OS-Ⅱ时间管理C/OS-Ⅱ任务通信与同步93现在是93页\一共有118页\编辑于星期五建立任务UseoneoftwoservicesOSTaskCreate()OSTaskCreateExt()94现在是94页\一共有118页\编辑于星期五建立任务,OSTaskCreate()INT8UOSTaskCreate(void(*task)(void*pd),void*pdata,OS_STK*ptos,INT8Uprio){void*psp;INT8Uerr;if(prio>OS_LOWEST_PRIO){(1)return(OS_PRIO_INVALID);}OS_ENTER_CRITICAL();if(OSTCBPrioTbl[prio]==(OS_TCB*)0){ (2)OSTCBPrioTbl[prio]=(OS_TCB*)1;(3)OS_EXIT_CRITICAL();(4)psp=(void*)OSTaskStkInit(task,pdata,ptos,0);err=OSTCBInit(prio,psp,(void*)0,0,0,(void*)0,0);if(err==OS_NO_ERR){ OS_ENTER_CRITICAL();95现在是95页\一共有118页\编辑于星期五OSTaskCtr++; OSTaskCreateHook(OSTCBPrioTbl[prio]); OS_EXIT_CRITICAL();if(OSRunning){ OSSched(); }}else{OS_ENTER_CRITICAL();OSTCBPrioTbl[prio]=(OS_TCB*)0; OS_EXIT_CRITICAL();}return(err);}else{OS_EXIT_CRITICAL();return(OS_PRIO_EXIST);}}96现在是96页\一共有118页\编辑于星期五堆栈检验,OSTaskStkChk()删除任务,OSTaskDel()请求删除任务,OSTaskDelReq()改变任务的优先级,OSTaskChangePrio()挂起任务,OSTaskSuspend()恢复任务,OSTaskResume()其它相关函数97现在是97页\一共有118页\编辑于星期五主要内容嵌入式操作系统C/OS-Ⅱ简介C/OS-Ⅱ内核结构C/OS-Ⅱ任务管理C/OS-Ⅱ时间管理C/OS-Ⅱ任务通信与同步98现在是98页\一共有118页\编辑于星期五时间管理Fiveservices:OSTimeDLY()OSTimeDLYHMSM()OSTimeDlyResmue()OStimeGet()OSTimeSet()99现在是99页\一共有118页\编辑于星期五OSTimeDly()voidOSTimeDly(INT16Uticks){if(ticks>0){OS_ENTER_CRITICAL();if((OSRdyTbl[OSTCBCur->OSTCBY]&=~OSTCBCur->OSTCBBitX)==0){OSRdyGrp&=~OSTCBCur->OSTCBBitY;}OSTCBCur->OSTCBDly=ticks;OS_EXIT_CRITICAL();OSSched();}}100现在是100页\一共有118页\编辑于星期五OSTimeDlyHMSM()101现在是101页\一共有118页\编辑于星期五主要内容嵌入式操作系统C/OS-Ⅱ简介C/OS-Ⅱ内核结构C/OS-Ⅱ任务管理C/OS-Ⅱ时间管理C/OS-Ⅱ任务通信与同步102现在是102页\一共有118页\编辑于星期五任务间通信手段C/OS中,采用多种方法保护任务之间的共享数据和提供任务之间的通信。提供OS_ENTER_CRITICAL和OS_EXIT_CRITICAL来对临界资源进行保护OSSchedLock()禁止调度保护任务级的共享资源。提供了经典操作系统任务间通信方法:信号量、邮箱、消息队列,事件标志。103现在是103页\一共有118页\编辑于星期五事件控制块ECB

程序4.5ECB的结构如下---------------------------------------------------------------------typedefstruct{void*OSEventPtr;/*指向

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论