⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 task.c

📁 基于MDK的LPC1100处理器开发应用例程
💻 C
📖 第 1 页 / 共 3 页
字号:
				ptcb->TCBprev = tcbInsert;
				TCBRdy         = tcbInsert;
			}
			return;
		}
		else
		{
			ptcb = &TCBTbl[RdyTaskPri[RdyTaskSeqNum]];	
		}
	}

	ptcbNext = ptcb->TCBnext;
	tcbInsert->TCBnext = ptcbNext;    /* Set link for list                  */
	ptcb->TCBnext      = tcbInsert;
	tcbInsert->TCBprev = ptcb;
	if(ptcbNext != NULL)
	{
	    ptcbNext->TCBprev  = tcbInsert;
	}


#else
    ptcb = TCBRdy;
    if (ptcb == NULL)                   /* Is ready list NULL?                */
    {
        TaskSchedReq = TRUE;
        TCBRdy = tcbInsert;         /* Yse,set tcbInsert as head item of list */
    }
    else if (prio < ptcb->prio)/* Is PRI of inserted task higher than TCBRdy? */
    {
        TaskSchedReq = TRUE;
        tcbInsert->TCBnext = ptcb;  /* Yes,set tcbInsert as head item of list */
        ptcb->TCBprev  = tcbInsert;
        TCBRdy         = tcbInsert;
    }
    else                                /* No,find correct place              */
    {								    
        ptcbNext = ptcb->TCBnext;       /* Get next item                      */
        while(ptcbNext != NULL)         /* Is last item in ready list?        */
        {                               /* No,find correct place              */
            if(prio < ptcbNext->prio)   /* Is correct place?                  */
                break;                  /* Yes,break circulation              */
            ptcb     = ptcbNext;        /* Save current item                  */
            ptcbNext = ptcbNext->TCBnext; /* Get next item                    */
        }
        tcbInsert->TCBnext = ptcbNext;  /* Set link for list                  */
        ptcb->TCBnext      = tcbInsert;
        tcbInsert->TCBprev = ptcb;
        if(ptcbNext != NULL)
        {
            ptcbNext->TCBprev  = tcbInsert;
        }		
    }
#endif
}



/**
 *******************************************************************************
 * @brief      Remove a task from the READY list	   
 * @param[in]  ptcb     A pointer to task which be removed.	 
 * @param[out] None 				 
 * @retval     None		 
 *
 * @par Description
 * @details    This function is called to remove a task from the READY list.
 *******************************************************************************
 */
void RemoveFromTCBRdyList(P_OSTCB ptcb)
{

#if CFG_ORDER_LIST_SCHEDULE_EN ==0
	U8 prio;
	U8 seqNum;
	BOOL isChange;
	isChange = FALSE;
	prio = ptcb->prio;
	GetPriSeqNum(prio,&seqNum);
#endif

    /* Is there only one item in READY list?                                  */
    if((ptcb->TCBnext == NULL) && (ptcb->TCBprev == NULL) )
    {
        TCBRdy = NULL;                  /* Yes,set READY list as NULL         */
#if CFG_ORDER_LIST_SCHEDULE_EN ==0
		isChange = TRUE;
#endif
    }
    else if(ptcb->TCBprev == NULL)      /* Is the first item in READY list?   */
    {   
	    /* Yes,remove task from the list,and reset the head of READY list     */
        TCBRdy = ptcb->TCBnext;		    
        ptcb->TCBnext   = NULL;
        TCBRdy->TCBprev = NULL;
#if CFG_ORDER_LIST_SCHEDULE_EN ==0
		if(TCBRdy->prio != prio)
			isChange = TRUE;
		
#endif
    }
    else if( ptcb->TCBnext == NULL)     /* Is the last item in READY list?    */
    {                                   /* Yes,remove task from list          */
#if CFG_ORDER_LIST_SCHEDULE_EN ==0
		if(ptcb->TCBprev->prio != prio)
			isChange = TRUE;
		else 
			RdyTaskPri[seqNum] = ptcb->TCBprev->taskID;
#endif
        ptcb->TCBprev->TCBnext = NULL;  
        ptcb->TCBprev          = NULL;
    }
    else                                /* No, remove task from list          */
    {	
#if CFG_ORDER_LIST_SCHEDULE_EN ==0
		if((ptcb->TCBprev->prio != prio) && (ptcb->TCBnext->prio != prio))
			isChange = TRUE;
		else if((ptcb->TCBprev->prio == prio) && (ptcb->TCBnext->prio != prio))
			RdyTaskPri[seqNum] = ptcb->TCBprev->taskID;
#endif								
        ptcb->TCBprev->TCBnext = ptcb->TCBnext;
        ptcb->TCBnext->TCBprev = ptcb->TCBprev;
        ptcb->TCBnext = NULL;
        ptcb->TCBprev = NULL;
    }
#if CFG_ORDER_LIST_SCHEDULE_EN ==0
		if(isChange == TRUE)
		{
			RdyTaskPri[seqNum] = INVALID_ID;
			SetPrioSeqNumStatus(seqNum, 0);
		}
#endif
}


