Download presentation
Presentation is loading. Please wait.
1
μC/OSⅡ中的任务调度 Group01小组 柴永锋 李逢春 苗 冬
2
相关介绍 C/OS是占先式实时多任务内核,优先级最高的任 务一旦准备就绪,则拥有CPU的所有权开始投入运 行。
C/OS –II 2.51版本支持64个任务,每个任务一 个特定的优先级。优先级越高,数字越小。 C/OS任务调度所花的时间为常数,与应用程序中 建立的任务数无关
3
任务状态 3
4
任务控制块(TCB) 任务控制块 OS_TCB是一个数据结构,保存 该任务的相关参数,包括任务堆栈指针, 状态,优先级,任务表位置,任务链表指 针等。 所有的任务控制块分为两条链表,空闲链 表和使用链表。 4
5
µC/OS-II任务控制块.ucos-ii.h
typedef struct os_tcb { OS_STK *OSTCBStkPtr; 指向当前任务栈顶的指针 #if OS_TASK_CREATE_EXT_EN>0 void *OSTCBExtPtr; 指向用户定义的任务控制 块扩展 OS_STK *OSTCBStkBottom; 指向任务栈底的指针 INT32U OSTCBStkSize; 栈中可容纳的指针元数 INT16U OSTCBOpt; 把“选择项”传给 OSTaskCreateExt() INT16U OSTCBId; 任务的识别码 #endif struct os_tcb *OSTCBNext; 任务控制块OS_TCBs的双重 链接 struct os_tcb *OSTCBPrev; #if OS_EVENT_EN OS_EVENT *OSTCBEventPtr; /* 指向事件控制 块*/ 5
6
µC/OS-II任务控制块.ucos-ii.h
#if ((OS_Q_EN>0) && (OS_MAX_QS > 0)) || (OS_MBOX_EN >0) void *OSTCBMsg; 指向传给任务的消息的指 针 #endif INT16U OSTCBDly; 任务延时若干时钟节拍 INT8U OSTCBStat; 任务的状态字 0,就绪 INT8U OSTCBPrio; 任务优先级 INT8U OSTCBX; INT8U OSTCBY; 用于加速任务进入就绪态的过 程 INT8U OSTCBBitX; 或进入等待事件发生状态的过 程 INT8U OSTCBBitY; #if OS_TASK_DEL_EN BOOLEAN OSTCBDelReq; 表示该任务是否需要删除 自身 } OS_TCB; 6
7
与TCB相关的结构 7
8
两个关键: 优先级数分解为高三位和低三位分别确定; 高优先级有着小的优先级号 ; 8
9
优先级和就绪任务表的位置关系 每个就绪的任务都放入就绪表中(ready list) 中,就绪表有两个变量:OSRdyGrp、OSRdyTbl[] 9
10
优先根据优先级确定就绪表(1) 假设优先级为12的任务进入就绪状态,12=1100b,则 OSRdyTbl[1]的第4位置1,且OSRdyGrp的第1位置1,相应 的数学表达式为: OSRdyGrp |=0x02; OSMapTbl[1]=( ) OSRdyTbl[1] |=0x10; OSMapTbl[4]=( ) 而优先级为21的任务就绪21=10 101b,则OSRdyTbl[2]的 第5位置1,且OSRdyGrp的第2位置1,相应的数学表达式为 : OSRdyGrp |=0x04; OSMapTbl[2]=( ) OSRdyTbl[2] |=0x20; OSMapTbl[5]=( ) 10
11
根据优先级确定就绪表(2) 从上面的计算我们可以得到:若OSRdyGrp及OSRdyTbl[]的第n位置1, 则应该把OSRdyGrp及OSRdyTbl[]的值与2n 相或。uC/OS中,把2n的 n=0-7的8个值先计算好存在数组OSMapTbl[7]中,也就是: OSMapTbl[0] =20=0x01( ) OSMapTbl[1] =21=0x02( ) …… Index Bit Mask (Binary) 1 2 3 4 5 6 7 11
12
使任务进入就绪态 如果prio是任务是优先级,也是任务的识别号, 则将任务放入就绪表,即使任务进入就绪态的方 法是:
OSRdyGrp |=OSMapTbl[prio>>3]; OSRdyTbl[prio>>3] |=OSMapTbl[prio & 0x07]; 假设优先级为12——1100b OSMapTbl[1]= OSMapTbl[4]= OSRdyGrp |=0x02; OSRdyTbl[1] |=0x10; 12
13
根据就绪表确定最高优先级 通过OSRdyGrp值确定高3位,假设为0x24= b, --- 〉 对应OSRdyTbl[2] 和OSRdyTbl[5],高优先级为2 通过OSRdyTbl[2]的值来确定低3位, 假设为0x12= b ,---〉第2个和第5个任务,取高 优先级为2,则最高优先级的任务号为17 13
14
源代码中使用了查表法 查表法具有确定的时间,增加了系统的可预测性, uC/OS中所有的系统调用时间都是确定的
High3 =OSUnMapTbl[OSRdyGrp]; Low3 =OSUnMapTbl[OSRdyTbl[High3]]; Prio =(High3<<3)+Low3; 14
15
优先级判定表OSUnMapTbl[256] (os_core.c)
举例: 如OSRdyGrp的值为 B,即0X28,则查得OSUnMapTbl[OSRdyGrp]的值是3,它相应于OSRdyGrp中的第3位置1; 如OSRdyTbl[3]的值是 B,即0XE4,则查OSUnMapTbl[OSRdyTbl[3]]的值是2,则进入就绪态的最高任务优先级 Prio=3*8+2=26 INT8U const OSUnMapTbl[] = { 0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 }; 15
16
Task scheduler void OS_Sched (void) /*os_core.c中*/ { INT8U y;
OS_ENTER_CRITICAL(); if ((OSLockNesting =0)&&(OSIntNesting= 0)) { y = OSUnMapTbl[OSRdyGrp]; OSPrioHighRdy = (INT8U)((y << 3) OSUnMapTbl[OSRdyTbl[y]]) if (OSPrioHighRdy != OSPrioCur) { OSTCBHighRdy=OSTCBPrioTbl[OSPrioHighRdy]; OSCtxSwCtr++; OS_TASK_SW(); } OS_EXIT_CRITICAL(); 16
17
谢谢!
Similar presentations