/*
*********************************************************************************************************
* CHANGE PRIORITY OF A TASK
*
* Description: This function allows you to change the priority of a task dynamically. Note that the new
* priority MUST be available.
*
* Arguments : oldp is the old priority
*
* newp is the new priority
*
* Returns : OS_ERR_NONE is the call was successful
* OS_ERR_PRIO_INVALID if the priority you specify is higher that the maximum allowed
* (i.e. >= OS_LOWEST_PRIO)
* OS_ERR_PRIO_EXIST if the new priority already exist.
* OS_ERR_PRIO there is no task with the specified OLD priority (i.e. the OLD task does
* not exist.
* OS_ERR_TASK_NOT_EXIST if the task is assigned to a Mutex PIP.
*********************************************************************************************************
*/
#if OS_TASK_CHANGE_PRIO_EN > 0
INT8U OSTaskChangePrio (INT8U oldprio, INT8U newprio)
{
#if OS_EVENT_EN
OS_EVENT *pevent;
#endif
OS_TCB *ptcb;
INT8U x;
INT8U y;
#if OS_LOWEST_PRIO <= 63
INT8U bitx;
INT8U bity;
#else
INT16U bitx;
INT16U bity;
#endif
INT8U y_old;
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr = 0; /* Storage for CPU status register */ 存储
//存PRIMASK(除能所有的中断寄存器)——(当然了,不可屏蔽中断(NMI)才不甩它呢)状态的。
#endif
#if OS_ARG_CHK_EN > 0
if (oldprio >= OS_LOWEST_PRIO) {//看看优先级在不在范围
if (oldprio != OS_PRIO_SELF) {
return (OS_ERR_PRIO_INVALID);
}
}
if (newprio >= OS_LOWEST_PRIO) {
return (OS_ERR_PRIO_INVALID);
}
#endif
OS_ENTER_CRITICAL();
if (OSTCBPrioTbl[newprio] != (OS_TCB *)0) { /* New priority must not already exist */ 新优先级当然是没被其他任务用过的。所以是NULL的。用过了,就指向其他任务的tcb了,或者临时赋值1了。
OS_EXIT_CRITICAL();
return (OS_ERR_PRIO_EXIST);
}
if (oldprio == OS_PRIO_SELF) { /* See if changing self *///优先级为0xff代表改变自己
oldprio = OSTCBCur->OSTCBPrio; /* Yes, get priority */
//#define OS_PRIO_SELF 0xFFu 也就是说0xFF这个优先级用来形容改变自己的优先级。
}
ptcb = OSTCBPrioTbl[oldprio];
if (ptcb == (OS_TCB *)0) { /* Does task to change exist? */
OS_EXIT_CRITICAL(); /* No, can't change its priority! */
return (OS_ERR_PRIO);
}
if (ptcb == OS_TCB_RESERVED) { /* Is task assigned to Mutex */
//见<ucos-ii之OSTaskCreate> OS_TCB_RESERVED(是1)代表该优先级的任务tcb储存在OSTCBPrioTbl的位置
//被其他任务先占领了。只是还没指向被先占领的任务的tcb.也就是说该优先级已经被其他任务用了,你就不能再用了。
OS_EXIT_CRITICAL(); /* No, can't change its priority! */
return (OS_ERR_TASK_NOT_EXIST);
}
#if OS_LOWEST_PRIO <= 63
y = (INT8U)(newprio >> 3); /* Yes, compute new TCB fields *///三位高,三位低。2三次方8
x = (INT8U)(newprio & 0x07);
bity = (INT8U)(1 << y);
bitx = (INT8U)(1 << x);
#else
y = (INT8U)((newprio >> 4) & 0x0F);//现在是四位高,四位低 //2四次方16
x = (INT8U)( newprio & 0x0F);
bity = (INT16U)(1 << y);
bitx = (INT16U)(1 << x);
#endif
OSTCBPrioTbl[oldprio] = (OS_TCB *)0; /* Remove TCB from old priority */
/* Make this priority available to others */为0代表没用过,可以被用。
OSTCBPrioTbl[newprio] = ptcb; /* Place pointer to TCB @ new priority */
y_old = ptcb->OSTCBY;
//<uc/os_II优先级判定表OSUnMapTbl>讲诉了以下的如何设置OSRdyTbl和OSRdyGrp
if ((OSRdyTbl[y_old] & ptcb->OSTCBBitX) != 0) { /* If task is ready make it not */
OSRdyTbl[y_old] &= ~ptcb->OSTCBBitX;
if (OSRdyTbl[y_old] == 0) {
OSRdyGrp &= ~ptcb->OSTCBBitY;
}
OSRdyGrp |= bity; /* Make new priority ready to run */
OSRdyTbl[y] |= bitx;
}
#if OS_EVENT_EN
pevent = ptcb->OSTCBEventPtr;
if (pevent != (OS_EVENT *)0) { /* ... remove from event wait list */
pevent->OSEventTbl[y_old] &= ~ptcb->OSTCBBitX;
if (pevent->OSEventTbl[y_old] == 0) {
pevent->OSEventGrp &= ~ptcb->OSTCBBitY;
}
pevent->OSEventGrp |= bity; /* Add new priority to wait list */
pevent->OSEventTbl[y] |= bitx;
}
#endif
ptcb->OSTCBPrio = newprio; /* Set new task priority */
ptcb->OSTCBY = y;
ptcb->OSTCBX = x;
ptcb->OSTCBBitY = bity;
ptcb->OSTCBBitX = bitx;
OS_EXIT_CRITICAL();
if (OSRunning == OS_TRUE) {
OS_Sched(); /* Find new highest priority task */
}
return (OS_ERR_NONE);
}
#endif
阅读(2015) | 评论(0) | 转发(0) |