54时间片轮询多任务操作系统_第1页
54时间片轮询多任务操作系统_第2页
54时间片轮询多任务操作系统_第3页
54时间片轮询多任务操作系统_第4页
54时间片轮询多任务操作系统_第5页
已阅读5页,还剩26页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、5.4 时间片轮询多任务操作系统 目 录1概述概述 2整体规划整体规划 3任务控制块任务控制块 4内部变量初始化内部变量初始化 5创建任务创建任务6启动多任务环境启动多任务环境 longjmpInIsr() 9任务调度任务调度 7时钟节拍中断时钟节拍中断 8任务延时任务延时 10删除任务删除任务 11运行的任务难以得知其他任务状态,任务切换时机难以把握。如果一个任务死掉,势必造成整个系统死掉。协作式多任务系统 任务任务 协作式多任务系统的特点 安全安全性性 复杂复杂性性 协作式多任务系统中,任务切换需正在运行的任务主动让出CPU,这不仅带来一些安全隐患,而且使程序设计相当的复杂。任务任务调度调

2、度任务调度交给操作系统,引入任务调度交给操作系统,引入调度算法调度算法 调度算法 时间片轮询时间片轮询 1优先级调度优先级调度2带优先级调度的时间片轮询带优先级调度的时间片轮询 3调度算法 时间片轮询时间片轮询 1t t 任务的运行时间 时间片轮询系统中任务运行情况 在时间片轮询操作系统中,CPU的执行时间被划分为若干时间片,然后让处于就绪状态的任务,按顺序轮流占用CPU。当时间片用完时,即使任务未执行完,系统也剥夺此任务的CPU使用权力。时间片长度时间片长度t一般为一般为110ms 优先级调度优先级调度2带优先级调度的时间片轮询带优先级调度的时间片轮询 3任务A 任务B任务C 所有任务相同对

3、待,分时运行。调度算法 时间片轮询时间片轮询 1优先级调度优先级调度2带优先级调度的时间片轮询带优先级调度的时间片轮询 3+ 低低优先级优先级 + 中中优先级优先级 + 高高优先级优先级 任务A 任务B任务C t 高高优先级任务优先级任务先先运行运行 t 高高优先级任务优先级任务抢占抢占低优先级任务低优先级任务 不同任务不同对待,优先级高任务的先运行。调度算法 时间片轮询时间片轮询 1优先级调度优先级调度2带优先级调度的时间片轮询带优先级调度的时间片轮询 3 这种调度算法情况较复杂,类型较多,自己去学习了解。任务切换时机 分配给任务的时间片已到分配给任务的时间片已到 任务主动请求调度任务主动请

4、求调度 12 任务在调用操作系统提供的“管理”类服务(如删除任务等)和“等待”类服务(如延时、获取信号量、等待消息等)时,会主动请求调度。 操作系统采用一个周期性的中断来管理时间片,在这个中断服务函数中,判断运行的任务是否用完了时间片。使用时间片轮询调度的操作系统中,会在两种下进行任务切换。 目 录2整体规划整体规划 1概述概述 34任务控制块任务控制块 内部变量初始化内部变量初始化 时间片轮询操作系统规划 时间片轮询时间片轮询调度算法调度算法时间片轮询时间片轮询多任务多任务操作系统操作系统协作式协作式多任务系统多任务系统 TinyOS51 V1.0 TinyOS51 V1.1 TinyOS5

5、1 V1.1采用最简单的时间片轮询调度算法,在每个时钟节拍中断时调度,即分配给任务的时间片为一个时钟节拍。 这样,在任务控制块中不仅不需要保存时钟任务剩余的时钟节拍,而且也不必编写计算任务的剩余时间和设置任务时间片的代码。TinyOS51从V1.0到V1.1的改变 TinyOS51 V1.0TinyOS51 v1.1任务调度函数任务调度函数tnOsSched()_tnOsSched()任务延时函数任务延时函数无tnOsTimeDly()时钟节拍处理函数时钟节拍处理函数无tnOsTimeTick()TinyOS51 V1.0和TinyOS51 V1.1的API不同点 提供操作系统的一种基本服务延

6、时服务,延时以时钟节拍为单位。 在TinyOS51中,时钟节拍中断由用户实现,在时钟节拍中断处理函数中调用tnOsTimeTick()。void task0(void) TMOD = (TMOD & 0 xF0) | 0 x01; TL0 = 0 x00; / TH0 = 0 x00; / 初始化初始化timer0,即,即 TR0 = 1; / 初始化时钟节拍初始化时钟节拍 ET0 = 1; / 中断。中断。 TF0 = 0; / while (1) _GucTask0+; /* * 一个简单的任务,无限循环中让一个简单的任务,无限循环中让 * _GucTask0+。 */void t

