μC/OS II中的任务

实时系统中任务的执行大多数都是由外部事件触发的,即实时操作系统的主要工作就是响应并处理各种外部事件。作为实时系统,对于每个事件都应对应有一个处理这个事件的程序模块,这些程序模块就是任务 。从外部事件的形式来看,主要有三种:异步事件、周期性事件、异步事件与周期性事件的组合。

一、任务的存储结构

系统只要掌握了一个任务的任务控制块,就可以找到任务的可执行代码,也可以找到存储这个任务私有数据的存

储区

嵌入式系统任务监控 嵌入式实时任务_优先级


嵌入式系统任务监控 嵌入式实时任务_任务控制块_02

二、任务的状态

⒈睡眠状态:任务在没有被配备任务控制块或被剥夺了任务控制块时的状态叫做任务的睡眠状态 ;

⒉就绪状态:系统为任务配备了任务控制块且在任务就绪表中进行了就绪登记,这时任务的状态叫做就绪状态。

⒊运行状态:处于就绪状态的任务如果经调度器判断获得了CPU的使用权,则任务就进入运行状态。

⒋中断状态:一个正在运行的任务一旦响应中断申请就会中止运行而去执行中断服务程序,这时任务的状态叫做中断服务状态。

⒌等待状态:正在运行的任务,需要等待一段时间或需要等待一个事件发生再运行时,该任务就会把CPU的使用权让给别的任务而使任务进入等待状态。

嵌入式系统任务监控 嵌入式实时任务_优先级_03

三、任务的优先级别

⒈μC/OS II把任务的优先权分为64个优先级别,每一个级别用一个数字来表示。数字0表示任务的优先级别最高,数字越大则优先级别越低。
⒉μC/OS II中一个应用程序的任务数最多可以有64个,任务数的具体个数通过常数OS_LOWEST_PRIO赋值的方法来说明,OS_LOWEST_PRIO表示系统中任务的最低优先级别。
⒊系统总是把最低优先级别OS_LOWEST_PRIO自动赋给由系统创建的一个任务——空闲任务,系统总是把优先级别OS_LOWEST_PRIO-1自动赋给统计任务,用户任务可使用的优先级别为:0、1、2、… 、OS_LOWEST_PRIO - 2,共OS_LOWEST_PRIO - 1个。
例题:如果希望应用程序中任务的优先级别为28个,则常数OS_LOWEST_PRIO的值应该是多少? 答:27
如果应用程序中使用了系统提供的空闲任务和统计任务,则该应用程序最多可安排多少个任务? 答:26
⒋由于每个任务都具有唯一的优先级别,因此μC/OS II通常用任务的优先级别来作为这个任务的标识。

四、任务控制块

⒈任务控制块

用来记录与任务管理有关的属性的表就叫做任务控制块,任务控制块即进程中的进程控制块,没有任务控制块的任务是不能被系统承认和管理的。

嵌入式系统任务监控 嵌入式实时任务_嵌入式系统任务监控_04

⒉任务控制块链表

μC/OS II用两条链表来管理任务控制块: 一条是空任务块链表(其中所有任务控制块还没有分配给任务),一条是任务块链表(其中所有任务控制块已经分配给任务)。

⑴空任务块链表的创建

①先在RAM中建立一个OS_TCB结构类型的数组OSTCBTb1[ ],并使数组的每个元素都是一个任务控制块;

②然后利用OS_TCB结构中的两个指针OSTCBNext和OSTCBPrev把这些控制块链接成一个链表。

由于链表中的这些控制块还没被分配给任务,因此被称为空任务块链表;空任务块链表是在函数OSInit()对μC/OS II系统进行初始化时建立的。

嵌入式系统任务监控 嵌入式实时任务_μC/OS II_05

⑵任务块链表的创建

①当应用程序创建一个任务时,系统从空任务块链表的头部(指针OSTCBFreeList指向的任务控制块)摘取一个空任务控制块分配给该任务,并把它加入到任务控制块链表中,同时要给任务控制块中的各成员赋值。

