当前位置:首页 > 申请书大全 > μC\OS-Ⅱ操作系统的任务切换|
 

μC\OS-Ⅱ操作系统的任务切换|

发布时间:2019-02-21 03:55:00 影响了:

  摘要:μC\OS-Ⅱ操作系统是一个多任务占先式实时操作系统,每一个任务由三部分组成,任务控制块,任务的私有堆栈、任务代码。每一个任务有一个决定其重要性的任务优先级,系统通过任务就绪表来进行任务的切换,就绪的任务在任务就绪表中设置其标志位,退出就绪的任务在就绪表中撤消其标志位。任务的切换过程就是通过任务就绪表找到优先级最高的任务,保存原来运行任务的上下文到该任务的私有堆栈中,从最高优先级的任务私有堆栈中复制断点数据到工作寄存器中,pc指针指向该任务的代码段,实现了任务的切换。
  关键词:操作系统任务控制块优先级任务切换
  
  1 μC\OS-Ⅱ的任务
   μC\OS-Ⅱ操作系统是一个多任务系统,它最多可以管理64个任务,但两个优先级最低的任务已被系统占用,一个是统计任务,一个是空闲任务。空闲任务的作用为当操作系统没有其它任务执行时,就转入空闲任务而不使系统没事可做。
  任务的结构
   每一个任务都有如下结构。它由任务控制块TCB,任务代码,任务堆栈组成,多个任务控制块形成一个任务控制块链表。每一个任务在创建时都被分配有一个任务优先级,优先级序号从0到63,优先级数值越大则表示优先级越低,最高的优先级是优先级序号为0的任务,最低的优先级是优先级为63的任务。操作系统可以设定管理的任务数,在OS_CFG.H文件中,可以定义OS_LOWEST_PRIO值,该值最大为63。每一个任务都有唯一的任务优先级,μC\OS-Ⅱ操作系统任务切换的关键就是该任务的优先级,操作系统总是运行处于就绪状态的最高优先级的任务。创建任务主要完成四项任务,一是指出任务代码存放的地址,二是指明任务参数指针,也即任务参数地址,三是指明任务堆栈栈顶指针,在进行任务切换时保存或恢复与任务相关的寄存器的值,四是确定任务的优先级,优先级的高低决定了任务的紧迫性和重要性。任务创建的代码如下。
   INT8U OSTaskCreate (
   void (*task)(void *pd), //任务代码指针
   void *pdata, //任务参数指针
   OS_STK *ptos, //任务栈的栈顶指针
   INT8U prio //任务的优先级
   );
  1.2 任务堆栈
   每一个任务都有一个私有的堆栈空间,在任务切换时保存CPU 寄存器现场(R0~R12、LR、SPSR 等)和本任务的私有数据。任务的堆栈的增长方向有向高地址与向低地址两个方向,堆栈存储数据遵循后进先出的规则。
   任务控制块
   任务控制块是μC\OS-Ⅱ操作系统任务管理与切换的关键。任务控制块是一个C语言的自定义结构体,主要包含有任务堆栈栈顶地址、任务的优先级、上下任务控制块的地址、任务的状态等相关信息。任务控制块由上下控制块地址指针与上下任务控制块之间形成一个双向链表。一个任务控制块的结构的主要成员如下:
   typedef struct os_tcb {
   structos_tcb *OSTCBNext;//指向下一个TCB的指针
   structos_tcb *OSTCBPrev;//指向前一个TCB的指针
   OS_STK*OSTCBStkPtr; //指向任务堆栈栈顶的指针
     ……
   INT16U OSTCBDly;//任务等待时间
   INT8U OSTCBStat; //任务的当前状态标志
   INT8U OSTCBPrio;//任务的优先级别 
   ……
   } OS_TCB;
   任务控制块的管理主要有以下几个变量,一是OSTCBTbl[ ]―任务控制块数组;二是OSTCBPrioTbl[ ] ―任务控制块优先级数组,以 Prio 为下标存放已使能的 TCB 指针。用于加速 TCB 的访问。OSTCBCur―全局系统变量,指向当前正在运行的任务的TCB 。
  
  2 任务就绪表及任务进入、脱离就绪状态
  2.1 任务就绪表的结构
   为了能够使系统清楚地知道,系统中哪些任务已经就绪,哪些还没有就绪,μC/OS_II 在 RAM中设立了一个记录表,系统中的每个任务都在这个表中占据一Bit 的位置,并用这个位置的状态(1或者0)来表示任务是否处于就绪状态,这个表就叫做任务就绪状态表,简称叫任务就绪表。由一个 8位的数组 OSRdyTbl[ ] 充当,该数组最多8个元素,可以标示64个任务。
   任务就绪表就是一个二维数组OSRdyTbl[ ],如果某一位为1,则表明该优先级的任务已就绪,可以进行调度,否则该任务还没有处于就绪状态,系统还不能直接运行该项任务。例如OSRdyTbl[2]的D3为1则表示任务优先级为19的任务已处于就绪状态,可以被系统运行。为加快访问任务就绪表的速度,系统定义了一个变量OSRdyGrp来表明就绪表每行中是否存在就绪任务。
   根据任务的优先级prio、优先级就绪数组OSRdyTbl[]、任务就绪组OSRdyGrp。系统就可以对任务进行管理与控制。
   μC\OS-Ⅱ可以管理的64个任务的优先级prio值为0~63(000000~111111),由任务的优先级就可以找到该任务在任务就绪表中所对应的位,优先级prio除以8取整,也就相当于优先级prio右移三位,代表该任务在任务就绪表中的组号x,也即OSRdyTbl[]数组的下标等于prio.[5:3]。优先级prio的低三位prio.[2:0]代表在任务优先级组中的位y。为了加快任务的调度及保证任务切换时间一致性,μC\OS-Ⅱ操作系统预先定义了一个数组OSMapTbl[],
   OSMapTbl[0] = 0000,0001B
   OSMapTbl[1] = 0000,0010B
   OSMapTbl[2] = 0000,0100B
   OSMapTbl[3] = 0000,1000B
   OSMapTbl[4] = 0001,0000B
   OSMapTbl[5] = 0010,0000B
   OSMapTbl[6] = 0100,0000B
   OSMapTbl[7] = 1000,0000B
   通过查表法,操作系统就可以知道该优先级在任务就绪表中哪一组,对应OSRdyGrp的哪一位,在该组中处于哪一位。例如:如果任务优先级prio为21的任务处于就绪状态,十进制21转换为二进制则为10101,该数值右移三位为010,010表示十进制的2,查表OSMapTbl[2]=00000100B知道OSRdyTbl[2]有任务进行就绪状态。10101的低三位为101,101表示十进制5,查表OSMapTbl[5]= 00100000B可确定OSRdyTbl[2]的第五位为1。
  2.2 任务进入就绪状态
   只有进入就绪状态的任务才能被调度,从而被CPU执行。一个任务如何才能处于就绪状态呢?只要在对应的任务就绪表中登记该任务,就使该任务处于就绪状态。如果该任务的优先级为prio,首先使该优先级对应的就绪组置位,
  OSRdyGrp|= OSMapTbl[prio>>3]