7、ask1(void) while (1) _GucTask0+; /* * 用户实现时钟节拍中断服务函数,用户实现时钟节拍中断服务函数, * 并调用并调用tnOsTimeTick()。 */void timer0ISR(void) _interrupt1 tnOsTimeTick();/* * 1. 初始化系统初始化系统 * 2. 创建任务创建任务 * 3. 启动系统启动系统 */void main(void) tnOsInit(); tnOsTaskCreate(task0, _GucTaskStks0; tnOsTaskCreate(task1, _GucTaskStk1); tnOsSt

8、art();资源配置与示例 n任务函数任务函数 task0()和和task1() n时钟节拍中断服务函数时钟节拍中断服务函数timer0ISR() nmain函数函数 main() static idata unsigned char _GucTaskStk232;static unsigned char _GucTask0;static unsigned char _GucTask1;/ 分配任务堆栈分配任务堆栈/ 任务任务0测试变量测试变量 / 任务任务1测试变量测试变量 全局变量定义全局变量定义 函数实现函数实现 目 录3任务控制块任务控制块 45内部变量初始化内部变量初始化 创建任务创

9、建任务 12概述概述 整体规划整体规划任务控制块 TinyOS51 V1.1增加了延时服务功能,因此,在TCB中增加了一个记录时间的成员uiTicks。#define _TN_TASK_FLG_DEL 0 x00 / 任务被删除任务被删除#define _TN_TASK_FLG_RDY 0 x01 / 任务就绪任务就绪#define _TN_TASK_FLG_DLY 0 x02 / 任务延时任务延时struct tn_os_tcb jmp_buf jbTaskContext; / 任务上下文任务上下文 unsigned char ucTaskStat; / 任务状态任务状态 unsigned

10、int uiTicks; / 任务延时时间任务延时时间 ;typedef struct tn_os_tcb TN_OS_TCB;static data TN_OS_TCB _GtcbTasksTN_OS_MAX_TASKS; / 任务控制块数组任务控制块数组与任务控制块相关代码: 目 录4内部变量初始化内部变量初始化 56创建任务创建任务 启动多任务环境启动多任务环境 23整体规划整体规划 任务控制块任务控制块 tnOsInit() void tnOsInit (void) TN_OS_TASK_HANDLE thTask; / 操作的任务操作的任务 for (thTask = 0; thTa

11、sk TN_OS_MAX_TASKS; thTask+) _GtcbTasksthTask.ucTaskStat = _TN_TASK_FLG_DEL; / 任务初始处于删除状态任务初始处于删除状态 _GtcbTasksthTask.uiTicks = 0; / 设置初值设置初值 _GthTaskCur = 0; / 初始运行初始运行0号任务号任务 由于TCB增加了一个uiTicks,则在tnOsInit()中进行初始化。 OS初始化函数代码: 目 录5创建任务创建任务67启动多任务环境启动多任务环境 任务调度任务调度 34任务控制块任务控制块内部变量初始化内部变量初始化 通常,为了提高可移植

12、性,采用一个宏或函数来编写实现开中断和关中断程序。由于TinyOS51仅适合80C51系列单片机,故直接使用“EA=0”和“EA=1”。创建任务函数tnOsTaskCreate() 由于tnOsTaskCreate()要操作TCB,而时钟节拍中断中也要操作TCB,因此tnOsTaskCreate()中操作TCB的代码为临界区代码,要避免被时钟节拍中断打断。 TinyOS51中采用开开/关中断关中断的方式解决此问题。TN_OS_TASK_HANDLE tnOsTaskCreate(void (*pfuncTask)(void), idata unsgined char *pucStk)TN_OS

13、_TASK_HANDLE thRt;for (thRt = 0; thRt TN_OS_MAX_TASKS; thRt+) EA = 0; / 禁止中断禁止中断if (_GtcbTasksthRt.ucTaskStat = _TN_TASK_FLG_DEL) setTaskJmp(pfuncTask, pucStk, _GtcbTasksthRt.jbTaskContext); _GtcbTaskthRt.ucTaskStat = _TN_TASK_FLG_RDY; EA = 1; / 允许中断允许中断 return thRt;EA = 1; / 允许中断允许中断 目 录6启动多任务环境启动多

14、任务环境 78任务调度任务调度 时钟节拍中断时钟节拍中断 45内部变量初始化内部变量初始化 创建任务创建任务 tnOsStart() 在TinyOS51 V1.1中,如果不允许中断,则时钟节拍中断服务程序不会运行,因此,在tnOsStart()中增加允许中断的代码。 void tnOsStart (void) EA = 1; / 允许中断允许中断longjmp (_GtcbTask0.jbTaskContext); / 执行执行0号任务号任务 tnOsInit()中_GthTaskCur = 0,即当前运行任务为0号任务。 目 录7任务调度任务调度 89时钟节拍中断时钟节拍中断 longjmp

15、InIsr() 56创建任务创建任务 启动多任务环境启动多任务环境 _tnOsSched() tnOsSched() 开开/关中断代码关中断代码_tnOsSched() TinyOS51 V1.0 TinyOS51 V1.1 任务调度函数_tnOsSched()中也要操作TCB,因此也需要加入开/关中断代码包含临界区。另外,_tnOsSched()不再提供给任务直接调用,仅供内部调用,因此添加前缀“_”。保护临界资源保护临界资源 目 录8时钟节拍中断时钟节拍中断 9longjmpInIsr() 任务延时任务延时 67启动多任务环境启动多任务环境 任务调度任务调度 10 如果uiTicks不为0

16、,则uiTicks-,即缩短延时时间。未使用任务状态标志判断任务是否处于延时状态。这是因为TinyOS51更高的版本具有超时功能,需要使用uiTicks来判断任务是否超时。 如果uiTicks为0,则将任务设置为就绪状态。为了向上兼容超时代码,即区分系统服务是正常返回还是超时返回,未直接将任务设置为就绪状态,而使用“|=”操作。时钟节拍中断 大多数操作系统中的延时管理和中断服务程序中的任务切换功能,分别是用两个函数实现的,由于TinyOS51 V1.1是纯粹的时间片轮询操作系统,非时钟节拍中断的中断服务程序不进行任务切换操作,因此将二者合二为一。 for (thTask = 0; thTask

17、 TN_OS_MAX_TASKS;thTask+) if (_GtcbTasksthTask.uiTicks != 0) _GtcbTasksthTask.uiTicks-; / 缩短延时时间缩短延时时间 if (_GtcbTasksthTask.uiTicks = 0) _GtcbTasksthTask.ucTaskStat |= _TN_TASK_FLG_RDY; / 设置任务就绪状态位设置任务就绪状态位 延时管理延时管理 1任务切换任务切换 2 对于80C51来说,规定:一般函数返回使用RET指令,而中断返回使用RETI指令。由于longjmp()函数是使用RET指令返回的,如果在时钟节

18、拍中断中继线使用longjmp(),则任务切换后CPU会认为中断仍未退出,同级中断(包括自身)将被屏蔽,从而造成整个系统执行错误。因此必须将longjmp()函数改为longjmpInIsr()。时钟节拍中断 大多数操作系统中的延时管理和中断服务程序中的任务切换功能,分别是用两个函数实现的,由于TinyOS51 V1.1是纯粹的时间片轮询操作系统,非时钟节拍中断的中断服务程序不进行任务切换操作,因此将二者合二为一。 for (thTask = 0; thTask = TN_OS_MAX_TASKS) thTmp2 = 0; if (_GtcbTasksthTmp2.ucTaskStat &am

19、p; _TN_TASK_FLG_RDY) != 0) cTmp1 = setjump(_GtcbTask_GthTaskCur.jbTaskContext); / 保持上下文保持上下文 if (cTmep1 = 0) _GthTaskCur = thTmp2; longjmpInIsr(_GtcbTasksthTmp2.jbTaskContext); / 中断中切换上下文中断中切换上下文 延时管理延时管理 1任务切换任务切换 2 目 录9longjmpInIsr() 任务延时任务延时 删除任务删除任务 78任务调度任务调度 时钟节拍中断时钟节拍中断 1110中断中切换任务 在中断中切换任务,不

