uCOS-II学习笔记:实时操作系统(一)

来源:互联网 发布:windows没有视频设备 编辑:程序博客网 时间:2024/05/16 18:00

1.前后台系统:前后台系统的架构用一句话来形容的话,就是一个大的循环,加上中断,就形成了一个整的体系。


假设来了中断需要处理模块3,如果模块3的处理是最紧迫的,但是当前cpu 只运行到模块1, 这样的话,必须还要承受模块2的运行时间延迟,才能轮到模块3的处理,当模块越多的时候很可能情况更糟糕。单个循环要解决此类问题的话,只能在中断里面去处理紧急事件,这样会造成中断执行太长,造成多层的中断嵌套,最终可能导致中断栈空间爆掉。更重要的是:不是所有的中断都是紧急的重要的,很可能各个要处理的模块优先级要大于不紧急的中断处理。这样造成的后果是不但各个模块间不能相互通讯,而且实时模块完全得不到处理,在一个中大型软件项目中,采用此类方法可以说是一种管理的灾难。(实时性差)

2.代码临界区

3.资源:任何为任务所占用的实体都可称为资源,可以是输入设备/输出设备,如打印机;也可以是一个变量,一个结构或一个数组。

4.任务:即线程,每个任务都是一个无限的循环,都可能处于以下5种状态之一:休眠态(相当于任务驻留在内存中,但并不被多任务内核所调度)、就绪态、运行态、挂起态(等待某一事件发生)和被中断态。

5.任务切换:保存正在运行任务的当前状态即CPU寄存器中的全部内容到任务的当前状况保护区也就是任务自己的堆栈中。

6.内核:负责管理各个任务,分配CPU时间,负责任务间的通信,提供的基本服务是任务切换。

7.调度:采用优先级的调度算法,合适高优先级任务掌握CPU的使用权由使用的内核类型确定:不可剥夺型和可剥夺型。

8.不可剥夺型:要求每个任务主动放弃CPU的主动权。中断服务可以使一个高优先级的任务由挂起态变为就绪态(只发生状态改变),但中断服务后使用权还是回到原来被中断了的那个任务,因此可以调用不可重入函数。优点是几乎无须使用信号量保护共享数据,运行着的任务占有CPU,而不必单行被别的任务抢占。缺陷在于其响应时间。

9.可剥夺型:最高优先级的任务一旦就绪,总能得到CPU的使用权。如果是中断服务子程序使一个高优先级的任务进入就绪态,中断完成时,中断了的任务呗挂起,优先级高的任务开始运行。

10.可重入函数任何时候都可以被中断,一段时间以后又可以运行,而相应的数据不会丢失。可重入函数或者只是用局部变量,即变量保存在CPU寄存器中或栈中;或使用全局变量,则要对全局变量予以保护。

11.优先级反转:  优先级反转是指一个低优先级的任务持有一个被高优先级任务所需要的共享资源。高优先任务由于因资源缺乏而处于受阻状态,一直等到低优先级任务释放资源为止。而低优先级获得的CPU时间少,如果此时有优先级处于两者之间的任务,并且不需要那个共享资源,则该中优先级的任务反而超过这两个任务而获得CPU时间。如果高优先级等待资源时不是阻塞等待,而是忙循环,则可能永远无法获得资源,因为此时低优先级进程无法与高优先级进程争夺CPU时间,从而无法执行,进而无法释放资源,造成的后果就是高优先级任务无法获得资源而继续推进。

解决方法:

动态改变任务的优先级:设置优先级上限,给临界区一个高优先级,进入临界区的进程都将获得这个高优先级,如果其他试图进入临界区的进程的优先级都低于这个高优先级,那么优先级反转就不会发生。

‚优先级继承:当一个高优先级进程等待一个低优先级进程持有的资源时,低优先级进程将暂时获得高优先级进程的优先级别,在释放共享资源后,低优先级进程回到原来的优先级别。

13.互斥条件:

①关中断和开中断:
OS_ENTER_CRITICAL();

OS_EXIT_CRITICAL();

