实时系统的概念——uC/OS学习笔记(一)

1.      实时系统

实时系统的特点是:如果逻辑和时序出现偏差,将会引起严重后果。有2种类型的实时系统:软实时系统和硬实时系统。

在软实时系统中,系统的宗旨是是各个任务尽快地运行,而不要求限定某一任务在多长时间内完成;在硬实时系统中,个任务不仅须执行无误,而且要做到准时。

大多数实时系统是二者的结合。实时系统的应用涵盖广泛的领域,而多数实时系统又是嵌入式的。这意味着计算机建在系统内部,用户看不到有个计算机在系统里面。

 

2.      前/后台系统

应用程序是一个无限的循环,循环中调用相应的函数完成相应的操作,这部分可以看成后台行为。中断服务程序处理异步事件,这部分可以看成前台行为

后台也可以叫做任务级,前台叫做中断级。

时间相关性很强的关键操作一定是靠中断服务来保证的。因为中断服务提供的信息一直要等到后台程序运行到处理这个消息时,才能得到处理。所以这种系统在处理信息的及时性相对较差。

 

3.      代码临界段

它指处理时不可分割的代码。一旦这部分代码开始执行,则不允许任何中断打入。为确保临界段代码的执行不被中断,在进入临界段之前须关中断,而临界段代码执行完后,要立即打开中断。

 

4.      资源

任何为任务所占用的实体都可称为资源。资源可以是输入/输出设备,例如打印机、键盘及显示器;资源也可以是一个变量、一个结构或一个数组。

 

5.      共享资源

可以被一个以上任务使用的资源叫做共享资源。为了防止数据被破坏,每个任务在与共享资源打交道时,必须独占该资源,这叫做互斥。

 

6.      多任务

多任务运行的实现实际上是靠CPU在许多任务之间转换和调度,CPU只有一个,轮番服务于一系列任务中的某一个。多任务运行很像前/后台系统,只是后台任务有多个。多任务运行使CPU的利用率达到最高,并使应用程序模块化

在实际应用中,多任务化的最大特点是,开发人员可以将很复杂的应用程序层次化。使用多任务,应用程序将更容易设计和维护。

 

7.      任务

一个任务,也称作一个线程,是一个简单的程序,该程序可以认为CPU完全只属于该程序自己。实时应用程序的设计过程包括如何把问题分割成多个任务。每个任务都是整个应用的一部分,都被赋予一定的优先级,有自己的一套CPU寄存器和栈空间。

每个任务都是一个无线的循环,都可能处于一下5种状态之一——休眠态、就绪态、运行态、挂起态(等待某一事件发生)及被中断态、

休眠态:相当于任务驻留在内存中,但并不被多任务内核所调度;

就绪态:意味着任务已经准备好,可以运行,但由于该任务的优先权比正在运行的任务的优先级别低,还暂时不能运行;

运行态:是指任务掌握了CPU的使用权,正在运行中;

挂起态:也可以叫做等待事件态,指任务在等待,等待某一时间的发生(例如:等待某外设的I/O操作,等待某共享资源由暂不能使用变成能使用状态,等待定时脉冲的到来,或等待超时信号的到来,以结束目前的等待,等等)

被中断态:发生中断时,CPU提供相应的中断服务,原来正在运行的任务暂不能运行,就进入了被中断状态。

 

8.      任务切换

当多任务内核决定运行另外的任务时,它保存正在运行任务的当前状态,即CPU寄存器中的全部内容。这些内容保存在任务的当前状况保存区,也就是任务自己的栈区之中。入栈工作完成以后,就把下一个将要运行的任务的当前状况从该任务的栈中重新装入CPU的寄存器,并开始下一个任务的运行,这个过程叫做任务的切换。

任务切换过程增加了应用程序的额外负荷,CPU的内部寄存器越多,额外的负荷就越重。任务切换的时间取决于CPU有多少个寄存器要入栈。

 

9.      内核

