1 2 |
|
INT8U OSRdyGrp; /* Ready list group */ INT8U OSRdyTbl[OS_RDY_TBL_SIZE]; /* Table of tasks which are ready to run */ |
1 2 3 4 5 6 7 8 9 10 |
|
/* ********************************************************************************************************* * MAPPING TABLE TO MAP BIT POSITION TO BIT MASK * * Note: Index into table is desired bit position, 0..7 * Indexed value corresponds to bit mask ********************************************************************************************************* */ INT8U const OSMapTbl[8] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80}; |
Index |
Bit Mask (Binary) |
0 |
00000001 |
1 |
00000010 |
2 |
00000100 |
3 |
00001000 |
4 |
00010000 |
5 |
00100000 |
6 |
01000000 |
7 |
10000000 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
|
/* ********************************************************************************************************* * PRIORITY RESOLUTION TABLE * * Note: Index into table is bit pattern to resolve highest priority * Indexed value corresponds to highest priority bit position (i.e. 0..7) ********************************************************************************************************* */ INT8U const OSUnMapTbl[256] = { 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 */ }; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
|
#include int main(void) { int i,t,n; int tab[256]={0}; for(i=0;i<8;i++) for(t=1;(t<256 tab[t< //output this tab for(n=0;n<=0xff;n++) { if(n%0x10==0) printf("\n"); printf("%3d" , tab[n]); } printf("\n"); } |
1 2 |
|
OSRdyGrp |= OSMapTbl[prio >> 3]; OSRdyTbl[prio >> 3] |= OSMapTbl[prio & 0x07]; |
1 2 |
|
if((OSRdyTbl[prio >> 3] &= ~OSMapTbl[prio & 0x07]) == 0) OSRdyGrp &= ~OSMapTbl[prio >> 3]; |
1 2 3 4 |
|
y = OSUnMapTbl[OSRdyGrp]; x = OSUnMapTbl[OSRdyTbl[y]]; prio = (y << 3) + x; /* 括号一定要加:优先级 */ |
1 |
|
OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy];
|
1 |
|
#define OS_TASK_SW() OSCtxSw()
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
|
//任务调度 //描述: uC/OS-II总是运行进入就绪态任务中优先级最高的那一个。确定哪个任务优先级最高,下面该哪 // 个任务运行了的工作是由调度器(Scheduler)完成的。任务级的调度是由函数OSSched()完成的。 // 中断级的调度是由另一个函数OSIntExt()完成的eduling). //参数: none //返回: none //注意: 1) 这是一个uC/OS-II内部函数,你不能在应用程序中使用它 // 2) 给调度器上锁用于禁止任务调度 (查看 OSSchedLock()函数) //说明: 1)任务切换很简单,由以下两步完成,将被挂起任务的微处理器寄存器推入堆栈,然后将较高优先 // 级的任务的寄存器值从栈中恢复到寄存器中。在uC/OS-II中,就绪任务的栈结构总是看起来跟刚 // 刚发生过中断一样,所有微处理器的寄存器都保存在栈中。换句话说,uC/OS-II运行就绪态的任 // 务所要做的一切,只是恢复所有的CPU寄存器并运行中断返回指令。为了做任务切换,运行 // OS_TASK_SW(),人为模仿了一次中断。多数微处理器有软中断指令或者陷阱指令TRAP来实现上述操 // 作。中断服务子程序或陷阱处理(Trap hardler),也称作事故处理(exception handler),必须提 // 供中断向量给汇编语言函数OSCtxSw()。OSCtxSw()除了需要OS_TCBHighRdy指向即将被挂起的任务, // 还需要让当前任务控制块OSTCBCur指向即将被挂起的任务,参见第8章,移植uC/OS-II,有关于 // OSCtxSw()的更详尽的解释。 // 2) OSSched()的所有代码都属临界段代码。在寻找进入就绪态的优先级最高的任务过程中,为防止中 // 断服务子程序把一个或几个任务的就绪位置位,中断是被关掉的。为缩短切换时间,OSSched()全 // 部代码都可以用汇编语言写。为增加可读性,可移植性和将汇编语言代码最少化,OSSched()是用 // C写的。 void OS_Sched (void) { #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ OS_CPU_SR cpu_sr; #endif INT8U y; OS_ENTER_CRITICAL(); //为实现任务切换,OSTCBHighRdy必须指向优先级最高的那个任务控制块OS_TCB,这是通过将 if ((OSIntNesting == 0) && (OSLockNesting == 0)) { /* Sched. only if all ISRs done & not locked */ //如果函数不是在中断服务子程序中调用的,且调度允许的,则任务调度函数将找出进入就绪态的 //最高优先级任务,进入就绪态的任务在就绪表中OSRdyTbl[ ]中相应位置位. y = OSUnMapTbl[OSRdyGrp]; /* Get pointer to HPT ready to run */ OSPrioHighRdy = (INT8U)((y << 3) + OSUnMapTbl[OSRdyTbl[y]]); //找到最高优先级任务后,函数检查这个优先级最高的任务是否是当前正在运行的任务,以避免不 //必要的任务调度,多花时间 if (OSPrioHighRdy != OSPrioCur) { /* No Ctx Sw if current task is highest rdy */ //为实现任务切换,OSTCBHighRdy必须指向优先级最高的那个任务控制块OS_TCB,这是通过将 //以OSPrioHighRdy为下标的OSTCBPrioTbl[]数组中的那个元素赋给OSTCBHighRdy来实现的 OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy]; OSCtxSwCtr++; //统计计数器OSCtxSwCtr加1,以跟踪任务切换次数 OS_TASK_SW(); //最后宏调用OS_TASK_SW()来完成实际上的任务切换 } } OS_EXIT_CRITICAL(); } |