②*任务控制块链表是在系统调用系统函数OSTaskCreate()创建任务时建立的。任务控制块相当于任务在系统中的档案

两条链表相当于设立了两个装有档案的档案柜:一个用来装空白档案,一个用来装已存有任务信息的档案。

嵌入式系统任务监控 嵌入式实时任务_操作系统_06

五、任务堆栈

保存CPU寄存器中的内容及存储任务私有数据,每个任务都应该配有自己的堆栈,任务堆栈是任务的重要的组成部分 。

⒈任务堆栈的创建

⑴栈区的指定
在应用程序中定义任务堆栈的栈区非常简单,即定义一个OS_STK类型的一个数组;
例如:

//定义堆栈的长度
     #define	TASK_STK_SIZE	 512

 //定义一个数组来作为任务堆栈
     OS_STK TaskStk[TASK_STK_SIZE];

⑵将指定好的栈区提供给任务使用

嵌入式系统任务监控 嵌入式实时任务_任务控制块_07

⒉任务堆栈的初始化

堆栈初始化的工作是在创建任务函数OSTaskCreate( )中通过调用任务堆栈初始化函数OSTaskStkInit( )来完成的。具体内容:
将处理器处理任务时所需的有关这个任务的相关信息复制到处理器相应的寄存器里,相关信息包括:任务指针 、任务堆栈指针 、程序状态字… …

六、系统任务

μC/OS II中预定义了两个为应用程序服务的系统任务:空闲任务——每个应用程序必须使用;统计任务 ——应用程序根据实际需要来选择使用。统计任务的级别比空闲任务高一级。

⒈空闲任务 OSTaskIdle()

为了使处理器在没有用户任务可执行时有事可做。

嵌入式系统任务监控 嵌入式实时任务_操作系统_08

⒉统计任务 OSTaskStat()

每秒计算一次处理器在单位时间内被使用的时间,并把计算结果以百分比的形式存放在变量OSCPUsage中,以便应用程序通过访问它来了解处理器的利用率。统计任务的使用与否是由用户来决定的,如果要使用该统计任务,则:将常数OS_TASK_STAT_EN的值设为1(在系统头文件OS_CFG .H中)。

七、用户任务代码的一般结构

嵌入式系统任务监控 嵌入式实时任务_操作系统_09


于是可以这样说,μC/OS-II任务的代码结构是一个可以带有临界段的无限循环。

八、小结

⒈μC/OS II 是一个微内核。它的绝大部分代码都是用C 语言编写的,并且只对计算机的处理器与硬件时钟进行了抽象和封装,而没有提供其他硬件抽象层,所以若处理器供应商提供了相应的硬件抽象层,就可以很容易地把它移植到各种处理器上。
⒉μC/OS II 任务的存储结构由三部分组成:任务控制块、任务代码和任务堆栈。在任务控制块中有指向任务堆栈的指针和隐含指向任务控代码的指针。
⒊μC/OS II 中的任务,每一个都必须有一个唯一的优先级别。该优先级别用数字来表示,数字0 为最高优先级别,数字越大,优先级别越低。由于μC/OS II 中任务的优先级别是唯一的,因此优先级别也作为任务的标识来使用。
⒋任务控制块是任务在系统中的档案,它记录了系统在管理任务时所应掌握的任务的全部静态和动态信息。为了对系统中的任务进行管理,μC/OS II 把所有任务的任务控制块分为两部分:已有任务的任务控制块和尚未有对应任务的空任务控制块,并把这两部分分别组成一个链表。
⒌每个任务为了在运行中保存私有数据及在任务被中止时保留处理器各寄存器的值,μC/OS II 中的每个任务都有一个自己的堆栈,这个堆栈就叫做任务堆栈。在任务控制块中有一个指针就指向了自己的任务堆栈。
⒍空闲任务是当系统中没有可运行的其他任务时,由系统运行的任务,其优先级别最低,因此只要有其他任务就绪,这个空闲任务的处理器使用权就会被剥夺。
⒎μC/OS II 允许使用宏OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()在程序中来设置临界区,从而使临界区代码在执行期间不允许中断。