二、任务管理

任务管理是ucos-ii操作系统的核心内容。这一章大致就以下流程来介绍和总结任务管理的相关知识。

要实现复杂任务管理,必然要定义众多数据来描述任务状态,为了精简,建立了许多不同的数据结构,所以第一步就是了解这些数据结构和构成。为了避免枯燥,我们同时要认识到每一种结构具体起到什么作用,感受其中的精妙之处,这样理解起来就更容易了。

建立完必要的数据结构,程序在OS_TCBInit()中对TCB进行初始化,在OSInit()中对操作系统的其他重要数据结构进行初始化。

操作系统在启动和运行过程中,会调用一系列任务管理相关函数,我们通过对这些函数的功能认识进一步了解任务管理的具体实现。

最后我们会再次梳理任务管理从初始化到运行过程中任务切换的整个流程。

1.要了解的数据结构

1>任务控制块TCB(Task Control Block)

任务控制块是最核心的数据结构,定义为一个结构体,每一个任务对应一个TCB,包含了堆栈指针、下一个TCB指针、事件块指针、任务状态、任务优先级等一系列信息。

2>空闲链表和就绪链表

空闲链表和就绪链表是由各个TCB构成的链表,所有已经创建任务的TCB分配到就绪链表,其他分配到空闲链表,每建立一个任务就从空闲链表取一个TCB给到就绪链表,每删除一个任务就将该任务TCB释放回空闲链表。

3>任务优先级指针表OSTCBPrioTb1[OS_LOWEST_PRIO+1]

即任务优先级指针数组,类型为指向TCB的指针,用来获取某优先级任务对应的TCB地址.例如任务优先级为5,其  TCB地址将存入OSTCBPrioTb1[5]。

4>任务堆栈

每个任务都有自己的堆栈空间,用于任务切换或者响应中断时保存CPU寄存器数据和私有数据。堆栈必须声明为OS_STK类型,并且由连续的内存空间组成。

5>任务就绪表OSRdyTab1[]和就绪组OSRdyGrp

为了快速找到当前就绪任务中最高优先级的任务设置了任务就绪表和就绪组,就绪表中每一位以1表示就绪,0表示未就绪。通过设定好的OSMapTb1[]和OSUnMapTb1[]两个常量数组和既定操作可以快速获取就绪任务中的最高优先级。具体结构如下图所示。

6>初始化

OS_TCBInit():TCB初始化函数,创建任务时会分配一个TCB,并对其进行初始化;

OSInit():操作系统的初始化函数,内部又分为多个子函数,包含了对全局变量,就绪表,就绪组,任务优先级指针表,事件标志组,内存,消息队列等的初始化。

2.主要相关函数简介

1>   OS_TaskCreate()    基本任务创建;

2>   OS_TaskCreateExt() 拓展任务创建;

3>   OSTaskDel ()       删除任务(任务返回并处于休眠状态,而不是删除代码);

4>   OSTaskDelReq()    请求删除任务(一般用于删除任务前释放资源);

5>   OSTaskSuspend()   挂起任务(用来暂时停止任务的执行,将其阻塞掉);

6>   OSTaskResume()   恢复任务(将被挂起的任务恢复到就绪态);

7>   OSTimeTick()      任务调度器,每隔一段时间(如20ms)执行一次;

8>   OS_Sched()        任务切换函数,判断切换条件满足后执行OS_TASK_SW();

9>   OS_TASK_SW()     汇编语言编写,压栈和退栈操作,真正转到新任务执行;

10> OSIntExit() 中断中的任务调度函数,判断切换条件满足后执行OSIntCtxSw()

11> OSIntCtxSw()      与CPU相关,实现中断程序中的任务切换

3. 任务管理和调度流程

任务状态转换如下图所示:

任务通过不同的函数调用以及当前情况在不同状态之间切换。图中创建任务,删除任务与第二节中1> OS_TaskCreate()、2> OS_TaskCreateExt()和3> OSTaskDel ()、4> OSTaskDelReq()相对应,事件等待中包含但不局限于OSTaskSuspend(),任务在等待信号量,邮箱或者系统延时时都会被阻塞进入阻塞态。等待的发生包含但不局限于OSTaskResume(),任务接收到信号量,邮箱以及延时完毕进行任务调度会从阻塞态转到就绪态。

任务运行中被中断打断会进入挂起态,中断服务程序结束后执行任务调度使当前最高优先级的就续任务得到运行。被挂起的任务仍为最高优先级,则返回。

OSTimeTick()为任务调度器,实际上是定时器中断,在每个时间片开始遍历每一个任务,将被设置了时间延时的任务延时时间减1,设置满足条件的任务进入就绪态。在发现有更高优先级的就续任务时则执行一次任务调度。

OS_Sched()执行普通任务切换(任务创建,自我删除和自我阻塞时会进行的任务调度),首先判断切换条件,若ISR未完成,调度器上锁或者当前任务即为最高优先级则不会进行切换。OS_Sched()中OS_TASK_SW()用于保存上下文,实现真正转到新任务执行。

