任务创建
INT8U OSTaskCreate (void (*task)(void *pd), void *pdata, OS_STK *ptos, INT8U prio)
{
OS_STK *psp;
INT8U err;
OS_ENTER_CRITICAL(); //关中断函数 ,即进入临界区
//只允许一个任务进入临界区
if (OSTCBPrioTbl[prio] == (OS_TCB *)0) /* Make sure task doesn't already exist at this priority */
/*如果指的是0地址说明未初始化,此任务不存在。可以创建。*/
{
/* 通过放置一个非空指针来保存优先级Reserve the priority to prevent others from doing the same thing until task is created. */
OSTCBPrioTbl[prio] = (OS_TCB *)1; //当他不存在让其存在
OS_EXIT_CRITICAL(); //开中断函数 ,即能重新允许中断 ,退出临界区
psp = (OS_STK *)OSTaskStkInit(task, pdata, ptos, 0);//返回新的堆栈顶psp,并被保存在任务的OS_TCB中
/* Initialize初始化 the task's stack */
/* 一旦stkinit()函数完成了建立堆栈的任务,OSCREATE()就调用Binit()
这也是任务创建的核心,从空闲的OS_TCB池中获得并初始化一个TCB
一旦OS_TCB被分配,该任务的创建者就已经完全拥有它 ,即使这时内核又创建了其他
任务,这些新任务也不可能对已分配的OS_TCB做任何操作,所以OSTCBInit()
在这时就可以允许中断,并继续初始化os_tcb的数据单元 */
err = OS_TCBInit(prio, psp, (OS_STK *)0, 0, 0, (void *)0, 0);
// 从OSTCBINIT()返回后,OSCREATE()检验返回代码,成功,则
//增加OSTASKCTR,
if (err == OS_NO_ERR)
{
OS_ENTER_CRITICAL();
OSTaskCtr++; /* 用于保存产生的任务数目Increment the #tasks counter */
OS_EXIT_CRITICAL();
/*如果oscreat()函数是在某个任务的执行过程中被调用
则任务调度函数会被调用来判断是否新建立的任务比原来的任务有更高的优先级。如
果新任务的优先级更高,内核会进行一次从旧任务到新任务的任务切换。
如果在多任务调度开始之前(即用户还没有调用OSStart()),
新任务就已经建立了,则任务调度函数OS_Sched()不会被调用。*/
if (OSRunning == TRUE) //任务在系统运行时建立
{/* Find highest priority task if multitasking has started */
OS_Sched(); //找到当前最高优先级任务,让其运行
}
}
//返回失败,就置OSTCBPRIO[PRIO]的入口为0,以放弃该任务的优先级
else
{
OS_ENTER_CRITICAL();
OSTCBPrioTbl[prio] = (OS_TCB *)0;/* Make this priority available to others */
OS_EXIT_CRITICAL();
} yu
return (err);
}
OS_EXIT_CRITICAL();
return (OS_PRIO_EXIST);
}
OS_ENTER_CRITICAL(); //关中断函数 ,即进入临界区 只允许一个任务进入临界区
if (OSTCBPrioTbl[prio] == (OS_TCB )0) / Make sure task doesn’t already exist at this priority /
/如果指的是0地址说明未初始化,此任务不存在。可以创建。/
{
/ 通过放置一个非空指针来保存优先级Reserve the priority to prevent others from doing the same thing until task is created. */
OSTCBPrioTbl[prio] = (OS_TCB *)1; //当他不存在让其存在
OS_EXIT_CRITICAL(); //开中断函数 ,即能重新允许中断 ,退出临界区
if (OSRunning == TRUE) //任务在系统运行时建立
{/* Find highest priority task if multitasking has started */
OS_Sched(); //找到当前最高优先级任务,让其运行
}
删除任务
INT8U OSTaskDel (INT8U prio)
{ OS_EVENT *pevent;
OS_TCB *ptcb;
BOOLEAN self;
if (OSIntNesting > 0)
{ /* See if trying to delete from ISR */
return (OS_TASK_DEL_ISR);
}
OS_ENTER_CRITICAL();
if (prio == OS_PRIO_SELF)
{ /* See if requesting to delete self */
prio = OSTCBCur->OSTCBPrio;
/* Set priority to delete to current */
}
ptcb = OSTCBPrioTbl[prio];
if (ptcb != (OS_TCB *)0)
{ /* Task to delete must exist */
if ((OSRdyTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX) == 0x00)
{ /* Make task not ready*/
OSRdyGrp &= ~ptcb->OSTCBBitY;
}
pevent = ptcb->OSTCBEventPtr;
if (pevent != (OS_EVENT *)0)
{ /* If task is waiting on event */
if ((pevent->OSEventTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX) == 0)
{ /* ... remove task from event ctrl block */
pevent->OSEventGrp &= ~ptcb->OSTCBBitY;
}
}
ptcb->OSTCBDly = 0; /* Prevent OSTimeTick() from updating */
ptcb->OSTCBStat = OS_STAT_RDY; /* Prevent task from being resumed */
if (OSLockNesting < 255)
{
OSLockNesting++;
}
OS_EXIT_CRITICAL();
OS_Dummy(); /* ... Dummy ensures that INTs will be */
//人为把临界区分为两部分,为了及时响应
//函数原型为空函数,相当于nop延时
//如果没有这个函数,开中断后直接关中断可能会导致中断无效
OS_ENTER_CRITICAL(); /* ... enabled HERE! */
if (OSLockNesting > 0)
{
OSLockNesting--;
}
OSTaskDelHook(ptcb); /* Call user defined hook */
OSTaskCtr--; /* One less task being managed */
OSTCBPrioTbl[prio] = (OS_TCB *)0; /* Clear old priority entry */
if (ptcb->OSTCBPrev == (OS_TCB *)0)
{/* Remove from TCB chain */
ptcb->OSTCBNext->OSTCBPrev = (OS_TCB *)0;
OSTCBList = ptcb->OSTCBNext;
} else {
ptcb->OSTCBPrev->OSTCBNext = ptcb->OSTCBNext;
ptcb->OSTCBNext->OSTCBPrev = ptcb->OSTCBPrev;
}
ptcb->OSTCBNext = OSTCBFreeList; /* Return TCB to free TCB list */
OSTCBFreeList = ptcb;
OS_EXIT_CRITICAL();
OS_Sched(); /* Find new highest priority task */
return (OS_NO_ERR);
}
OS_EXIT_CRITICAL();
return (OS_TASK_DEL_ERR);
}
OS_EXIT_CRITICAL();
OS_Dummy(); /* … Dummy ensures that INTs will be /
//人为把临界区分为两部分,为了及时响应
//函数原型为空函数,相当于nop延时
//如果没有这个函数,开中断后直接关中断可能会导致中断无效
OS_ENTER_CRITICAL(); / … enabled HERE! */