嵌入式-3(new)讲解

上传人:我** 文档编号:115402779 上传时间:2019-11-13 格式:PPT 页数:137 大小:1.87MB
返回 下载 相关 举报
嵌入式-3(new)讲解_第1页
第1页 / 共137页
嵌入式-3(new)讲解_第2页
第2页 / 共137页
嵌入式-3(new)讲解_第3页
第3页 / 共137页
嵌入式-3(new)讲解_第4页
第4页 / 共137页
嵌入式-3(new)讲解_第5页
第5页 / 共137页
点击查看更多>>
资源描述

《嵌入式-3(new)讲解》由会员分享,可在线阅读,更多相关《嵌入式-3(new)讲解(137页珍藏版)》请在金锄头文库上搜索。

1、嵌入式操作系统,第三章 C/OS-II中的任务,2,第3章 C/OS-II中的任务,本部分的主要内容包括: 任务的基本概念 任务代码、任务控制块和任务堆栈 任务的优先权 任务就绪表结构及其操作 任务切换及任务调度 任务的创建、删除、挂起、恢复和查询 C/OS-II的初始化和启动,3,3.1 任务的基本概念 3.1.1 任务及其内存结构,在设计一个较为复杂的应用程序时,通常把一个大型任务分解成多个小任务,然后在计算机中通过运行这些小任务,最终达到完成大任务的目的。实时应用程序的设计过程包括如何把问题分割成多个任务。每个任务都是整个应用程序的一部分,都被赋予一定的优先级,有自己的一套CPU寄存器和

2、栈空间。由于这种方法可以使系统并发地运行多个任务,从而提高处理器的利用率,加快程序的执行速度,因此现代操作系统几乎都是多任务操作系统。,4,一个任务,也称作一个线程,是一个简单的程序,与大任务分割成的小任务对应的程序实体就叫做“任务”,而C/OS-II就是一个能对这些小任务的运行进行管理和调度的多任务操作系统。 从代码上看,C/OS-II的任务就是一个函数。而从任务的存储结构上看,C/OS-II的任务由三个部分组成:任务程序代码(函数)、任务堆栈和任务控制块。其中任务控制块就是关联了任务代码的程序控制块(TCB),它记录了任务的各个属性;任务堆栈则用来保存任务的工作环境;任务程序代码就是任务的

3、执行部分。,5,PC,6,C/OS-II任务控制块实质上就是2.4.2节中所介绍的具有二级结构的代码控制块,只不过用来指向代码的指针是CPU程序指针(程序计数器)PC的副本。系统可以根据任务控制块来了解代码的相关信息,当然也就是能够找到代码。 注:任务控制块通过任务堆栈和任务代码间接的关联起来,7,C/OS-II用任务控制块链表对任务进行管理,如下图所示:,8,C/OS-II的任务有两种:用户任务和系统任务。由应用程序设计者编写的任务,叫做用户任务;由系统提供的任务叫做系统任务。用户任务是为了解决应用问题而编写的;系统任务是为应用程序提供某种服务或为系统本身服务的。目前,在C/OS-II中,最

4、多可以含有64个任务(包括用户任务和系统任务)。,9, C/OS II 支持64个任务,每个任务有一个特定的优先级。 任务的优先级别用数字表示,0表示的任务的优先级最高,数字越大表示的优先级越低。 通过常数OS_LOWEST_PRIO (在OS_CFG.H中)定义系统的最低优先级别,同时限定系统能容纳的最多任务数量。 建议用户不要使用优先级为0、1、2、3、OS_LOWEST_PRIO-3、 OS_LOWEST_PRIO-2、 OS_LOWEST_PRIO-1、 OS_LOWEST_PRIO-0的任务。最低的两个已被目前版本的系统占用,将来版本可能会用到其它的。,10,3.1.2 任务的状态,

