描述:此函数允许你动态改变一个任务的优先级。但新的优先级必须可行
参数:oldp :旧的优先级
newp:新的优先级
返回:OS_NO_ERR:改变成功
OS_PRIO_INVALID:指定的优先级不合法:超过最大值
OS_PRIO_EXIST:新优先级已经存在
OS_PRIO_ERR:旧优先级任务不存在
*********************************************************************************************************
*/
#if OS_TASK_CHANGE_PRIO_EN >0 //如果OS_TASK_CHANGE_PRIO_EN设置为1,能使包含下面代码
INT8U OSTaskChangePrio (INT8U oldprio, INT8U newprio)
{
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
//为CPU状态寄存器分配存储器
OS_CPU_SRcpu_sr//OS_CPU_SR即为unsigned int
#endif
#if OS_EVENT_EN >0
//OS_EVENT_EN 定义为:(((OS_Q_EN >0) &&(OS_MAX_QS >0)) || (OS_MBOX_EN >0) || (OS_SEM_EN >0) || (OS_MUTEX_EN >0))
//OS_EVENT_EN 定义为:能使队列代码产生&&申请队列控制块最大数不为零||能使邮箱代码产生||
//能使信号量代码产生||能使互斥量代码产生
OS_EVENT*pevent
#endif
OS_TCB *ptcb
INT8Ux
INT8Uy
INT8Ubitx
INT8Ubity
#if OS_ARG_CHK_EN >0//允许参数检测
if ((oldprio >= OS_LOWEST_PRIO &&oldprio != OS_PRIO_SELF) ||
newprio >= OS_LOWEST_PRIO) {//旧新优先级都不合法
return (OS_PRIO_INVALID)
}
#endif
OS_ENTER_CRITICAL()//如果合法
if (OSTCBPrioTbl[newprio] != (OS_TCB *)0) { /* New priority must not already exist */
OS_EXIT_CRITICAL()
return (OS_PRIO_EXIST)//新优先级必须不存在,存在就重复了
} else {
OSTCBPrioTbl[newprio] = (OS_TCB *)1 /* Reserve the entry to prevent others */
//保留入口,防止其它任务占用此优先级
OS_EXIT_CRITICAL()
y= newprio >>3 /* Precompute to reduce INT. latency */
//此函数会预先计算新优先级任务的任务控制块中的某些值,使用这些值
//可以将任务放入就绪步或者从该表中移除任务.
bity = OSMapTbl[y]
x= newprio &0x07
bitx = OSMapTbl[x]
OS_ENTER_CRITICAL()
if (oldprio == OS_PRIO_SELF) { /* See if changing self*/
//如果改变自己
oldprio = OSTCBCur->OSTCBPrio /* Yes, get priority */
}//是的,得到优先级
ptcb = OSTCBPrioTbl[oldprio]//得到该优先级TCB指针
if (ptcb != (OS_TCB *)0) { /* Task to change must exist */
//优先级存在,如果要改变的是当前任务,由一定会成功
OSTCBPrioTbl[oldprio] = (OS_TCB *)0 /* Remove TCB from old priority*/
//通过放入空闲指针,将指向当前任务的TCB指针从优先级列表中删除,
//使当前旧的优先级空闲,可以被其它任务占用.
if ((OSRdyTbl[ptcb->OSTCBY] &ptcb->OSTCBBitX) != 0x00) { /* If task is ready make it not */
if ((OSRdyTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX) == 0x00) {//如果要改变优先级的任务就绪
OSRdyGrp &= ~ptcb->OSTCBBitY//不能让它就绪,
}
OSRdyGrp|= bity /* Make new priority ready to run */
OSRdyTbl[y] |= bitx//从就绪表中移除,然后在新优先级下,将任务插入就绪表,
//注意:OSTaskChangePrio是利用预先计算的值(见前面)将任务插入就绪表中的.
#if OS_EVENT_EN >0
//#define OS_EVENT_EN (((OS_Q_EN >0) &&(OS_MAX_QS >0)) || (OS_MBOX_EN >0) || (OS_SEM_EN >0) || (OS_MUTEX_EN >0))
//能使队列代码产生&&申请队列控制块最大数不为零||能使邮箱代码产生||
//能使信号量代码产生||能使互斥量代码产生
} else {
pevent = ptcb->OSTCBEventPtr
if (pevent != (OS_EVENT *)0) { /* Remove from event wait list */
//如果任务没有就绪,那么可能在等一个信号量,一个互斥型信号量,一个邮箱,队列
//等,如果OSTCBEventPtr非空,那么此函数会知道任务正在等以上的某件事.
if ((pevent->OSEventTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX) == 0) {
pevent->OSEventGrp &= ~ptcb->OSTCBBitY
}
pevent->OSEventGrp|= bity /* Add new priority to wait list */
//如果任务正在等某事件发生,OSTCBEventPtr必须将任务从事件控制块的等待队列(旧
//的优先级下)中移除,并在新的优先级下将事件插入到等待队列中.任务也可能正
//在等待延时时间到,或被挂起,上面几行可以省略
欢迎分享,转载请注明来源:夏雨云
评论列表(0条)