20、能再使用longjmp(),因为中断需要使用专用返回指令RETI,非RET指令。char longjmpInIsr (jmp_buf Buf) _naked unsigned char ucSpSave; / 用于保存堆栈指针的变量用于保存堆栈指针的变量 data unsigned char *pucBuf = (data void *)0; / 指向上下文信息存储位置的指针指向上下文信息存储位置的指针 pucBuf = (data unsigned char *)jbBuf; ucSpSave = *pucBuf+; bp = *pucBuf+; *(data unsigned char *

21、)(char)(ucSpSave) = *pucBuf+; *(data unsigned char *)(char)(ucSpSave 1) = *pucBuf; SP = ucSpSave; DPL = 1; _asm RETI _endasm;将将DPL设置为设置为1 ,使返回值为,使返回值为1。因为。因为SDCC51规定:规定:char类型返回值保存在类型返回值保存在DPL中。中。采用采用_naked修饰,表示此函数是无保修饰,表示此函数是无保护的,即编译器不会生成此函数的起护的,即编译器不会生成此函数的起始和结尾代码。使用者将完全控制这始和结尾代码。使用者将完全控制这个过程,这里用于加入个过程,这里用于加入RETI指令。指令。 目 录任务延时任务延时 删除任务删除任务 78时钟节拍中断时钟节拍中断 longjmpInIsr() 1110任务延时函数tnOsTimeDly() void delay ( unsigned int uiDly) unsigned int i, j; for

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论