必须十分小心,关中断的事件不能太长,因为他影响整个系统的中断响应时间,即中断延迟事件。当改变或复制某几个变量的值时,可以考虑使用。

②测试并置位操作(Test-and-Set):两个任务共享一个资源时,先测试一下全局变量,如果该变量是0,允许该任务与共享资源打交道。为防止另外一个任务使用该资源,第一个得到资源的任务只需简单地将全局变量置为1

③禁止然后允许任务切换(允许中断子程序):

OSSchedLock();

OSSchedUnlock();

④信号量:create, pend, post.如果想得到信号量的任务须执行P操作,如果该信号量有效(信号量值大于0),则信号量值减1,任务得以运行。如果信号量为0,等待信号量的任务就列入等待信号量列表中。

OSSemPend(SharedDataSem, 0, &err);

OSSemPost(SharedDataSem);

计数式信号量用于某资源可同时为几个任务所用。

请求和释放信号量的过程是要花费相当的时间的。

14.死锁,内核大多允许用户在申请信号量时定义等待超时,以此化解死锁。

15.同步:指系统中多个线程发生的事件存在某种时序关系,需要相互合作,共同完成一项任务,具体来说:一个线程运行到某一点时,要求另一伙伴线程为它提供信息,在未获得消息之前,该线程进入挂起态,获得消息后别唤醒进入就绪状态。(如消费者/生产者问题)


16.事件标志:独立型同步(逻辑或关系)、关联型同步(逻辑与关系)

用于当任务要与多个事件同步时,需要使用事件标志(event flag)。任务或中断服务可以给某一位置位或复位。当任务所需的事件都发生了,该任务继续执行。

17.任务间通信:任务间或中断服务与任务间的通信。

消息邮箱:用一个指针变量,一个任务或一个中断服务子程序通过内核服务,可以把一则消息(一个指针)放到邮箱里去,另外一个或多个任务通过内核服务,可以接收这则消息。

每个邮箱有相应的正在等待消息的任务列表,消息放入邮箱后,或者把消息传递给等待消息的任务列表中优先级最高的任务(基于优先级),或者将消息传给最先等待消息的任务(基于先进先出),uCOS-II只支持前者。

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

‚消息队列:实际是邮箱阵列。通常先进消息队列的消息先传给任务,任务先得到的是最先进入消息队列的消息,即先进先出原则(FIFO);而uCOS-II也使用后进先出方式(LIFO)。

18.中断延迟=关中断的最长时间+开始执行中断服务子程序第一条指令的时间

19.中断响应:从中断发生到开始执行用户的中断服务子程序代码来处理这个中断的时间。

20.中断处理:大多数情况下,中断服务子程序应识别中断来源,从请求中断的设备取得数据或状态,并通知真正做该事件处理的任务。

21.非屏蔽中断:通常留做应急处理用,如断电时保存重要的信息。在非屏蔽中断的中断子程序中,不能使用内核提供的服务,因为非屏蔽中断时关不掉的,故不能在非屏蔽中断处理中处理临界区代码;然而非屏蔽中断传输参数,或从非屏蔽中断获取参数,还是可以进行的。参数的传递必须使用全程变量,全程变量的位数必须是1次读或写能完成的。

22.时钟节拍(clock tick):是特定的周期性中断。中断之间的时间间隔取决于不同的应用,一般为10~200ms。时钟的节拍式中断使得内核可以将任务延时若干个整数时钟节拍,以及当任务等待事件发生时,提供等待超时的依据。

void OSTimeTick (void);

我们知道,CPU总是执行就绪表中优先级最高的任务,任务有没有在就绪表中就得依靠OSTimeTick()了。OSTimeTick()很大的工作是给每个用户任务控制块OS_TCB中的时间延时项OSTCBDly1,当某任务的任务控制块中的时间延时项OSTCBDly减到了零,这个任务就进入了就绪态。

OSTimeTick()跟踪所有任务的定时器以及超时时限。时钟节拍中断服务子程序必须用汇编语言编写,因为在C语言不能直接处理CPU的寄存器。

0 0
原创粉丝点击