




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
嵌入式实时操作系统
μC/OS-II讲座北华大学任哲2006广州为什么要学习μC/OS-II一.凡从事嵌入式系统开发工作的人,必须对嵌入式操作系统有足够的了解。二.对于初学者,从μC/OS-II开始是个明智的选择。1.μC/OS-II麻雀虽小,却五脏基本全(它是个微内核)。2.可以学习实时系统的一些编程技巧。3.可以把在学校中学到的操作系统抽象概念具体化。4.具有很强的实用性。5.学习数据结构应用的好例子。讲座的主要内容一.计算机操作系统的基本概念二.操作系统中常用的数据结构三.并发操作系统的概念四.任务的要素五.μC/OS-II的任务管理(任务调度)六.μC/OS-II的中断和时钟七.μC/OS-II的任务的同步与通信八.μC/OS-II的存储管理九.硬件抽象层和测试台操作系统是一种为应用程序提供服务的系统软件,是一个完整计算机系统的有机组成部分。从层次来看,操作系统位于计算机硬件之上,应用软件之下。所以也把它叫做应用软件的运行平台。什么是计算机操作系统(OperatingSystem,OS)它在计算机应用程序与计算机硬件系统之间,屏蔽了计算机硬件工作的一些细节,并对系统中的资源进行有效的管理。通过提供函数(应用程序接口(API)),从而使应用程序的设计人员得以在一个友好的平台上进行应用程序的设计和开发,大大地提高了应用程序的开发效率。计算机操作系统的作用从用户的角度来看,它就是一大堆函数(API和系统函数),用户可以调用(普通调用或系统调用)它们来对系统资源进行操作。计算机硬件用汇编语言编写的硬件抽象层高级语言的接口应用软件操作系统操作系统计算机操作系统的功能处理器的管理存储管理网络和通信的管理I/O设备管理文件管理任务管理任务表存储分配表文件目录设备表总之,需要一大堆表操作系统中经常使用的数据结构(数组)数组1。同一数据类型数据的集合;2。占用连续内存空间;3。其中的所有元素名称都相同,但每个元素都有一个编号;4。元素名去掉编号(下标),得到的是数组名,数组名是个指针。inta[10]a[0]a[1]a[2]a[3]a[9]aa+1使用上的特点:1。分类存放;2。检索速度快且恒定;3。缺点:占用连续空间大……a+2a+3a+9应用:记录同类事物的表操作系统中经常使用的数据结构(位图)位图是数组的一种特殊应用a[10](可以记录80个事物的状态)a[0]a[1]a[2]a[3]a[9]aa+1……a+2a+3a+9应用:登记表1/0D7D6D5D4D3D2D1D0操作系统中经常使用的数据结构(结构)1。不同数据类型数据的集合;2。占用连续内存空间;structStudent{intage;char*name;charsex;};使用上的特点:1。不分类存放,但用来描述同一事物;2。检索速度快且恒定;应用:通讯录中的一条记录、工具箱、厨房等等nextnext两个元素的链表操作系统中经常使用的数据结构(链表)structStudent{Student*nextintage;char*name;charsex;};1。同数据类型数据的集合;2。不占用连续内存空间。使用上的特点:1。分类存放,但空间上不连续(不需要大量的连续存储空间);2。检索速度慢,且耗费的时间不固定;应用:存放大量的较大的表,类似档案柜操作系统中经经常使用的数据结构((队列)按照先进先出的规则组织的的数据结构可以用数组也可以用链表来实现主要用于对象象的排队操作系统中经经常使用的数据结构((堆栈)按照先进后出规则组织的数数据结构主要用数组来来实现主要用于程序模块的嵌嵌套运行什么是多任务务系统简单地说,就就是能用一个个处理器并发(注意,,不是同时!!)地运行多个程程序的计算机机管理系统。。并发:由同一个处理理器轮换地运行多个程序序。或者说是是由多个程序轮班地占占用处理器这这个资源。且在占用这个个资源期间,,并不一定能够把程序序运行完毕。。并发过程示意图处理器如何进进行程序的切换?程序的切换((两句话)处理器是个傻傻瓜,PC让它干啥,它它就干啥。PC是个指路器,,它指向哪儿,处理器就就去哪儿。从此可以知道道,哪个程序序占有了PC,哪个程序就就占有了处理理器。
=PC深刻地理解PC是理解系统进行程序切换换动作的关键键。所谓切换就是:PC目标地址如何操作PC指令:不同的计算机机类型的指令令是不同的。。数据传送指令令子程序返回指指令(由堆栈弹出)中断服务程序序返回指令(由堆栈弹出)小结系统是通过把把待运行程序序的地址赋予予程序计数器器PC来实现程序的的切换的。任务代码任务堆栈内存处理器PCSP任务运行时与与处理器之间的的关系处理器通过两两个指针寄存存器(PC和和SP)来与与任务代码和和任务堆栈建建立联系并运运行它寄存器组程序运行环境运行环境包括括了两部分::处理器中的的运行环境和和内存中的运运行环境任务代码任务堆栈内存处理器PCSP多任务时的问问题任务代码任务堆栈内存任务代码任务堆栈内存?当有多个任务务时,处理器器中的运行环环境应该怎么么办?寄存器组程序运行环境境程序虚拟处理器PCSP虚拟处理器PCSP虚拟处理器PCSP虚拟处理器PCSP调度器多任务时任务务与处理器之之间关系的的处理程序处理器PCSP在内存中为每每个任务创建建一个虚拟的的处理器(处处理器部分的的运行环境由操作系统的的调度器按某种规则来来进行这两个个复制工作复制当需要运行某个任务时就把该任务的虚拟处理器复制到实际处理器中复制当需要中止当前任务时,则把任务对应的虚拟处理器复制到内存复制再把另一个需要运行的任务的虚拟处理器复制到实际处理器中寄存器组寄存器组也就是说,任任务的切换是是任务运行环境的切切换虚拟处理器虚拟处理器应应该存储的主主要信息:1。程序的断断点地址(PC)2。任务堆栈栈指针(SP)3。程序状态态字寄存器((PSW)4。通用寄存存器内容5。函数调用用信息(已存存在于堆栈))另外再用一个个数据结构保保存任务堆栈栈指针(SP)),这个数据据结构叫做任任务控制块,它除除了保存任务务堆栈指针之之外还要负责保保存任务其他他信息。这些内容通常常保存在任务务堆栈中,这这些内容也常常叫做任务的的上下文。任务控制块是是由操作系统统另行构造的的一个数据结结构,每个任任务都有一个个。任务控制块结结构的主要成成员typedefstructos_tcb{OS_STK*OSTCBStkPtr;//指向任务务堆栈栈顶的的指针……INT8UOSTCBStat;//任务的当当前状态标志志INT8UOSTCBPrio;//任任务的的优先先级别别……}OS_TCB;任务代码任务堆栈内存任务控制块其实,,程序序切换换的关关键是是把程序序的私有堆堆栈指指针赋予处理理器的的堆栈栈指针针SP实质上上系统统是通通过SP的的切换换来实现现程序序的切切换的的。要建立立一个个概念念:具具有控制块块的程程序才才是一一个可以被被系统统所运运行的的任务务。程序代代码、、私有有堆栈栈、任任务控制制块是任务务的三三要件件。任务控控制块块提供供了运运行环环境的存存储位位置。。任务的的基本本概念念把一个个大型型任务务分解解成多多个小小任务务,然然后在在计算算机中中通过过运行行这些些小任任务,,最终终达到到完成成大任任务的的目的的。在μC/OS-II中,,与上上述那那些小小任务务对应应的程程序实实体就就叫做做“任任务””(实实质上上是一一个线线程)),μC/OS-II就是是一个个能对对这些些小任任务的的运行行进行行管理理和调调度的的多任任务操操作系系统。。从应用用程序序设计计的角角度来来看,,μC/OS-II的任任务就就是一一个用用户编编写的的C函函数和和与之之相关关联的的一些些数据据结构构而构构成的的一个个实体体。任务代码任务堆栈内存在内存中应该存有任务的代码和与该任务配套的堆栈任务切切换过过程获得待待运行行任务务的任任务控控制块块恢复待运行任务的运行环境处理器的PC=任务堆栈中的断点地址处理器的SP=任务块中保存的SP如何获获得待待运行行任务务的任任务控控制块块?小结一个完完整的的任务务应该该有如如下三三部分分:任务代代码((程序序)任务的的私有有堆栈栈(用用以保保护运运行环环境))任务控控制块块(提供供私有有堆栈栈也是是虚拟拟处理理器的的位置置)这些都都是任任务方方应该该提供供的基基本信信息。。μC/OS-II中的任务管管理任务的的状态态及其其转换换正在运运行的的任务务,需需要等等待一一段时时间或或需要要等待待一个个事件件发生生再运运行时时,该该任务务就会会把CPU的使使用权权让给给别的的任务务而使使任务务进入入等待待状态态。任务在在没有有被配配备任任务控控制块块或被被剥夺夺了任任务控控制块块时的的状态态叫做做任务务的睡睡眠状状态系统为为任务务配备备了任任务控控制块块且在在任务务就绪绪表中中进行行了就就绪登登记,,这时时任务务的状状态叫叫做就就绪状状态。。处于就就绪状状态的的任务务如果果经调调度器器判断断获得得了CPU的使用用权,,则任任务就就进入入运行行状态态一个正正在运运行的的任务务一旦旦响应应中断断申请请就会会中止止运行行而去去执行行中断断服务务程序序,这这时任任务的的状态态叫做做中断断服务务状态态前面谈谈到,,一个个任务务的任任务控控制块块的主要要作用用就是是保存存该任任务的的虚拟拟处理器器的堆堆栈指指针寄寄存器器SP。其实,,随着着任务务管理理工作作的复复杂性性的提高高,它它还应应该保保存一一些其其他信信息。任务控控制块块———任务在在系统统中的的身份份证由于系系统存存在着着多个个任务务,于于是系统如如何来来识别别并管管理一一个任任务就就是一个需需要解解决的的问题题。识识别一一个任任务的最直直接的的办法法是为为每一一个任任务起起一个名称称。由于μC/OS-II中的的任务务都有有一个个惟一的的优先先级别别,因因此μC/OS-II是是用用任务务的的优优先先级级来来作作为为任任务务的的标标识识的。。所以以,,任任务务控控制制块块还还要要来来保存存该该任务务的的优优先先级级别别。另外外,,前前面面也也谈谈到到,,一一个个任任务务在在不同同的的时时刻刻还还处处于于不不同同的的状状态态,,显然然,,记记录录了了任任务务状态态的数数据据也也应该该保保存存到到任任务务控控制制块块中中。。基于于上上述述原原因因,,系系统统必必须须为为每每个个任任务务创创建建一个个保保存存与与该该任任务务有有关关的的相相关关信信息息的的数数据据结构构,,这这个个数数据据结结构构就就叫叫做做该该任任务务的的任任务务控制制块块((TCB))。。任务务控控制制块块结结构构的的主主要要成成员员typedefstructos_tcb{OS_STK*OSTCBStkPtr;//指指向向任任务务堆堆栈栈栈栈顶顶的的指指针针………INT8UOSTCBStat;//任任务务的的当当前前状状态态标标志志INT8UOSTCBPrio;//任任务务的的优优先先级级别别………}OS_TCB;任务务控控制制块块是是不不是是像像我们们人人在在一一个个国国家家中中的身份份证证?((其其实实,,系统统中中的的所所有有资资源源都应应该该有有身身份份证证。。))任务务在在内内存存中中的的结结构构用户户任任务务代代码码的的一般般结结构构voidMyTask(void*pdata){for(;;){可以被中中断的用用户代码码;OS_ENTER_CRITICAL();//进入入临界段段(关中中断)不可以被被中断的的用户代代码;OS_EXIT_CRITICAL();//退出出临界段段(开中中断)可以被中中断的用用户代码码;}}临界段无限循环环于是可以以这样说说,μC/OS-II任务的的代码结构构是一个个可以带带有临界界段的无无限循环环。系统提供供的空闲任务务在多任务务系统运运行时,,系统经经常会在在某个时时间内无无用户任任务可运运行而处处于所谓谓的空闲闲状态,,为了使使CPU在没有有用户任任务可执执行的时时候有事事可做,,μC/OS-II提供了了一个叫叫做空闲闲任务OSTaskIdle()的系统任任务voidOSTaskIdle(void*pdata){#ifOS_CRITICAL_METHOD==3OS_CPU_SRcpu_sr;#endifpdata=pdata;//防止止某些编编译器报报错for(;;){OS_ENTER_CRITICAL();//关闭闭中断OSdleCtr++;//计数数OS_EXIT_CRITICAL();//开放放中断}}空闲任务务只是做做了一个个计数工工作注意!空空闲任务务中没有有调用任任务延时时函数μC/OS-II规定,一一个用户户应用程程序必须须使用这这个空闲闲任务,,而且这这个任务务是不能能用软件件来删除除的系统提供供的另一一个任务务——统计任务务μC/OS-II提供的的另一个个系统任任务是统统计任务务OSTaskStat()。这个统统计任务务每秒计计算一次次CPU在单位位时间内内被使用用的时间间,并把把计算结结果以百百分比的的形式存存放在变变量OSCPUsage中,,以便应应用程序序通过访访问它来来了解CPU的的利用率率,所以以这个系系统任务务OSTaskStat()叫做统计计任务任务的优优先权及优先级级别μC/OS_II把任任务的优优先权分分为64个优先先级别,,每一个个级别都都用一个个数字来来表示。。数字0表示任任务的优优先级别别最高,,数字越大大则表示示任务的的优先级级别越低低用户可以以根据应应用程序序的需要要,在文文件OS_CFG.H中通过过给表示示最低优优先级别别的常数数OS_LOWEST_PRIO赋值的方方法,来来说明应应用程序序中任务务优先级级别的数数目。该该常数一一旦被定定义,则则意味着着系统中中可供使使用的优优先级别别为:0,1,,2,………,OS_LOWEST_PRIO,共OS_LOWEST_PRIO+1个固定地,,系统总总是把最最低优先先级别OS_LOWEST_PRIO自动赋给给空闲任任务。如如果应用用程序中中还使用用了统计计任务,,系统则则会把优优先级别别OS_LOWEST_PRIO-1自动赋给给统计任任务,因因此用户户任务可可以使用用的优先先级别是是:0,,1,2…OS_LOWEST_PRIO-2,,共OS_LOWEST_PRIO-1个个任务务堆堆栈栈保存CPU寄存存器中的的内容及及存储任任务私有有数据的的需要,,每个任任务都应应该配有有自己的的堆栈,,任务堆堆栈是任任务的重重要的组组成部分分在应用程程序中定定义任务务堆栈的的栈区非非常简单单,即定定义一个个OS_STK类型的的一个数数组并在在创建一一个任务务时把这这个数组组的地址址赋给该该任务就就可以了了。例如://定义堆栈栈的长度#define TASK_STK_SIZE 512//定义一个个数组来作为为任务堆栈OS_STKTaskStk[TASK_STK_SIZE];typedefunsignedintOS_STK;//这是系统统定义的一个个数据类型voidmain(void){……OSTaskCreate(MyTask,//任务的指指针&MyTaskAgu,//传递给任任务的参数&MyTaskStk[MyTaskStkN-1],//任务堆栈栈栈顶地址20//任务的优优先级别);……}在创建用户任任务时,要传传递任务的堆堆栈指针和任任务优先级别别使用函数OSTaskCreate()创建建任务时,,一定要注注意所使用用的处理器器对堆栈增增长方向的的支持是向向上的还是是向下的任务堆栈的的初始化应用程序在在创建一个个新任务的的时候,必必须把在系系统启动这这个任务时时CPU各各寄存器所所需要的初初始数据((任务指针针、任务堆堆栈指针、、程序状态态字等等)),事先存存放在任务务的堆栈中中μC/OS-II在创创建任务函函数OSTaskCreate()中通过调调用任务堆堆栈初始化化函数OSTaskStkInit()来完成任务务堆栈初始始化工作的的它的原型如如下:OS_STK*OSTaskStkInit(void(*task)(void*pd),void*pdato,OS_STK*ptos,INT16Uopt);由于各种处处理器的寄寄存器及对对堆栈的操操作方式不不尽相同,,因此该函函数需要用用户在进行行μC/OS-II的移移植时,按按所使用的的处理器由由用户来编编写。实现现这个函数数的具体细细节,将在在本书有关关μC/OS-II移植植的章节中中做进一步的介绍绍其实,任务务堆栈的初初始化就是是对该任务务的虚拟处处理器的初始化(复复位)。任务控制块块(OS_TCB)及任务控制制块链表μC/OS-II用来来记录任务务的堆栈指指针、任务务的当前状状态、任务务的优先级级别等一些些与任务管管理有关的的属性的表表就叫做任务控制块块任务控制块块就相当于于是一个任任务的身份份证,没有有任务控制制块的任务务是不能被被系统承认认和管理的的任务控制块块结构的主主要成员typedefstructos_tcb{OS_STK*OSTCBStkPtr;//指向任任务堆栈栈栈顶的指针针……structos_tcb*OSTCBNext;//指向后后一个任务务控制块的的指针structos_tcb*OSTCBPrev;//指向前前一个任务务控制块的的指针……INT16UOSTCBDly;//任务等等待的时限限(节拍数数)INT8UOSTCBStat;//任务的的当前状态态标志INT8UOSTCBPrio;//任务的的优先级别别……}OS_TCB;任务控制块块链表空任务控制制块链表当应用程序序调用函数数OSTaskCreate()创创建一个任任务时,这这个函数会会调用系统统函数OSTCBInit()来来为任务控控制块进行行初始化。。这个函数数首先为被被创建任务务从空任务务控制块链链表获取一一个任务控控制块,然然后用任务务的属性对对任务控制制块各个成成员进行赋赋值,最后后再把这个个任务控制制块链入到到任务控制制块链表的的头部当进行系统统初始化时时,初始化化函数会按按用户提供供的任务数数为系统创创建具有相相应数量的的任务控制制块并把它它们链接为为一个链表表。由于这些任任务控制块块还没有对对应的任务务,故这个个链表叫做做空任务块块链表。即即相当于是是一些空白白的身份证证。任务就绪表表及任务调度多任务操作作系统的核核心工作就就是任务调调度。所谓调度,,就是通过过一个算法法在多个任任务中确定定该运行的的任务,做做这项工作作的函数就就叫做调度度器。μC/OS_II进行任务调调度的思想想是“近似地每时时每刻总是是让优先级级最高的就就绪任务处处于运行状状态”。为了了保证这一一点,它在系统或用用户任务调调用系统函函数及执行行中断服务务程序结束束时总是调调用调度器器,来确定定应该运行行的任务并并运行它。μC/OS_II进行行任务调度度的依据就就是任务就绪表表为了能够使使系统清楚楚地知道,系统中哪些些任务已经经就绪,哪哪些还没有有就绪,μC/OS_II在RAM中设设立了一个个记录表,,系统中的每每个任务都都在这个表表中占据一一个位置,,并用这个个位置的状状态(1或或者0)来来表示任务务是否处于于就绪状态态,这个表就就叫做任务务就绪状态态表,简称称叫任务就就绪表任务就绪表就是一个二维数组OSRdyTbl[]为加快访问任务就绪表的速度,系统定义了一个变量OSRdyGrp来表明就绪表每行中是否存在就绪任务。OSRdyTbl[]1/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/0OSRdyGrpD7D6D5D4D3D2D1D01/01/01/01/01/01/01/01/0任务就绪表表的示意图图01234567xy01234567OSRdyGrpD7D6D5D4D3D2D1D011110000prio=29D7D6D5D4D3D2D1D01D7D6D5D4D3D2D1D01OSRdyTbl[3]把prio为29的的任务置为为就绪状态态YXOSRdyGrp|=OSMapTbl[prio>>3];OSRdyTbl[prio>>3]|=OSMapTbl[prio&0x07];在程序中,,可以用类类似下面的的代码把优优先级别为为prio的任务置置为就绪状状态:OSRdyGrp|=OSMapTbl[prio>>3];OSRdyTbl[prio>>3]|=OSMapTbl[prio&0x07];如果要使一一个优先级级别为prio的任任务脱离就就绪状态则则可使用如如下类似代代码:if((OSRdyTbl[prio>>3]&=~OSMapTbl[prio&0x07])==0)OSRdyGrp&=~OSMapTbl[prio>>3];OSRdyGrpD7D6D5D4D3D2D1D011110000prio=29D7D6D5D4D3D2D1D01D7D6D5D4D3D2D1D01OSRdyTbl[y]x=OSUnMapTal[OSRdyTbl[y]];11000000000000y=OSUnMapTal[OSRdyGrp];图5-6在在就绪表中查查找最高优先先级别任务的的过程从任务就绪表表中获取优先先级别最高的的就绪任务可可用如下类似似的代码:y=OSUnMapTal[OSRdyGrp];//D5、D4、D3位x=OSUnMapTal[OSRdyTbl[y]];//D2、D1、D0位prio=(y<<3)+x;//优先级别别或y=OSUnMapTbl[OSRdyGrp];prio=(INT8U)((y<<3)+OSUnMapTbl[OSRdyTbl[y]]);优先级判定表表OSUnMapTbl[256](os_core.c)INT8UconstOSUnMapTbl[]={0,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,7,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0};举例:如OSRdyGrp的值值为00101000B,即0X28,则查得得OSUnMapTbl[OSRdyGrp]的值是3,,它相应于OSRdyGrp中的第第3位置1;;如OSRdyTbl[3]的值是11100100B,即即0XE4,,则查OSUnMapTbl[OSRdyTbl[3]]的值是2,,则进入就绪绪态的最高任任务优先级Prio=3*8+2=26小结系统通过查找找任务就绪表表来获取待运行任任务的优先级级优先级任务切换过程程获得待运行任任务的任务控控制块恢复待运行任务的运行环境处理器的PC=任务堆栈中的断点地址处理器的SP=任务块中保存的SP如何获得待运运行任务的任任务控制块??根据就绪表获得待运行任任务的任务控制块指指针其实,调度器器在进行调度度时,在这个个位置还要进进行一下判断断:究竟是待待运行任务是是否为当前任任务,如果是是,则不切换换;如果不是是才切换,而而且还要保存存被中止任务务的运行环境境。1.任务切换宏OS_TASK_SW()任务切换就是是中止正在运运行的任务((当前任务)),转而去运运行另外一个个任务的操作作,当然这个个任务应该是是就绪任务中中优先级别最最高的那个任任务先保护被中止止任务的断点点数据后恢复待运行行任务的断点点数据不要企图用PUSH和POP指令来来使程序计数数器PC压栈栈和出栈,因因为没有这样样的指令。只好变通一下下了。中断动作和过过程调用指令令可以使PC压栈;中断返回指令令可以使PC出栈。因此任务切换换OSCtxSw()必定是一一个中断断服务程程序。需要由宏宏OS_TASK_SW()来引发一一次中断断或者一一次调用用来使OSCtxSw()执行任务务切换工工作调度时机机很容易想想到的调调度时机机就是定时调调度。对于实时时系统来来说,应应该尽可能地实实现即时时调度。。用函数OSTaskCreate()创建任务务应用程序序通过调调用OSTaskCreate()函函数来创创建一个个任务,,OSTaskCreate()函数的的原型如如下:INT8UOSTaskCreate(void(*task)(void*pd),//指向任任务的指指针void*pdata,//传传递给任任务的参参数OS_STK*ptos, //指向任任务堆栈栈栈顶的的指针INT8Uprio //任务的的优先级级)创建任务务的一般方方法一般来说说,任务务可以在在调用函函数OSStart()启启动任务务调度之之前来创创建,也也可以在在任务中中来创建建。但是是,μC/OS-II有一个个规定::在调用用启动任任务函数数OSStart()之前前,必须须已经创创建了至至少一个个任务。。因此,,人们习习惯上在在调用函函数OSStart()之之前先创创建一个个任务,,并赋予予它最高高的优先先级别,,从而使使它成为为起始任任务。然然后在这这个起始始任务中中,再创创建其他他各任务务。如果要使使用系统统提供的的统计任任务,则则统计任任务的初初始化函函数也必必须在这这个起始始任务中中来调用用voidmain(void){ ………OSInit();//对μC/OS-II进行初初始化……OSTaskCreate(TaskStart,………);//创建建任务TaskStartOSStart();//开始始多任务务调度}voidTaskStart(void*pdata){……//在这这个位置置安装并并启动μC/OS-II的时钟钟OSStatInit();//初始始化统计计任务……//在这这个位置置创建其其他任务务for(;;){起始任务务TaskStart的代码码}}μC/OS-II的初始化在使用μC/OS-II的所有有服务之之前,必必须要调调用μC/OS-II的初始始化函数数OSInit()对μC/OS-II自身的的运行环环境进行行初始化化。函数OSInit()将对对μC/OS-II的所有有的全局局变量和和数据结结构进行行初始化化,同时时创建空空闲任务务OSTaskIdle,并并赋之以以最低的的优先级级别和永永远的就就绪状态态。如果果用户应应用程序序还要使使用统计计任务的的话(常常数OS_TASK_STAT_EN=1),则则OSInit()还要以以优先级级别为OS_LOWEST_PRIO-1来创建建统计任任务初始化函函数OSInit()对数数据结构构进行初初始化时时,主要要要创建建包括空空任务控控制块链链表在内内的5个个空数据据缓冲区区。同时时,为了了可以快快速地查查询任务务控制块块链表中中的各个个元素,,初始化化函数OSInit()还还要创建建一个数数组OSTCBPrioTbl[OS_LOWEST_PRIO+1],在这这个数组组中,按按任务的的优先级级别的顺顺序把任任务控制制块的指指针存放放在了对对应的元元素中μC/OS-II的的启启动动μC/OS-II进进行行任任务务的的管管理理是是从从调调用用启启动动函函数数OSStart()开开始始的的,,当当然然其其前前提提条条件件是是在在调调用用该该函函数数之之前前至至少少创创建建了了一一个个用用户户任任务务第3章章μC/OS-ⅡⅡ的中中断断和和时时钟钟本章章主主要要内内容容::μC/OS-II系系统统响应应中中断断的的过过程程μC/OS-II系系统统响响应应中中断断的的过过程程为为::系系统统接接收收到到中中断断请请求求后后,,这这时时如如果果CPU处处于于中中断断允允许许状状态态((即即中中断断是是开开放放的的)),,系系统统就就会会中中止止正正在在运运行行的的当当前前任任务务,,而而按按照照中中断断向向量量的的指指向向转转而而去去运运行行中中断断服服务务子子程程序序;;当当中中断断服服务务子子程程序序的的运运行行结结束束后后,,系系统统将将会会根根据据情情况况返返回回到到被被中中止止的的任任务务继继续续运运行行或或者者转转向向运运行行另另一一个个具具有有更更高高优优先先级级别别的的就就绪绪任任务务。。注意意!!中断断服服务务子子程程序序运运行行结结束束之之后后,,系系统统将将会会根根据据情情况况进进行行一一次次任任务务调调度度去去运运行行优优先先级级别别最最高高的的就就绪绪任任务务,,而而并并不不是是一一定定要要接接续续运运行行被被中中断断的的任任务务的的。中断断请请求求关闭闭中中断断转到到中中断断向向量量保存存CPU寄寄存存器器通知知内内核核退退出出ISRISR给给任任务务发发信信号号中断断返返回回恢复复CPU寄寄存存器器中断断响响应应中断断恢恢复复中断断恢恢复复任务务响响应应时时间间任务务响响应应时时间间中断断的的响响应应过过程程无新新高高级级任任务务则则返返回回原原任任务务通知内核退出ISR恢复CPU寄存器中断返回有新高级任务则运行高级任务通知知内内核核进进入入ISRvoidOSIntEnter(void){if(OSRunning==TRUE){if(OSIntNesting<255){OSIntNesting++;//中中断断嵌嵌套套层层数数计计数数器器加加一一}}}voidOSIntExit(void){#ifOS_CRITICAL_METHOD==3OS_CPU_SRcpu_sr;#endifif(OSRunning==TRUE){OS_ENTER_CRITICAL();if(OSIntNesting>0){OSIntNesting--;//中中断断嵌嵌套套层层数数计计数数器器减减一一}if((OSIntNesting==0)&&(OSLockNesting==0)){OSIntExitY=OSUnMapTbl[OSRdyGrp];OSPrioHighRdy=(INT8U)((OSIntExitY<<3)+OSUnMapTbl[OSRdyTbl[OSIntExitY]]);if(OSPrioHighRdy!=OSPrioCur){OSTCBHighRdy=OSTCBPrioTbl[OSPrioHighRdy];OSCtxSwCtr++;OSIntCtxSw();}}OS_EXIT_CRITICAL();}}在中中断断服服务务程程序序中中调调用用的的负负责责任任务务切切换换工工作作的的函函数数OSIntCtxSw()叫做做中中断断级级任任务务切切换换函函数数OSIntCtxSw(){OSTCBCur=OSTCBHighRdy;//任任务务控控制制块块的的切切换换OSPrioCur=OSPrioHighRdy;SP=OSTCBHighRdy->OSTCBStkPtr;//SP指指向向待待运运行行任任务务堆堆栈栈用出栈栈指令令把R1,R2,………弹弹入CPU的通通用寄寄存器器;RETI;//中中断返返回,,使PC指指向待待运行行任务务}应用程程序中中的临界段段在应用用程序序中经经常有有一些些代码码段必必须不不受任任何干干扰地地连续续运行行,这这样的的代码码段叫叫做临临界段段。因因此,,为了了使临临界段段在运运行时时不受受中断断所打打断,,在临临界段段代码码前必必须用用关中中断指指令使使CPU屏屏蔽中中断请请求,,而在在临界界段代代码后后必须须用开开中断断指令令解除除屏蔽蔽使得得CPU可可以响响应中中断请请求由于各各厂商商生产产的CPU和C编译译器的的关中中断和和开中中断的的方法法和指指令不不尽相相同,,为增增强μC/OS-II的可可移植植性((即在在μC/OS-II的各各个C函数数中尽尽可能能地不不出现现汇编编语言言代码码),,μC/OS-II用两两个宏宏来实实现中中断的的开放放和关关闭,,而把把与系系统的的硬件件相关关的关关中断断和开开中断断的指指令分分别封封装在在这两两个宏宏中::OS_ENTER_CRITICAL()OS_EXIT_CRITICAL()第一种种方法法最简简单,,即直直接使使用处处理器器的开开中断断和关关中断断指令令来实实现宏宏,这这时需需要令令常数数OS_CRITICAL_METHOD=1。其其示意意性代代码为为:#defineOS_ENTER_CRITICAL()\asm(““DI”)\\关关中断断#defineOS_EXIT_CRITICAL()\asm(““EI”)\\开开中断断第二种种方法法稍微微复杂杂一些些,但但可以以使CPU中断断允许许标志志的状状态,,在临临界段段前和和临界界段后后不发发生改改变。。在宏宏OS_ENTER_CRITICAL()中,,把CPU的允允许中中断标标志保保持到到堆栈栈中,,然后后再关关闭中中断,,这样样在临临界段段结束束时,,即在在调用用宏OS_EXIT_CRITICAL()时只只要把把堆栈栈中保保存的的CPU允允许中中断状状态恢恢复就就可以以了。。这两两个宏宏的示示意性性代码码如下下:#defineOS_ENTER_CRITICAL()\asm(““PUSHPSW”)\/*通通过保保存程程序状状态字字来保保存中中断允许许标志志*/asm(““DI”)//关关中断断#defineOS_EXIT_CRITICAL()asm(““POPPSW”)//恢恢复中中断允允许标标志μC/OS-II的系统时时钟μC/OS-II与大大多数数计算算机系系统一一样,,用硬硬件定定时器器产生生一个周周期为为ms级的的周期期性中中断来来实现现系统统时钟钟,最小的时钟单单位就就是两两次中中断之之间相相间隔隔的时时间,,这个个最小小时钟钟单位位叫做做时钟节节拍(TimeTick))。硬件定定时器器以时钟节节拍为为周期期定时时地产产生中中断,,该中中断的的中断断服务务程序序叫做做OSTickISR()。中中断服服务程程序通通过调调用函函数OSTimeTick()来完完成系系统在在每个个时钟钟节拍拍时需需要做做的工工作。voidOSTickISR(void){保存CPU寄存存器;;调用OSIntEnter();//记记录中中断嵌嵌套层层数if(OSIntNesting==1;{OSTCBCur->OSTCBStkPtr=SP;//保保存堆堆栈指指针}调用OSTimeTick();//节节拍处处理清除中中断;;开中断断;调用OSIntExit();//中中断嵌嵌套层层数减减一恢复CPU寄存存器;;中断返返回;;}这是系系统时时钟中中断服服务程程序voidOSTimeTick(void){……OSTimeTickHook();……OSTime++;//记记录节节拍数数……if(OSRunning==TRUE){ptcb=OSTCBList;while(ptcb->OSTCBPrio!=OS_IDLE_PRIO){OS_ENTER_CRITICAL();if(ptcb->OSTCBDly!=0){if(--ptcb->OSTCBDly==0)//任任务的的延时时时间间减一一{if((ptcb->OSTCBStat&OS_STAT_SUSPEND)==OS_STAT_RDY){OSRdyGrp|=ptcb->OSTCBBitY;OSRdyTbl[ptcb->OSTCBY]|=ptcb->OSTCBBitX;}else{ptcb->OSTCBDly=1;}}}ptcb=ptcb->OSTCBNext;OS_EXIT_CRITICAL();}}时钟节节拍服服务函函数函数OSTimeTick()的任任务,,就是是在每个个时钟钟节拍拍了解解每个个任务务的延延时状状态,,使其其中已已经到到了延延时时时限的的非挂挂起任任务进进入就就绪状状态。任务的的延时时由于嵌嵌入式式系统统的任任务是是一个个无限限循环环,并并且μC/OS-II还是一一个抢抢占式式内核核,所所以为为了使使高优优先级级别的的任务务不至至于独独占CPU,可以以给其其他任任务优优先级级别较较低的的任务务获得得CPU使用权权的机机会,,μC/OS-II规定::除了空空闲任任务之之外的的所有有任务务必须须在任任务中中合适适的位位置调调用系系统提提供的的函数数OSTimeDly(),使使当前前任务务的运运行延延时((暂停停)一一段时时间并并进行行一次次任务务调度度,以以让出出CPU的的使用用权。。voidOSTimeDly(INT16Uticks){#ifOS_CRITICAL_METHOD==3OS_CPU_SRcpu_sr;#endifif(ticks>0){OS_ENTER_CRITICAL();if((OSRdyTbl[OSTCBCur->OSTCBY]&=~OSTCBCur->OSTCBBitX)==0){OSRdyGrp&=~OSTCBCur->OSTCBBitY;//取消当当前任任务的的就绪绪状态态}OSTCBCur->OSTCBDly=ticks;//延延时节节拍数数存入入任务务控制制块OS_EXIT_CRITICAL();OS_Sched();//调用调调度函函数}}这是系系统提提供的的延时时函数数其他用用来管管理时时间的的函数数INT8UOSTimeDlyResume(INT8Uprio);INT32UOSTimeGet(void);voidOSTimeSet(INT32Uticks);取消任任务延延时函函数获得系系统时时间函函数设置系系统时时间函函数第4章章任务的的同步步与通通信系统中中的多多个任任务在在运行行时,,经常常需要要互相相无冲冲突地地访问问同一一个共共享资资源,,或者者需要要互相相支持持和依依赖,,甚至至有时时还要要互相相加以以必要要的限限制和和制约约,才才保证证任务务的顺顺利运运行。。因此此,操操作系系统必必须具具有对对任务务的运运行进进行协协调的的能力力,从从而使使任务务之间间可以以无冲冲突、、流畅畅地同同步运运行,,而不不致导导致灾灾难性性的后后果。。与人们们依靠靠通信信来互互相沟沟通,,从而而使人人际关关系和和谐、、工作作顺利利的做做法一一样,,计算算机系系统是是依靠靠任务务之间间的良良好通通信来来保证证任务务与任任务的的同步步的。。例如,两个任任务:任务A和任务B,,它们需要通通过访问同一一个数据缓冲冲区合作完成成一项工作,,任务A负责责向缓冲区写写入数据,任任务B负责从从缓冲区读取取该数据。显显然,当任务务A还未向缓缓冲区写入数数据时(缓冲冲区为空时)),任务B因因不能从缓冲冲区得到有效效数据而应该该处于等待状状态,只有等等任务A向缓缓冲区写入了了数据之后,,才应该通知知任务B去取取数据。例如,任务A和任务B共共享一台打印印机,如果系系统已经把打打印机分配给给了任务A,,则任务B因因不能获得打打印机的使用用权而应该处处于等待状态态,只有当任任务A把打印印机释放后,,系统才能唤唤醒任务B使使其获得打印印机的使用权权。如果这两两个任务不这这样做,那么么也会造成极极大的混乱。总之,多个任任务共享同一一资源或有工工作顺序要求求时,在正式式工作之前要要互相打招呼呼。黄宏:别走啊啊!宋丹丹:我自自己的腿,我我爱走就走,,你管不着!!黄宏:腿是你你自己的,但但手是咱俩的的呀!事件任务间的同步步依赖于任务务间的通信。。在μC/OS-II中,是使使用信号量、、邮箱(消息息邮箱)和消消息队列这些些被称作事件件的中间环节节来实现任务务之间的通信信的。宋丹丹黄宏一个简单的信信号量1/0收信方发信方共享资源事件控制块为了把描述事事件的数据结结构统一起来来,μC/OS-II使用叫做做事件控制块块ECB的数数据结构来描描述诸如信号号量、邮箱((消息邮箱))和消息队列列这些事件。。事件控制块块中包含包括括等待任务表表在内的所有有有关事件的的数据typedefstruct{INT8UOSEventType;//事件件的类型INT16UOSEventCnt;//信号量量计数器void*OSEventPtr; //消息或消息息队列的指针针INT8UOSEventGrp;//等待事件件的任务组INT8UOSEventTbl[OS_EVENT_TBL_SIZE];//任务等等待表}OS_EVENT;把一个任务置置于等待状态态要调用OS_EventTaskWait()函数。。该函数的原原型为:voidOS_EventTaskWait(OS_EVENT*pevent //事件件控制块的指指针);函数OS_EventTaskWait(),将在任任务调用函数数OS××××Pend()请求求一个事件时时,被OS××××Pend()所所调用。如果一个正在在等待的任务务具备了可以以运行的条件件,那么就要要使它进入就就绪状态。这这时要调用OS_EventTaskRdy()函数。。该函数的作作用就是把调调用这个函数数的任务在任任务等待表中中的位置清0(解除等待待状态)后,,再把任务在在任务就绪表表中对应的位位置1,然后后引发一次任任务调度。OS_EventTaskRdy()函数的的原型为:INT8UOS_EventTaskRdy(OS_EVENT*pevent, //事件控制块块的指针void*msg,//未使用INT8Umsk//清除除TCB状态态标志掩码);函数OS_EventTaskRdy()将在任务调调用函数OS×××Post()发送一一个事件时,,被函数OS×××Post()所调用。。如果一个正在在等待事件的的任务已经超超过了等待的的时间,却仍仍因为没有获获取事件等原原因而未具备备可以运行的的条件,却又又要使它进入入就绪状态,,这时要调用用OS_EventTO()函数数。OS_EventTO()函数的原型为为:voidOS_EventTO(OS_EVENT*pevent //事件控制块块的指针);函数OS_EventTO()将在任务调用用OS×××Pend()请求一个事件件时,被函数数OS×××Pend()所调用。空事件控制块块链表在μC/OS-II初始化时时,系统会在在初始化函数数OSInit()中中按应用程序序使用事件的的总数OS_MAX_EVENTS(在文件OS_CFG.H中定义义),创建OS_MAX_EVENTS个空事事件控制块并并借用成员OSEventPtr作作为链接指针针,把这些空空事件控制块块链接成一个个单向链表。。由于链表中中的所有控制制块尚未与具具体事件相关关联,故该链链表叫做空事事件控制块链链表。以后,,每当应用程程序创建一个个事件时,系系统就会从链链表中取出一一个空事件控控制块,并对对它进行初始始化以描述该该事件。而当当应用程序删删除一个事件件时,就会将将该事件的控控制块归还给给空事件控制制块链表信号量及其操操作在使用信号量量之前,应用用程序必须调调用函数OSSemCreate()来创建建一个信号量量,OSSemCreate()的原型为::OS_EVENT*OSSemCreate(INT16Ucnt//信号号量计数器初初值);函数的返回值值为已创建的的信号量的指指针。任务通过调用用函数OSSemPend()请请求信号量,,函数OSSemPend()的的原型如下::voidOSSemPend(OS_EVENT*pevent,//信号量量的指针INT16Utimeout,//等待待时限INT8U*err); //错误信息参数pevent是被请请求信号量的的指针。为防止任务因因得不到信号号量而处于长长期的等待状状态,函数OSSemPend允许许用参数timeout设置一个等等待时间的限限制,当任务务等待的时间间超过timeout时时可以结束等等待状态而进进入就绪状态态。如果参数数timeout被设置置为0,则表表明任务的等等待时间为无无限长。任务获得信号号量,并在访访问共享资源源结束以后,,必须要释放放信号量,释释放信号量也也叫做发送信信号量,发送送信号量需调调用函数OSSemPost()。OSSemPost()函数在对信信号量的计数数器操作之前前,首先要检检查是否还有有等待该信号号量的任务。。如果没有,,就把信号量量计数器OSEventCnt加一一;如果有,,则调用调度度器OS_Sched()去运行行等待任务中中优先级别最最高的任务。。函数OSSemPost()的的原型为:INT8UOSSemPost (OS_EVENT*pevent //信号号量的指针);调用函数成功功后,函数返返回值为OS_ON_ERR,否则则会根据具体体错误返回OS_ERR_EVENT_TYPE、OS_SEM_OVF。应用程序如果果不需要某个个信号量了,,那么可以调调用函数OSSemDel()来来删除该信号号量,这个函函数的原型为为:OS_EVENT*OSSemDel(OS_EVENT*pevent, //信号量的的指针INT8Uopt,//删删除条件选选项INT8U*err//错误误信息);互斥型信号号量和任务务优先级反反转在可剥夺型型内核中,,当任务以以独占方式式使用共享享资源时,,会出现低低优先级任任务先于高高优先级任任务而被运运行的现象象,这种现现象叫做任任务优先级级反转。在一般情情况下是不不允许出现现这种任务务优先级反反转现象的的,下面就就对优先级级的反转现现象做一个个详细的分分析,以期期找出原因因及解决方方法。图4-15描述了A、B、C三个任务务的运行情情况。其中中,任务A的优先级级别高于任任务B,任任务B的优优先级别高高于任务C。任务A和任务C都要使用用同一个共共享资源S,而用于于保护该资资源的信号号量在同一一时间只能能允许一个个任务以独独占的方式式对该资源源进行访问问,即这个个信号量是是一个互斥斥型信号量量。通过例子可可以发现,,使用信号号量的任务务是否能够够运行是受受任务的优优先级别和和是否占用用信号量两两个条件约约束的,而而信号量的的约束高于于优先级别别的约束。。于是当出出现低优先先级别的任任务与高优优先级别的的任务使用用同一个信信号量,而而系统中还还存有别的的中等优先先级别的任任务时,如如果低优先先级别的任任务先获得得了信号量量,就会使使高级别的的任务处于于等待状态态,而那些些不使用该该信号量的的中等级别别的任务却却可以剥夺夺低优先级级别的任务务的CPU使用权而而先于高优优先级别的的任务而运运行了。解决问题的的办法之一一,是使获获得信号量量任务的优优先级别在在使用共享享资源期间间暂时提升升到所有任任务最高优优先级的高高一个级别别上,以使使该任务不不被其他的的任务所打打断,从而而能尽快地地使用完共共
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 文化和旅游产业发展的策略及实施路径
- 建立家庭教育特派员制度的策略及实施路径
- 关于成立有机玻璃公司可行性研究报告(参考)
- 特色餐厅股份交易与区域市场拓展合同
- 水利工程建设项目场地调研与设计合同
- 国有矿山资产转让合同范本
- 自行车共享平台车位租赁及使用规则协议
- 产业园区场地租赁与产业项目合作开发合同
- 双方认可下的广告合作合同
- 铲车操作安全培训及考核协议
- 2025年中考历史复习专项训练:中国近代史材料题40题(原卷版)
- TCTSS 3-2024 茶艺职业技能竞赛技术规程
- 以教育家精神引领教育硕士研究生高质量培养的价值意蕴与实践路径
- 有限空间作业气体检测记录表
- 部编版语文六年级下册第五单元教材解读大单元集体备课
- 乒乓球的起源与发展
- 服装表演音乐游戏课程设计
- 理工英语3-01-国开机考参考资料
- 头颅常见病影像
- 漫画解读非煤地采矿山重大事故隐患判定标准
- 2024年建筑业10项新技术
评论
0/150
提交评论