5、C/OS-II是按照系统中只有一个CPU来设计的,在这种系统中,一个具体时刻只会有一个任务占用,及处在运行状态,而其他任务只能处在其他状态。C/OS-II系统中的任务共有5种状态: 睡眠态(DORMANT):任务在没有被配备任务控制块或被剥夺了任务控制块时的状态叫作任务的睡眠态。 就绪态(READY):如果系统为任务配备了任务控制块且在任务就绪表中进行了就绪登记,则任务就具备了运行的充分条件,这时的任务的状态叫就绪态。,11, 运行态(RUNNING):处于就绪态的任务如果经调度器判断获得了CPU的使用权,则任务就进入运行态。任何时刻只能有一个任务处于运行态。 等待态(WAITING):正在运

6、行的任务,需要等待一段时间或需要等待一个事件发生再运行时,该任务就会把CPU的使用权让给其他任务而使任务进入waiting状态。 注:进入waiting的状态有可能是因为延时,有可能是被挂起,有可能是等待的资源未获得,总之,uC/OS将所有的已经注册了的但未就绪的任务归为waiting态。 被中断态(ISR):正在运行的任务是可以被中断的,除非该任务将中断关了,或者uC/OS-将中断关了。被中断了的任务就进入了中断服务态(ISR)。 当所有的任务都在等待事件发生或等待延迟时间结束,uC/OS-执行空闲任务(idle task),执行OSTaskIdle() 函数。,12,在系统的管理下,一个任

7、务可以在5个不同的状态之间发生转换。其转换关系如图所示,13,线上的函数作用:状态迁移依靠这些函数完成,14,3.1.3 用户任务代码的一般结构,1. 用户任务代码的一般结构 根据嵌入式系统任务的工作特点,任务的执行代码通常是一个无限循环结构(对于一些一次性任务例外),并且在这个循环中可以响应中断,这种结构也叫做超循环结构。例3-1就是一个具有超循环结构的任务的示意性代码。,15,例3-1 一个用C语言编写的任务 void MyTask(void * pdata) for( ; ; ) 可以被中断的用户代码; OS_ENTER_CRITICAL(); /进入临界段(关中断) 不可以被中断的用户

8、代码; OS_EXIT_CRITICAL(); /退出临界段(开中断) 可以被中断的用户代码; 从程序的角度来看,一个C/OS-II任务的代码就是一个C语言函数。之所以把任务的参数定义成一个void类型的指针,是为了传递各种不同类型的数据。,16,为了有效的对中断进行控制,在任务的代码里可使用uC/OS-II定义的宏OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()来控制何时响应中断,何时屏蔽中断。这两个宏之间的代码时是不会响应中断的,这种受保护的代码段叫临界段。 代码的临界段也称为临界区,指处理时不可分割的代码。一旦这部分代码开始执行,则不允许任何中断打入。为确保临

9、界段代码的执行不被中断,在进入临界段之前必须关中断,而临界段代码执行完后,要立即开中断。,17,2用户应用程序的一般结构 从程序代码来看,用户任务就是一个C语言函数,但这个函数不是自主函数main()调用的函数,在系统中它与主函数main()处于平等的地位,它们何时被运行以及何时被终止是由操作系统来调度的。但要注意,main()毕竟是一个应用程序的主函数,是程序运行的入口点,所以虽然它不调用任务,但要负责任务的创建并将它们交给系统,至于何时运行它们,则与主函数无关。,18,用户应用程序的代码大体如下: 例3-2 用户应用程序的结构 void MyTask1(void * pdata) /定义用

10、户任务1 for( ; ; ) void MyTask2(void * pdata) /定义用户任务2 for( ; ; ) ,19,void MyTask3(void * pdata) /定义用户任务3 for( ; ; ) void main() OSInit(); /初始化C/OS-II OSTaskCreate(MyTask1,); /创建用户任务1 OSTaskCreate(MyTask2,); /创建用户任务2 OSTaskCreate(MyTask3,); /创建用户任务3 OSStart(); /启动C/OS-II ,20,其中,OSTaskCreate()是C/OS-II提供