#if CFG_MUTEX_EN > 0
#define CFG_PRIORITY_SET_EN       (1)
#endif
#if CFG_PRIORITY_SET_EN >0
/**
 *******************************************************************************
 * @brief      Change task priority	   
 * @param[in]  taskID     Specify task id.
 * @param[in]  priority   New priority.	 
 * @param[out] None		   
 * @retval     E_OK              Change priority successful.
 * @retval     E_INVALID_ID      Invalid id,change priority fail.
 * @retval     E_PROTECTED_TASK  Can't change idle task priority.		 
 *
 * @par Description
 * @details    This function is called to change priority for a specify task. 	
 *******************************************************************************
 */
StatusType CoSetPriority(OS_TID taskID,U8 priority)
{			
    P_OSTCB ptcb;
#if CFG_MUTEX_EN >0
    U8 prio;
    P_MUTEX	pMutex;
#endif
#if CFG_EVENT_EN >0
    P_ECB pecb;
#endif

    if(taskID == 0)                     /* Is idle task?                      */
    {											 
        return E_PROTECTED_TASK;        /* Yes,error return                   */
    }   
	
#if CFG_PAR_CHECKOUT_EN >0              /* Check validity of parameter        */
    if(taskID >= CFG_MAX_USER_TASKS + SYS_TASK_NUM)
    {
        return E_INVALID_ID;
    }
#endif
	ptcb = &TCBTbl[taskID];             /* Get TCB of task ID                 */
#if CFG_PAR_CHECKOUT_EN >0    
    if(ptcb->state == TASK_DORMANT)
    {
        return E_INVALID_ID;
    }
    if(priority > CFG_LOWEST_PRIO)
    {
        return E_INVALID_ID;
    }
#endif

    if(ptcb->prio != priority)          /* Is PRI equal to original PRI?      */
    {                                   /* No                                 */
#if CFG_MUTEX_EN >0
        if(ptcb->mutexID != INVALID_ID)
        {
            pMutex = &MutexTbl[ptcb->mutexID];
            if(pMutex->taskID == ptcb->taskID)  /* Task hold mutex?               */
            {
                 pMutex->originalPrio= priority;/* Yes,change original PRI in mutex*/
                 if(ptcb->prio < priority)     /* Is task priority higher than set?*/
                 {
                     return E_OK;                /* Yes,do nothing,return OK       */
                 }
            }		
         }

#endif	

#if CFG_ORDER_LIST_SCHEDULE_EN ==0
		DeleteTaskPri(ptcb->prio);
		ActiveTaskPri(priority);	
#endif	

        ptcb->prio = priority;              /* Change task PRI                */
        if(ptcb->state == TASK_READY)       /* Is task in READY list?         */
        {
            OsSchedLock();                  /* Yes,reorder task in READY list */
            RemoveFromTCBRdyList(ptcb);
            InsertToTCBRdyList(ptcb);	
            OsSchedUnlock();
        }
        else if(ptcb->state == TASK_RUNNING)/* Is task running?               */
        {
            if(ptcb->prio > TCBRdy->prio)   /* Yes,Is PRI higher than TCBRdy? */
            {
				OsSchedLock();              /* Yes,reorder task in READY list */
				TaskSchedReq = TRUE;
                OsSchedUnlock();
            }
        }
        else
        {                                   /* No,task in WAITING list        */
#if CFG_MUTEX_EN >0
            if(ptcb->mutexID != INVALID_ID) /* Is task in mutex WAITING list? */
            {
                /* Yes,reset the highest PRI in the list */
				OsSchedLock(); 
				pMutex = &MutexTbl[ptcb->mutexID];
                ptcb = pMutex->waittingList;  
                prio = pMutex->originalPrio; 
                pMutex->hipriTaskID = pMutex->taskID;
                while(ptcb != NULL)
                {
                    if(ptcb->prio < prio)
                    {
                        prio = ptcb->prio;
                        pMutex->hipriTaskID = ptcb->taskID;
                    }
                    ptcb = ptcb->TCBnext;			
                }
				OsSchedUnlock();
                if(pMutex->originalPrio != prio)
                {
                    CoSetPriority(pMutex->taskID,prio);	
                }	
            }
#endif

#if CFG_EVENT_EN >0
			ptcb = &TCBTbl[taskID];
            if(ptcb->eventID != INVALID_ID) /* Is task in event WAITING list? */
            {								    
                pecb = &EventTbl[ptcb->eventID];
                
                /* Yes,is event sort type as preemptive PRI?                  */
                if(pecb->eventSortType == EVENT_SORT_TYPE_PRIO)
                {	  
                    /* Yes,reorder task in the list                           */
                    RemoveEventWaittingList(ptcb);
                    EventTaskToWait(pecb,ptcb);
                }	
            }
#endif
        }
    }
    return E_OK;
}
#endif