多任务系统中,内核负责管理各个任务,或者说为每个任务分配CPU时间,并且负责任务间的通信内核提供的基本服务是任务切换,使用实时内核可以大大简化应用系统的设计,因为实时内核允许将应用程序分成若干个任务,由实时内核来管理它们。

内核本身会增加应用程序的额外负荷,因为内核提供的服务需要一定的执行时间。由于内核是加载用户应用程序中的软件,所以内核会增加ROM的用量。而且,内核要为每个任务分配栈空间,所以会增加很多RAM用量

单片机一般不能运行实时内核,因为单片机的RAM很有限。通过提供必不可少的系统服务,如:信号量管理、邮箱、消息队列及时间延时等,实时内核使得CPU的利用更为有效。

 

10.  调度

这是内核的主要职责之一,就是决定该轮到哪个任务运行了。多数实时内核是基于优先级调度法的。每个任务根据其重要程度的不同,被赋予一定的优先级。基于优先级的调度法是指,CPU总是让处于就绪态的、优先级最高的任务先运行。然而,何时高优先级任务掌握CPU的使用权,由使用的内核类型决定

基于优先级的内核有两种:不可剥夺型和可剥夺型

 

11.  不可剥夺型内核

它要求每个任务主动放弃CPU的使用权,各任务彼此合作共享一个CPU

异步事件还是由中断服务来处理。中断服务可使一个高优先级的任务由挂起态变为就绪态,但中断服务以后,使用权还是回到原来被中断了的那个任务

优点:

a)        不可剥夺型内核的一个优点是响应中断快。在任务级,不可剥夺型内核允许使用不可重入函数。

b)        任务级响应时间比前/后台系统快得多。此时的任务级响应时间取决于最长的任务的执行时间

c)        几乎无须使用信号量保护共享数据,运行着的任务占有CPU,而不必担心被别的任务抢占。

缺点:不可剥夺型内核最大的缺陷在于其响应时间。高优先级的任务已经已经进入就绪态,但还不能运行,直到当前运行着的任务释放CPU。与前/后台系统一样,不可剥夺型内核的任务级响应时间是不确定的,这完全取决于应用程序何时释放CPU。商业软件几乎没有不可剥夺型内核

 

12.  可剥夺型内核

当系统响应时间很重要时,须使用可剥夺型内核。uC/OS以及极大多数商业实时内核都是可剥夺型内核。

最高优先级的任务一旦就绪,总能得到CPU的使用权。当一个运行着的任务使一个比它优先级高的任务进入了就绪态时,当前任务的CPU的使用权就被剥夺了,或者说被挂起了,更高优先级的任务立刻得到了CPU的使用权。如果中断服务子程序使一个高优先级的任务进入就绪态,中断完成时,中断了的任务被挂起,优先级高的任务开始运行。

使用可剥夺型内核,最高优先级的任务何时可以执行,何时可以得到CPU的使用权,这些是可知的。可剥夺型内核使得任务级响应时间得以最优化。

使用可剥夺型内核时,应用程序不应直接使用不可重入函数。调用不可重入函数时,应满足互斥条件

 

13.  可重入函数

它可以被一个以上的任务调用,而不必担心数据被破坏。可重入函数任何时候都可以被中断,一段时间以后又可以运行,而相应的数据不会丢失。

可重入函数或者只使用局部变量,即变量保存在CPU寄存器中或堆栈中;或者使用全局变量,则要对全局变量予以维护。

                   不可从重入函数则与可重入函数相反。

 

14.  时间片轮番调度法(重点

当2个或者2个以上任务有同样的优先级时,内核允许1个任务运行事先确定的一段时间,这段时间叫做时间额度,然后切换给另一个任务。这个过程叫做时间片轮番调度。内核在满足以下条件时,把CPU使用权交给下一个就绪态的任务:

a)        当前任务已空闲

b)        当前任务在时间片还没结束时就已经完成

c)        时间片结束