本文为全文原貌 未安装PDF浏览器用户请先下载安装 原版全文   然后使该组对应的的位置位,
  OSRdyTbl[prio>>3]|= OSMapTbl[prio&0x07]
  2.3 任务脱离就绪状态
   与任务进入就绪状态相反,使该优先级的任务对应的位复位,如果该就绪组没有任务处于就绪状态,就使该任务就绪组对应的位复位。首先使该任务对应的位复位,
  OSRdyTbl[prio>>3]&= ~OSMapTbl[prio&0x07]
   如果该就绪组没有任务处于就绪状态,则该就绪组对应的位复位,
  if(OSRdyTbl[prio>>3]==0)
   {
   OSRdyGrp&=~ OSMapTbl[prio>>3]
   }
  
  3 任务调度
   任务调度,也就是找到优先级最高的任务,然后转到该任务的代码段并执行该项段代码。
  3.1 找到优先级最高的任务。
   根据任务就绪表的结构,任务就绪组中最低为1的位所对应的组中最低为1的位所对应的优先级就是处于就绪状态的最高优先级的任务。
   如果OSRdyGrp=01011010,则说明四个组中有任务处于就绪状态,而OSRdyTbl[1]这一组优先级别最高。如果OSRdyTbl[1]=10010010,则说明该组有三个任务处于就绪状态,从右数第二个1所代表的优先级是所有就绪的任务中优先级最高的。为了快速得到优先级最高的任务,μC\OS-Ⅱ仍然采用查表的方式,μC\OS-Ⅱ操作系统预先定义了一个数组OSUnMapTbl[256]
  INT8UconstOSUnMapTbl[] = {
  0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x00 to 0x0F */
  4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x10 to 0x1F */
  5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x20 to 0x2F */
  4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x30 to 0x3F */
  6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x40 to 0x4F */
  4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x50 to 0x5F */
  5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x60 to 0x6F */
  4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x70 to 0x7F */
  7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x80 to 0x8F */
  4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x90 to 0x9F */
  5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0xA0 to 0xAF */
  4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0xB0 to 0xBF */
  6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0xC0 to 0xCF */
  4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0xD0 to 0xDF */
  5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0xE0 to 0xEF */
  4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0/* 0xF0 to 0xFF */
  };
   设最高优先级组为y,该组内优先级最高的位为x,则y= OSUnMapTbl[OSRdyGrp],x= OSUnMapTbl[OSRdyTbl[y]],与由优先级找到就绪组和该组内的位的方法相反,则最高优先任务的优先级prio=y*3+x 。当OSRdyGrp=01011010b=0x5a,OSRdyTbl[1]=10010010=0x92时,
   y= OSUnMapTbl[0x5a]=1
   x= OSUnMapTbl[OSRdyTbl[1]]= OSUnMapTbl[0x92]=1
   prio=1*3+1=4
   也就是说优先级为4的任务是当前优先级最高的任务。知道了最高优先级的任务,由OSTCBPrioTbl[prio]就可以得到该任务的任务控制块的地址。
  3.2 切换任务上下文。
   这里有四个工作要做,第一五保存当前任务的CPU的格寄存器内容到当前任务的私有堆栈中,第二保存当前任务的堆栈的栈底地址到当前任务的任务TCB中,第三由最高任务的控制块TCB得到该任务的私有堆栈地址sp,第四根据该任务的堆栈地址sp,装入该任务的中断的数据。
  3.3 运行最高优先级的任务代码。
   经任务调度后,PC已指向最高优先级的代码段的位置,该任务获得了CPU的使用权,从而实现了任务的切换工作。
  
  结语
   μC\OS-Ⅱ操作系统是一个多任务占先式的实时操作系统,其对任务的管理依靠任务控制块TCB,任务控制块TCB保存有任务的私有堆栈地址、任务的代码段地址、上下任务控制块TCB的地址及任务的优先级等信息。所有就绪的任务在任务就绪表中都有登记,根据任务就绪表就可以找到最高优先级的任务,任务的切换就是保存原来任务的数据到该任务的私有堆栈中,从最高优先级的任务堆栈中获得其被中断的数据,PC指向该任务的代码段并运行该段代码。
  
  参考文献
  [1] 任哲.嵌入式实时操作系统μC\OS-Ⅱ-II 原理及应用(第二版)[M].北京:北京航空航天大学出版社,2009.
  [2] 王田苗.嵌入式系统设计与实例开发[M].北京:清华大学出版社,2003年10月.
   [3] 原著作者(美)Jean J.Labrosse.嵌入式实时操作系统μC\OS-Ⅱ[M].译者,邵贝贝 等译.北京:北京航空航天大学出版社,2003.
本文为全文原貌 未安装PDF浏览器用户请先下载安装 原版全文

猜你想看
相关文章

Copyright © 2008 - 2022 版权所有 职场范文网

工业和信息化部 备案号:沪ICP备18009755号-3