/**
 *******************************************************************************
 * @brief      Schedule function	  
 * @param[in]  None 	 
 * @param[out] None  	 
 * @retval     None	 
 *
 * @par Description
 * @details    This function is called by every where need to switch context,
 *             It is schedule function of OS kernel.
 *******************************************************************************
 */
void Schedule(void)
{
    U8  RunPrio,RdyPrio;
    P_OSTCB pRdyTcb,pCurTcb;
   
	
    pCurTcb = TCBRunning;    
    pRdyTcb = TCBRdy;

	if((pRdyTcb==NULL) || (pCurTcb != TCBNext) || (OSSchedLock >1) || (OSIntNesting >0))
	{
		return;
	}
    
	TaskSchedReq = FALSE;
    RunPrio = pCurTcb->prio;
    RdyPrio = pRdyTcb->prio;

	/* Is Running task status was changed? */
    if(pCurTcb->state != TASK_RUNNING)	
    {
        TCBNext        = pRdyTcb;   /* Yes,set TCBNext and reorder READY list */
        pRdyTcb->state = TASK_RUNNING;
        RemoveFromTCBRdyList(pRdyTcb);
    }

    else if(RdyPrio < RunPrio )     /* Is higher PRI task coming in?          */
    {
        TCBNext        = pRdyTcb;   /* Yes,set TCBNext and reorder READY list */
        InsertToTCBRdyList(pCurTcb);
		RemoveFromTCBRdyList(pRdyTcb);
        pRdyTcb->state = TASK_RUNNING;
    }
    
#if CFG_ROBIN_EN >0                 /* Is time for robinning                  */                            
    else if((RunPrio == RdyPrio) && (OSCheckTime == OSTickCnt))
    {
        TCBNext        = pRdyTcb;   /* Yes,set TCBNext and reorder READY list */
        InsertToTCBRdyList(pCurTcb);
		RemoveFromTCBRdyList(pRdyTcb);
        pRdyTcb->state = TASK_RUNNING;
    }
#endif
    else
    {								    
        return;	
    }
    
#if CFG_ROBIN_EN >0
    if(TCBNext->prio == TCBRdy->prio)  /* Reset OSCheckTime for task robinnig */
        OSCheckTime = OSTickCnt + TCBNext->timeSlice;
#endif
    
  
#if CFG_STK_CHECKOUT_EN > 0                       /* Is stack overflow?       */
    if((pCurTcb->stkPtr < pCurTcb->stack)||(*(U32*)(pCurTcb->stack) != MAGIC_WORD))       
    {									
        CoStkOverflowHook(pCurTcb->taskID);       /* Yes,call handler         */		
    }   
#endif
 	
    SwitchContext();                              /* Call task context switch */
}


/**
 *******************************************************************************
 * @brief      Assign a TCB to task being created	 					
 * @param[in]  None     
 * @param[out] None     
 * 	 
 * @retval     XXXX							 
 *
 * @par Description
 * @details    This function is called to assign a task control block for task 
 *              being created.
 *******************************************************************************
 */
static P_OSTCB AssignTCB(void)
{
    P_OSTCB	ptcb;
    
    OsSchedLock();                      /* Lock schedule                      */
    if(FreeTCB == NULL)                 /* Is there no free TCB               */
    {
        OsSchedUnlock();                /* Yes,unlock schedule                */
        return NULL;                    /* Error return                       */
    }	
	ptcb    = FreeTCB;          /* Yes,assgin free TCB for this task  */    
	/* Set next item as the head of free TCB list                     */
    FreeTCB = FreeTCB->TCBnext; 
	OsSchedUnlock();
	return ptcb;
}


/**
 *******************************************************************************
 * @brief      Create a task	   
 * @param[in]  task       Task code entry.
 * @param[in]  argv       The parameter passed to task.
 * @param[in]  parameter  Task priority + stack size + time slice + isWaitting.
 * @param[in]  stk        Pointer to stack top of task.
 * @param[out] None   
 * @retval     E_CREATE_FAIL    Fail to create a task .
 * @retval     others           Valid task id.				 
 *
 * @par Description
 * @details    This function is called by application to create a task,return a id 
 *             to mark this task.
 *******************************************************************************
 */
OS_TID CreateTask(FUNCPtr task,void *argv,U32 parameter,OS_STK *stk)
{
    OS_STK* stkTopPtr;
    P_OSTCB ptcb;
    U8      prio;
#if CFG_ROBIN_EN >0	
    U16     timeSlice;
#endif
   
#if CFG_STK_CHECKOUT_EN >0              /* Check validity of parameter        */
    U16 sktSz;
    sktSz = (parameter&0xfff00)>>8;    
#endif
    prio = parameter&0xff;

#if CFG_PAR_CHECKOUT_EN >0              /* Check validity of parameter        */
    if(task == NULL)
    {
        return E_CREATE_FAIL;
    }
    if(stk == NULL)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -