《时间片轮询多任务操作系统教材dpoj.pptx》由会员分享,可在线阅读,更多相关《时间片轮询多任务操作系统教材dpoj.pptx(31页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
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 这种调度算法情况较复杂,类型较多,自己去学习了解。任务切换时机 分配给任务的时间片已到分配给任务的时间片已到 任务主动请求调度任务主动请求调度 12
4、 任务在调用操作系统提供的“管理”类服务(如删除任务等)和“等待”类服务(如延时、获取信号量、等待消息等)时,会主动请求调度。操作系统采用一个周期性的中断来管理时间片,在这个中断服务函数中,判断运行的任务是否用完了时间片。中断中中断中中断中中断中切换任务切换任务切换任务切换任务 使用时间片轮询调度的操作系统中,会在两种下进行任务切换。目 录2整体规划整体规划 1概述概述 34任务控制块任务控制块 内部变量初始化内部变量初始化 时间片轮询操作系统规划 时间片轮询时间片轮询调度算法调度算法时间片轮询时间片轮询多任务多任务操作系统操作系统协作式协作式多任务系统多任务系统 TinyOS51 V1.0
5、TinyOS51 V1.1 TinyOS51 V1.1采用最简单的时间片轮询调度算法,在每个时钟节拍中断时调度,即分配给任务的时间片为一个时钟节拍。这样,在任务控制块中不仅不需要保存时钟任务剩余的时钟节拍,而且也不必编写计算任务的剩余时间和设置任务时间片的代码。TinyOS51从V1.0到V1.1的改变 TinyOS51 V1.0TinyOS51 v1.1任务调度函数任务调度函数tnOsSched()_tnOsSched()任务延时函数任务延时函数无tnOsTimeDly()时钟节拍处理函数时钟节拍处理函数无tnOsTimeTick()TinyOS51 V1.0和TinyOS51 V1.1的A
6、PI不同点 提供操作系统的一种基本服务延时服务,延时以时钟节拍为单位。在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 task1(void)while(1)
7、_GucTask0+;/*用户实现时钟节拍中断服务函数,用户实现时钟节拍中断服务函数,*并调用并调用tnOsTimeTick()。*/void timer0ISR(void)_interrupt1 tnOsTimeTick();/*1.初始化系统初始化系统*2.创建任务创建任务*3.启动系统启动系统*/void main(void)tnOsInit();tnOsTaskCreate(task0,_GucTaskStks0;tnOsTaskCreate(task1,_GucTaskStk1);tnOsStart();资源配置与示例 n任务函数任务函数 task0()和和task1()n时钟节拍中
8、断服务函数时钟节拍中断服务函数timer0ISR()nmain函数函数 main()static idata unsigned char _GucTaskStk232;static unsigned char _GucTask0;static unsigned char _GucTask1;/分配任务堆栈分配任务堆栈/任务任务0测试变量测试变量/任务任务1测试变量测试变量 全局变量定义全局变量定义 函数实现函数实现 目 录3任务控制块任务控制块 45内部变量初始化内部变量初始化 创建任务创建任务 12概述概述 整体规划整体规划任务控制块 TinyOS51 V1.1增加了延时服务功能,因此,在T
9、CB中增加了一个记录时间的成员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 int uiTicks;/任务延时时间任务延时时间;typedef struct tn_os_tcb TN_OS_TCB
10、;static data TN_OS_TCB _GtcbTasksTN_OS_MAX_TASKS;/任务控制块数组任务控制块数组与任务控制块相关代码:目 录4内部变量初始化内部变量初始化 56创建任务创建任务 启动多任务环境启动多任务环境 23整体规划整体规划 任务控制块任务控制块 tnOsInit()void tnOsInit(void)TN_OS_TASK_HANDLE thTask;/操作的任务操作的任务 for(thTask=0;thTask TN_OS_MAX_TASKS;thTask+)_GtcbTasksthTask.ucTaskStat=_TN_TASK_FLG_DEL;/任务
11、初始处于删除状态任务初始处于删除状态 _GtcbTasksthTask.uiTicks =0;/设置初值设置初值 _GthTaskCur=0;/初始运行初始运行0号任务号任务 由于TCB增加了一个uiTicks,则在tnOsInit()中进行初始化。OS初始化函数代码:目 录5创建任务创建任务67启动多任务环境启动多任务环境 任务调度任务调度 34任务控制块任务控制块内部变量初始化内部变量初始化 通常,为了提高可移植性,采用一个宏或函数来编写实现开中断和关中断程序。由于TinyOS51仅适合80C51系列单片机,故直接使用“EA=0”和“EA=1”。创建任务函数tnOsTaskCreate()
12、由于tnOsTaskCreate()要操作TCB,而时钟节拍中断中也要操作TCB,因此tnOsTaskCreate()中操作TCB的代码为临界区代码,要避免被时钟节拍中断打断。TinyOS51中采用开开/关中断关中断的方式解决此问题。TN_OS_TASK_HANDLE tnOsTaskCreate(void(*pfuncTask)(void),idata unsgined char*pucStk)TN_OS_TASK_HANDLE thRt;for(thRt=0;thRt TN_OS_MAX_TASKS;thRt+)EA=0;/禁止中断禁止中断if(_GtcbTasksthRt.ucTaskS
13、tat=_TN_TASK_FLG_DEL)setTaskJmp(pfuncTask,pucStk,_GtcbTasksthRt.jbTaskContext);_GtcbTaskthRt.ucTaskStat=_TN_TASK_FLG_RDY;EA=1;/允许中断允许中断 return thRt;EA=1;/允许中断允许中断 目 录6启动多任务环境启动多任务环境 78任务调度任务调度 时钟节拍中断时钟节拍中断 45内部变量初始化内部变量初始化 创建任务创建任务 tnOsStart()在TinyOS51 V1.1中,如果不允许中断,则时钟节拍中断服务程序不会运行,因此,在tnOsStart()中增
14、加允许中断的代码。void tnOsStart(void)EA=1;/允许中断允许中断longjmp(_GtcbTask0.jbTaskContext);/执行执行0号任务号任务 tnOsInit()中_GthTaskCur =0,即当前运行任务为0号任务。目 录7任务调度任务调度 89时钟节拍中断时钟节拍中断 longjmpInIsr()56创建任务创建任务 启动多任务环境启动多任务环境 _tnOsSched()tnOsSched()开开/关中断代码关中断代码_tnOsSched()TinyOS51 V1.0 TinyOS51 V1.1 任务调度函数_tnOsSched()中也要操作TCB,
15、因此也需要加入开/关中断代码包含临界区。另外,_tnOsSched()不再提供给任务直接调用,仅供内部调用,因此添加前缀“_”。保护临界资源保护临界资源 目 录8时钟节拍中断时钟节拍中断 9longjmpInIsr()任务延时任务延时 67启动多任务环境启动多任务环境 任务调度任务调度 10如果uiTicks不为0,则uiTicks-,即缩短延时时间。未使用任务状态标志判断任务是否处于延时状态。这是因为TinyOS51更高的版本具有超时功能,需要使用uiTicks来判断任务是否超时。如果uiTicks为0,则将任务设置为就绪状态。为了向上兼容超时代码,即区分系统服务是正常返回还是超时返回,未直
16、接将任务设置为就绪状态,而使用“|=”操作。时钟节拍中断 大多数操作系统中的延时管理和中断服务程序中的任务切换功能,分别是用两个函数实现的,由于TinyOS51 V1.1是纯粹的时间片轮询操作系统,非时钟节拍中断的中断服务程序不进行任务切换操作,因此将二者合二为一。for(thTask=0;thTask TN_OS_MAX_TASKS;thTask+)if(_GtcbTasksthTask.uiTicks!=0)_GtcbTasksthTask.uiTicks-;/缩短延时时间缩短延时时间 if(_GtcbTasksthTask.uiTicks=0)_GtcbTasksthTask.ucTas
17、kStat|=_TN_TASK_FLG_RDY;/设置任务就绪状态位设置任务就绪状态位 延时管理延时管理 1任务切换任务切换 2 对于80C51来说,规定:一般函数返回使用RET指令,而中断返回使用RETI指令。由于longjmp()函数是使用RET指令返回的,如果在时钟节拍中断中继线使用longjmp(),则任务切换后CPU会认为中断仍未退出,同级中断(包括自身)将被屏蔽,从而造成整个系统执行错误。因此必须将longjmp()函数改为longjmpInIsr()。时钟节拍中断 大多数操作系统中的延时管理和中断服务程序中的任务切换功能,分别是用两个函数实现的,由于TinyOS51 V1.1是纯
18、粹的时间片轮询操作系统,非时钟节拍中断的中断服务程序不进行任务切换操作,因此将二者合二为一。for(thTask=0;thTask=TN_OS_MAX_TASKS)thTmp2=0;if(_GtcbTasksthTmp2.ucTaskStat&_TN_TASK_FLG_RDY)!=0)cTmp1=setjump(_GtcbTask_GthTaskCur.jbTaskContext);/保持上下文保持上下文 if(cTmep1=0)_GthTaskCur=thTmp2;longjmpInIsr(_GtcbTasksthTmp2.jbTaskContext);/中断中切换上下文中断中切换上下文 延
19、时管理延时管理 1任务切换任务切换 2 目 录9longjmpInIsr()任务延时任务延时 删除任务删除任务 78任务调度任务调度 时钟节拍中断时钟节拍中断 1110中断中切换任务 在中断中切换任务,不能再使用longjmp(),因为中断需要使用专用返回指令RETI,非RET指令。char longjmpInIsr(jmp_buf Buf)_naked unsigned char ucSpSave;/用于保存堆栈指针的变量用于保存堆栈指针的变量 data unsigned char*pucBuf =(data void*)0;/指向上下文信息存储位置的指针指向上下文信息存储位置的指针 puc
20、Buf =(data unsigned char*)jbBuf;ucSpSave =*pucBuf+;bp =*pucBuf+;*(data unsigned char*)(char)(ucSpSave)=*pucBuf+;*(data unsigned char*)(char)(ucSpSave 1)=*pucBuf;SP =ucSpSave;DPL=1;_asm RETI _endasm;将将DPL设置为设置为1,使返回值为,使返回值为1。因为。因为SDCC51规定:规定:char类型返回值保存在类型返回值保存在DPL中。中。采用采用_naked修饰,表示此函数是无保修饰,表示此函数是无保
21、护的,即编译器不会生成此函数的起护的,即编译器不会生成此函数的起始和结尾代码。使用者将完全控制这始和结尾代码。使用者将完全控制这个过程,这里用于加入个过程,这里用于加入RETI指令。指令。目 录任务延时任务延时 删除任务删除任务 78时钟节拍中断时钟节拍中断 longjmpInIsr()1110任务延时函数tnOsTimeDly()void delay(unsigned int uiDly)unsigned int i,j;for(i=0;i uiDly;i+)for(j=0;j 1000;j+)CPU处于空转状态,效率太低。传统延时传统延时 void tnOsTimeDly(unsigned
22、 int uiTick)if(uiTick!=0)EA=0;_GtcbTasks_GthTaskCur.ucTaskStat =_TN_TASK_FLG_DLY;_GtcbTasks_GthTaskCur.uiTick =uiTick;EA=1;_tnOsSched();_GtcbTasks_GthTaskCur.ucTaskStat =_TN_TASK_FLG_RDY;/延时结束任务延时任务延时 切换到其他任务运行切换到其他任务运行设置延时时间,让时钟节拍处理设置延时时间,让时钟节拍处理函数函数tnOsTimeTick()更新剩余更新剩余的延时时间。的延时时间。目 录删除任务删除任务 任务延时任务延时 78时钟节拍中断时钟节拍中断 longjmpInIsr()1011删除任务函数tnOsTaskDel()与V1.0版本相比,TinyOS51 V1.1 版本在tnOsTaskDel()函数中增加了初始化uiTicks和开/关中断代码。void tnOsTaskDel(TN_OS_TASK_HANDLE thTask).EA=0;_GtcbTasksthTask.ucTaskStat=_TN_TASK_FLG_DEL;_GtcbTasksthTask.uiTicks =0;EA=1;if(thTask=_GthTaskCur)_tnOsSched();