**根据时间片轮转调度在同优先级任务中的应用,需要对
任务的TCB进行修改,增加4个属性项:**
1)OSTSLen(时间片初始值)。保存任务建立时给任务分
配时间片的个数。
2)OSTSCurLen(时间片剩余值)。记录了任务运行中还
剩余的时间片个数”-。
3)OSTSPrev(TCB双向链表前驱指针)。用作组成图2
所示的TCB循环链表。
4)OSTSNext(TCB双向链表后继指针)。用作组成图2
所示的TcB循环链表。
OSTimeTick代码部分修改:
void OSTimeTick(void)
{
OS_TCB *ptcb;
OS_TCB *temptcb;
if OS_TICK_STEP_EN > 0
BOOLEAN step;
endif
if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr = 0;
endif
if OS_TIME_TICK_HOOK_EN > 0
OSTimeTickHook(); /* Call user definable hook */
endif
if OS_TIME_GET_SET_EN > 0
OS_ENTER_CRITICAL(); /* Update the 32-bit tick counter */
OSTime++;
OS_EXIT_CRITICAL();
endif
if (OSRunning == OS_TRUE) {
if OS_TICK_STEP_EN > 0
switch (OSTickStepState) { /* Determine whether we need to process a tick */
case OS_TICK_STEP_DIS: /* Yes, stepping is disabled */
step = OS_TRUE;
break;
case OS_TICK_STEP_WAIT: /* No, waiting for uC/OS-View to set ... */
step = OS_FALSE; /* .. OSTickStepState to OS_TICK_STEP_ONCE */
break;
case OS_TICK_STEP_ONCE: /* Yes, process tick once and wait for next ... */
step = OS_TRUE; /* ... step command from uC/OS-View */
OSTickStepState = OS_TICK_STEP_WAIT;
break;
default: /* Invalid case, correct situation */
step = OS_TRUE;
OSTickStepState = OS_TICK_STEP_DIS;
break;
}
if (step == OS_FALSE) { /* Return if waiting for step command */
return;
}
endif
ptcb = OSTCBList; /* Point at first TCB in TCB list */
while (ptcb->OSTCBPrio != OS_TASK_IDLE_PRIO) { /* Go through all TCBs in TCB list */
OS_ENTER_CRITICAL();
if (ptcb->OSTCBDly != 0) { /* No, Delayed or waiting for event with TO */
if (--ptcb->OSTCBDly == 0) { /* Decrement nbr of ticks to end of delay */
/* Check for timeout */
if ((ptcb->OSTCBStat & OS_STAT_PEND_ANY) != OS_STAT_RDY) {
ptcb->OSTCBStat &= ~OS_STAT_PEND_ANY; /* Yes, Clear status flag */
ptcb->OSTCBStatPend = OS_TRUE; /* Indicate PEND timeout */
}
else {
ptcb->OSTCBStatPend = OS_FALSE;
}
if ((ptcb->OSTCBStat & OS_STAT_SUSPEND) == OS_STAT_RDY) { /* Is task suspended? */
OSRdyGrp |= ptcb->OSTCBBitY; /* No, Make ready */
OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
}
}
}
if (ptcb == OSTCBCur){ /*找出处于运行态的任务*/
if (ptcb->OSTCBPrio>OS_RT_PRIO&&ptcb->OSTCBPrio<OS_TASK_STAT_PRIO){ /*分时任务*/
if (ptcb->OSTCBCounter != 0){
if (--ptcb->OSTCBCounter == 0){ /*时间片减1后为0*/
ptcb->OSTCBStat = OS_STAT_TS_USEUP; /*设置为等待状态*/
if ((OSRdyTbl[ptcb->OSTCBPrio >> 3] &= ~OSMapTbl[ptcb->OSTCBPrio & 0x07]) == 0) /*从就绪队列中取出*/
OSRdyGrp &= ~OSMapTbl[ptcb->OSTCBPrio >> 3]; /*对于OSRdyGrp,只有当被删除任务所在任务组中全组任务一个都没有进入就绪态时,才将相应位清零*/
OSTSSGrp |= ptcb->OSTCBBitY; /*进入等待队列*/
OSTSSTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
/*进行任务切换或重新分配时间片*/
if (((OSRdyGrp & 0x7f) == 0) && OSTSSGrp != 0){ /*就绪队列中无任务等待队列中有*/
temptcb = OSTCBList; /*重新分配时间片*/
while (temptcb->OSTCBPrio != OS_TASK_IDLE_PRIO){
if (temptcb->OSTCBPrio>OS_RT_PRIO&&ptcb->OSTCBPrio<OS_TASK_STAT_PRIO){
temptcb->OSTCBCounter = temptcb->OSTCBTimeSlice;
temptcb->OSTCBStat = OS_STAT_RDY;
}
temptcb = temptcb->OSTCBNext;
}
OSRdyGrp |= OSTSSGrp; /*将等待队列中任务转到就绪队列*/
OSRdyTbl[0] |= OSTSSTbl[0];
OSRdyTbl[1] |= OSTSSTbl[1];
OSRdyTbl[2] |= OSTSSTbl[2];
OSRdyTbl[3] |= OSTSSTbl[3];
OSRdyTbl[4] |= OSTSSTbl[4];
OSRdyTbl[5] |= OSTSSTbl[5];
OSRdyTbl[6] |= OSTSSTbl[6];
OSRdyTbl[7] |= OSTSSTbl[7];
OSTSSGrp = 0; /*清空等待队列*/
OSTSSTbl[0] = 0;
OSTSSTbl[1] = 0;
OSTSSTbl[2] = 0;
OSTSSTbl[3] = 0;
OSTSSTbl[4] = 0;
OSTSSTbl[5] = 0;
OSTSSTbl[6] = 0;
OSTSSTbl[7] = 0;
}
else if (((OSRdyGrp & 0x7f) == 0) && (OSRdyTbl[7] == 0xc0) && OSTSSGrp == 0){ /*系统无任务就绪或等待*/
//OSStart();
//printf("I am coming\n");/*执行空闲任务*/
}
else
;
}
}
}
}
ptcb = ptcb->OSTCBNext; /* Point at next TCB in TCB list */
OS_EXIT_CRITICAL();
}
}
}
OSTaskCreate内添加任务优先级创建:
if OS_ARG_CHK_EN > 0u
if (prio > OS_LOWEST_PRIO) { /* Make sure priority is within allowable range */
return (OS_ERR_PRIO_INVALID);
}
endif
OS_ENTER_CRITICAL();
if (OSIntNesting > 0u) { /* Make sure we don't create the task from within an ISR */
OS_EXIT_CRITICAL();
return (OS_ERR_TASK_CREATE_ISR);
}
if (OSTCBPrioTbl[prio] == (OS_TCB *)0) { /* Make sure task doesn't already exist at this priority */
OSTCBPrioTbl[prio] = OS_TCB_RESERVED;/* Reserve the priority to prevent others from doing ... */
/* ... the same thing until task is created. */
OS_EXIT_CRITICAL();
psp = OSTaskStkInit(task, p_arg, ptos, 0u); /* Initialize the task's stack */
err = OS_TCBInit(prio, psp, (OS_STK *)0, 0u, 0u, (void *)0, 0u);
if (err == OS_ERR_NONE) {
if (OSRunning == OS_TRUE) { /* Find highest priority task if multitasking has started */
OS_Sched();
}
} else {
OS_ENTER_CRITICAL();
OSTCBPrioTbl[prio] = (OS_TCB *)0;/* Make this priority available to others */
OS_EXIT_CRITICAL();
}
return (err);
}
else
{
}
OS_EXIT_CRITICAL();
return (OS_ERR_PRIO_EXIST);
}
OS_TCBInit增添初始化TCB时间片代码:
if (prio