OSIntExit()用于在时钟中断中进行任务调度,类似于OS_Sched()首先判断切换条件,若满足则执行OSIntCtxSw()进行任务切换。OSTimeTick()任务调度器就属于中断方式进行的调度。

空闲任务OS_TaskIdle()(操作系统必须的)和统计任务OS_TaskStart()(非必须)是两个系统两个自带的任务,保证CPU不会无事可干和监控CPU运行情况。

4.总结:

     任务管理从任务控制块TCB等数据结构定义和初始化开始,进一步执行操作系统的初始化。多任务启动后,通过任务创建,删除,挂起,恢复等操作和其他事件信息操作使得任务在不同状态间切换。对于CPU来说,每次状态转换都伴随一次任务调度,内核会选择当前就续任务中最高优先级的任务执行,一直处于动态运转中。

μCos-ii学习笔记2_任务管理的更多相关文章

  1. UC_OS II学习笔记

    是一个可以基于ROM运行的.可裁减的.抢占式.实时.多任务OS内核: 可剥夺型的实时内核在任何时候都运行就绪了的最高优先级的任务. 一个任务,也称作一个线程,是一个简单的程序,该程序可以认为 CPU ...

  2. python学习笔记2_条件循环和其他语句

    一.条件循环和其他语句 1.print和import的更多信息. 1.1.使用逗号输出  //print() 打印多个表达式是可行的,用逗号隔开.       在脚本中,两个print语句想在一行输出 ...

  3. Arria10 SDI II学习笔记

    12G-SDI16是什么意思? 关于 int_vpid_byte1 int_vpid_byte2 int_vpid_byte3 int_vpid_byte4 这些参数是不是如果外部数据有就不需要传输, ...

  4. JS学习笔记2_面向对象

    1.对象的定义 ECMAScript中,对象是一个无序属性集,这里的“属性”可以是基本值.对象或者函数 2.数据属性与访问器属性 数据属性即有值的属性,可以设置属性只读.不可删除.不可枚举等等 访问器 ...

  5. JavaScript学习笔记2_面向对象

    1.对象的定义 ECMAScript中,对象是一个无序属性集,这里的“属性”可以是基本值.对象或者函数 2.数据属性与访问器属性 数据属性即有值的属性,可以设置属性只读.不可删除.不可枚举等等 访问器 ...

  6. Angularjs学习笔记2_添加删除DOM元素

    1.调用element方法     angular.element(html) 把字符串或dom对象转化成一JQuery对象, angular.element(document.getElementB ...

  7. Python学习笔记2_一些小程序

    counts = [98,12,3,4,1,4,9,3821] minNum = min(counts) #print minNum minNum_index = counts.index(minNu ...

  8. C++学习笔记2_函数.函数指针.函数模板

    1. 内联函数void printAB(int a,int b){ cout<<(a)<<(b)<<endl;}int main(void){ for(int i= ...

  9. python学习笔记2_二元运算符和比较运算

    一.二元操作符 a+b : a加b a-b :  a减b a*b :  a乘b a/b : a除以b a//b:a整除以b,表示的是返回a除以b的结果的整数部分,而不是证明了a能被b整除.要证明a能被 ...

随机推荐

  1. jQuery的animate在火狐浏览器上不支持backgroundPositionX的解决方法

    在网上找的ffSupp.js文件 /** * 自定义backgroundPosition的animate,支持火狐,jQuery1.8以上版本 * @author Meleong * v1.00 */ ...

  2. Jquery跨域调用后台方法

    //前端JS function CallHandlerByJquery() { var url = "http://" + window.location.hostname + & ...

  3. HDU-1757--A Simple Math Problem(矩阵乘法)

    Problem Description Lele now is thinking about a simple function f(x).If x < 10 f(x) = x.If x > ...

  4. android 操蛋的gradle

    首先看语法: -include {filename} 从给定的文件中读取配置参数 -basedirectory {directoryname} 指定基础目录为以后相对的档案名称 -injars {cl ...

  5. 对adapter的封装优化

    一般不优化的adapter通常继承自BaseAdapter会出现一下几个问题: getCount(), getItem(), getItemId()代码都要去重写,一个adapter还行,如果adap ...

  6. iOS开发讯飞语音的集成

    1.进入官网注册账号,登陆,注册,应用. 2,下载sdk  导入系统库. 3,关闭bitcode 4,初始化讯飞语音. NSString * initString = [[NSString alloc ...

  7. CSS3的基础知识点

    面临找工作之际,又将CSS3的基础知识撸了一把,做了相应的笔记,主要是方便自己查阅,参考的是W3C的知识.    1.CSS背景 (1).background-size 属性 background-s ...

  8. 一个ubuntu命令

      curl 获取web curl www.baidu.com

  9. socket的accept函数解析

    今天与同学争执一个话题:由于socket的accept函数在有客户端连接的时候产生了新的socket用于服务该客户端,那么,这个新的socket到底有没有占用一个新的端口? 讨论完后,才发现,自己虽然 ...

  10. Queues 队列

    1. Definiation What is a queue? A queue is a list. With a queue, inseration is done at one end (know ...