目前,uC/OS-2不支持时间片轮番调度法。应用程序中各任务的优先级必须互不相同。

 

15.  任务优先级

每个任务都有其优先级。任务越重要,赋予的优先级应越高。就大多数内核而言,每个任务的优先级是由用户决定

 

16.  静态优先级

应用程序执行过程中诸任务优先级不变,称为静态优先级。在静态优先级系统中,诸任务以及它们的时间约束在程序编译时是已知的。

 

17.  动态优先级

应用程序执行过程中,任务的优先级是可变的,称为动态优先级。实时内核应当避免出现优先级翻转问题。uC/OS 2 具有这一功能。

 

18.  优先级翻转(重点

这个问题是实时系统经常出现的问题。具体要查资料,或者看《嵌入式实时操作系统 uC/OS 2》的第44页。

大概就是当一个优先级低的任务正在使用一个共享资源,而这个期间,突然有一个优先级高的任务也要使用这个共享资源。但是这时候这个共享资源已经被这个优先级低的任务占用了,所以这个优先级高的任务只能挂起等待优先级低的任务释放掉这个共享资源。这样的结果是,原本优先级高的任务得不到运行,反而让优先级低的任务先运行。

解决方法:当优先级低的任务在使用共享资源时,应当提升该任务的优先级直到高于使用该资源的任何任务。所以多任务内核应允许动态改变任务的优先级,以避免出现优先级翻转的现象。

由于改变任务的优先级需要花很多时间,所以内核最好能够自动变换任务的优先级,称作优先级继承。uC/OS 2不支持优先级继承。

 

19.  任务优先级分配

给任务定(分配)优先级不是件简单的事,因为实时系统相对复杂。实时系统大多综合了软实时和硬实时2中需求。软实时系统只是要求任务执行得尽量快,并不要在某一特定时间内完成;硬实时系统中,任务不但要执行无误,还要准时完成

有一项技术用于分配任务的优先级,称为单调执行率调度法RMS。这种方法基于任务执行的次数,执行最频繁的任务优先级最高。但是RMS只能作为一个优先级分配的参考的起点,因为不是执行最频繁的任务最重要

 

20. 互斥条件

              实现任务间通信最简便的方法是使用共享数据结构。虽然共享数据区法简化了任务间的信息交换,但是必须保证每个任务在处理共享数据时的排它性,以避免竞争和              数据的破坏。

       使之满足互斥条件最一般的方法是:

a) 开关中断(重要)

       uC/OS在处理内部变量和数据结构时,大部分是进入临界区来处理,即先关中断,处理完成后再打开中断。

       当改变或者复制某几个变量的值时,应考虑使用这种方法。

       当在中断服务子程序中处理共享变量或共享数据结构时,必须使用这种方法

b) 使用测试并置位指令

              如果不使用实时内核,那么当两个任务共享一个资源时,须约定好,先测试一全局变量,如果该变量为0,允许该任务与共享资源打交道。为了防止另外一个任务也要           使用该资源,第一个得到资源的任务只需简单地将全程变量置为1。这通常称作测试并置位TAS操作。

       有些微处理器具有硬件的TAS指令

c) 禁止做任务切换(不太理解具体怎样用)

       如果任务不与中断服务子程序共享变量或数据结构,可以使用“禁止,然后允许任务切换操作”。即给任务切换上锁,然后开锁的方法实现数据共享。

d) 利用信号量(重要)

              信号量实际上是一种约定机制,在多任务内核中普遍使用。信号量就像一把钥匙,任务要运行下去,需要先拿到这把钥匙。如果信号量已被别的任务占用,那么该任务         只得被挂起,直到信号量被当前使用者释放。

       信号量用于:

       1) 控制共享资源的使用权(满足互斥条件)

       2) 标志某事件的发生

       3) 使两个任务的行为同步

       信号量的操作只有3种:建立,等信号和发信号。