11、的用来创建任务的函数;OSStart()启动C/OS-II的函数。系统被启动后,任务就由操作系统来管理和调度了。,21,3.1.4 系统任务,作为管理者,操作系统除了要管理用户任务之外,可能会有一些内部事务需要处理,最起码要有一个没有用户任务可执行时需要做的事情,因为计算机是不能停下来的。为了与用户任务相区别,这种系统自己所需要的任务叫做系统任务。C/OS-II预定义了两个系统任务:空闲任务和统计任务。其中空闲任务是每个应用程序必须使用的,而统计任务则是应用程序可以根据实际需要来选择使用的。,22,1. 空闲任务 C/OS-II总要建立一个空闲任务(idle task),这个任务在没有其他任务

12、进入就绪状态时投入运行。这个空闲任务OSTaskIdle()永远设为最低优先级,即OS_LOWER_PRIO。空闲任务OSTaskIdle()的代码如下: void OSTaskIdle( void * pdata) pdata = pdata; /防止某些编译器报错 for(;) OS_ENTER_CRITICAL(); /关闭中断 OSIdleCtr+; /计数 OS_EXIT_CRITICAL(); /开放中断 C/OS-II规定,一个用户应用程序必须使用这个空闲任务,而且这个任务是不能用程序来删除的。,23,2统计任务 C/OS-II提供的另一个系统任务就是统计任务OSTaskStat

13、( ) OSTaskStat( )每秒运行1次,计算CPU利用率,即告诉用户应用程序使用了多少CPU时间,用百分比表示,精确度为1%。 如果将系统头文件OS_CFG.H中的系统配置常数OS_TASK_STAT_EN设置为1,统计任务就会在操作系统初始化函数OSInit( )中调用OS_InitTaskStat()函数创建。,24, 在系统调用多任务启动函数OSStart( )之前,用户初始代码中必须先建立至少一个用户任务(如TaskStart),如果应用程序打算使用统计任务,需要在TaskStart任务中调用函数 OSStatInit( )对统计任务进行初始化。之后再建立应用程序中的其他任务。

14、 应该在用户任务中(第一个任务)启动时钟节拍。因为用户不希望在多任务还没有开始时就收到时钟节拍中断,25,void main (void) OSInit(); /初 始化uC/OS-II /* 创建用户起始任务(以TaskStart()作为起始任务,也可以创建多个任务)*/ OSStart(); /开 始多任务调度 void TaskStart (void *pdata) /* 在这里安装并启动uC/OS-II的时钟节拍 */ OSStatInit(); / 初始化统计任务 /* 创建用户应用程序任务 */ for (;) /* 这里是TaskStart()的代码 */ OSTimeDly(1

15、0); /调用该函数的任务将自己延时10个时钟并执行一次任务调度 ,26,3.1.5 任务的优先权及优先级别,uC/OS-II分为64个优先级别,每一个级别都用一个数字表示。数字0的级别最高,数字越大优先级别越低。 通常,一个应用程序的任务数小于64,用户可根据应用程序的需要,在OS_CFG.H中设置OS_LOWEST_PRIO,即定义了可供使用的优先级别共OS_LOWEST_PRIO +1个。 固定地,系统总是把最低优先级别自动赋给空闲任务,如果系统中还有统计任务,则其优先级别为OS_LOWEST_PRIO -1。因此用户任务可以使用的优先级别是0,1,2,.,OS_LOWEST_PRIO-

16、2,共OS_LOWEST_PRIO-1个,27,例:如果希望应用程序中任务的优先级别为28个,则表示最低优先级别的常数OS_LOWEST_PRIO值应该是多少?如果应用程序中使用了系统提供的空闲任务和统计任务,则该应用程序最多可以安排多少个任务?,28,答:表示最低优先级别的常数OS_LOWEST_PRIO值应该为27,优先级别分别为0,1,2,3,.,27;由于系统空闲任务占用了优先级别27,统计任务占用了优先级别26,则应用程序中最多可以安排优先级别分别为0,1,2,.,25的26个任务。,29,给某一个用户任务的定义优先级别,需要在调用系统函数OSTaskCreate()来创建任务时,用

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 高等教育 > 大学课件

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号