e)何时使用信号量和开关中断(重要)

       对于处理普通的共享变量:这样使用信号量是多余的。因为请求信号量会花费不少时间,这样只须关开中断即可

       对于处理一个花费时间较长的共享资源,或者在没有浮点型运行的芯片上处理浮点型变量:这样假如使用关开中断,那么关中断的时间可能会很长,所以应该使用信号量


21.死锁(重要

       指两个任务无限期地互等待对方控制着的资源。设任务T1正独享资源R1,任务T2正独享资源R2,而此时T1又要独享R2,T2也要独享R1,于是哪个任务都都无法继续执行了,发生了死锁。

       防止死锁的方法,让每个任务都:

       a)先得到全部需要的资源,再做下一步的工作

       b)用同样的顺序申请多个资源

       c)释放资源时,使用相反的顺序

       内核大多允许用户在申请信号量是定义等待超时时间,从而化解死锁


22.同步

      可以利用信号量使某个任务与中断服务同步(或者与另一个任务同步,这2个任务间没有数据交换)

      单向同步:例如:一个任务做I/O操作,然后等信号回应。当I/O操作完成时,中断服务程序(或另外一个任务)发出信号,该任务得到信号后继续往下执行。

      双向同步:使用两个信号量同步它们的行为。


23.事件标志

      当某任务要与多个事件同步时,须使用事件标志。

      若任务需要与任何事件的其中一个事件发生同步,称为独立型同步(逻辑“或”关系)。实际上,可以把多个事件组合成“或”关系,然后请求信号量

      若任务与若干事件都发生同步,称为关联型同步(逻辑“与”关系)。实际上,可以把多个事件组合成“与”关系,然后请求信号量

      典型的方法,把8个、16个事件组合在一个变量标志位上,每个事件栈1位(1bit),任务或中断服务程序可以给某一位置置位或者复位。从而把多个事件组合再一起,然后就能判断并请求信号量。


24.任务间通信(重要

      有时很需要任务间或中断服务与任务间的通信。

      任务间信息传递有2个途径:

      a)全局变量。

            这时必须保证每个任务或中断服务子程序独享该变量。在中断服务中唯一办法是关中断。在任务间可以使用关开中断或者信号量。

      b)发消息给另一个任务

            使用邮箱或消息队列


25.消息邮箱(重要

      作用:通过内核服务可以给任务发送消息

      原理:典型的消息邮箱也称作交换消息,即用一个指针变量,一个任务或一个中断服务子程序通过内核服务,可以把一则消息(即一个指针)放到邮箱里去。同样,一个或多个任务通过内核服务,可以接收这则消息。发送消息的任务和接收消息的任务约定,该指针指向的内容就是这则消息。

      使用过程:

            每个邮箱有相应的正在等待消息的任务列表。要得到消息的任务会因为邮箱是空的而被挂起

            当消息放入邮箱后,假如有多个任务在等待消息,会根据优先级别或者先进先出来把消息传给不同的任务。

      内核一般提供的邮箱服务:

            1)邮箱内消息内容的初始化

            2)将消息放入邮箱(POST)

            3)等待消息进入邮箱(PEND)(类似阻塞型rend)

            4)从邮箱中得到消息。如果邮箱内没有消息,则任务并不被挂起;如果有消息,就接收这则消息。(类似非阻塞read)

      消息邮箱当做信号量使用:把消息邮箱当做只取2个值的信号量来用。邮箱里有消息,表示资源可以使用;邮箱为空,表示资源已被其他任务占用


26.消息队列(重要

      用于给任务发消息。消息队列实际上是邮箱阵列。邮箱只能放一个消息,而消息队列可以放多个消息。通过内核提供的服务,任务或中断服务子程序可以将一则消息(该消息的指针)放入消息队列。


28.  主要参考书籍

a)        《嵌入式实时操作系统 uC/OS 2》

b)        《嵌入式实时操作系统 uC/OS 2 原理及应用》

 

 

 

 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值