コード例 #1
0
ファイル: core.c プロジェクト: benzeng/AutoQuad
/**
 *******************************************************************************
 * @brief      Initialize OS
 * @param[in]  None
 * @param[out] None
 * @retval     None
 *
 * @par Description
 * @details   This function is called to initialize OS.
 *
 * @note      You must call this function first,before any other OS API function
 *
 * @code      There is a example for useage of this function,as follows:
 *        e.g.
 *            ...                   // Your target initial code.
 *
 *            OsInit();             // Initial OS.
 *            CreateTask(...);      // Create tasks.
 *            ...
 *            OsStart();            // Start multitask.
 * @endcode
 *******************************************************************************
 */
void CoInitOS(void)
{
    InitSysTick();                /* Initialize system tick.                  */
    InitInt();                    /* Initialize PendSV,SVC,SysTick interrupt  */
    CreateTCBList();              /* Create TCB list.                         */
#if CFG_EVENT_EN > 0
    CreateEventList();            /* Create event control list.               */
#endif
#if CFG_KHEAP_EN > 0
    CoCreateKheap();              /* Create kernel heap within user define    */
#endif
    OsSchedLock();                /* Lock Schedule                            */
                                  /* Create first task -- IDLE task.          */
    CoCreateTask(                      CoIdleTask,
                                             Co_NULL,
                                  CFG_LOWEST_PRIO,
                 &idle_stk[CFG_IDLE_STACK_SIZE-1],
                              CFG_IDLE_STACK_SIZE
                 );
				                  /* Set PSP for CoIdleTask coming in */
	SetEnvironment(&idle_stk[CFG_IDLE_STACK_SIZE-1]);
}
コード例 #2
0
ファイル: time.c プロジェクト: AlexeySinushkin/gd25q32
/**
 *******************************************************************************
 * @brief      Reset task delay ticks	 
 * @param[in]  ptcb    Task that want to insert into DELAY list.
 * @param[in]  ticks   Specify system tick number which will delay .			 
 * @param[out] None  
 * @retval     E_CALL               Error call in ISR.
 * @retval     E_INVALID_ID         Invalid task id.
 * @retval     E_NOT_IN_DELAY_LIST  Task not in delay list.
 * @retval     E_OK                 The current task was inserted to DELAY list 
 *                                  successful,it will delay for specify time.		 
 * @par Description
 * @details    This function delay specify ticks for current task.
 ******************************************************************************* 	
 */
StatusType CoResetTaskDelayTick(OS_TID taskID,U32 ticks)
{
    P_OSTCB ptcb;
	

#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];
#if CFG_PAR_CHECKOUT_EN >0 
    if(ptcb->stkPtr == Co_NULL)
    {
        return E_INVALID_ID;
    }
#endif

    if(ptcb->delayTick == INVALID_VALUE)  /* Is tick==INVALID_VALUE?          */
    {
        return E_NOT_IN_DELAY_LIST;       /* Yes,error return                 */
    }
    OsSchedLock();                        /* Lock schedule                    */
    RemoveDelayList(ptcb);                /* Remove task from the DELAY list  */
    
    if(ticks == 0)                        /* Is delay tick==0?                */
    {
        InsertToTCBRdyList(ptcb);         /* Insert task into the DELAY list  */
    }
    else
    {									
        InsertDelayList(ptcb,ticks);      /* No,insert task into DELAY list   */
    }
    OsSchedUnlock();                /* Unlock schedule,and call task schedule */
    return E_OK;                          /* Return OK                        */
}
コード例 #3
0
ファイル: queue.c プロジェクト: PrinceBalabis/mahm3lib
/**
 *******************************************************************************
 * @brief      Post a mail to queue	   
 * @param[in]  id      Event ID.
 * @param[in]  pmail   Pointer to mail that want to send.	 	 
 * @param[out] None   
 * @retval     E_OK
 * @retval     E_INVALID_ID
 * @retval     E_QUEUE_FULL		 
 *
 * @par Description
 * @details    This function is called to post a mail to queue.
 * @note 
 *******************************************************************************
 */
StatusType CoPostQueueMail(OS_EventID id,void* pmail)
{	
    P_ECB pecb;
    P_QCB pqcb;
#if CFG_PAR_CHECKOUT_EN >0                     
    if(id >= CFG_MAX_EVENT)	
    {
        return E_INVALID_ID;          
    }
#endif

    pecb = &EventTbl[id];
#if CFG_PAR_CHECKOUT_EN >0
    if(pecb->eventType != EVENT_TYPE_QUEUE)   
    {
        return E_INVALID_ID;            /* The event type isn't queue,return  */	
    }	
#endif
    pqcb = (P_QCB)pecb->eventPtr;	
    if(pqcb->qSize == pqcb->qMaxSize)   /* If queue is full                   */
    {
        return E_QUEUE_FULL;
    }
    else                                /* If queue is not full               */
    {
        OsSchedLock();
        *(pqcb->qStart + pqcb->tail) = pmail;   /* Insert message into queue  */
        pqcb->tail++;                           /* Update queue tail          */
        pqcb->qSize++;          /* Update the number of messages in the queue */
        if(pqcb->tail == pqcb->qMaxSize)        /* Check queue tail           */   
        {
            pqcb->tail = 0;	
        }
        EventTaskToRdy(pecb);           /* Check the event waiting list       */
        OsSchedUnlock();
        return E_OK;
    }
}
コード例 #4
0
ファイル: mutex.c プロジェクト: AlexeySinushkin/gd25q32
/**
 *******************************************************************************
 * @brief      Create a mutex	 
 * @param[in]  None	 	 
 * @param[out] None  
 * @retval     E_CREATE_FAIL  Create mutex fail.
 * @retval     others         Create mutex successful.		 
 *
 * @par Description					  
 * @details    This function is called to create a mutex. 
 * @note  		
 *******************************************************************************
 */
OS_MutexID CoCreateMutex(void)
{
    OS_MutexID id;
    P_MUTEX pMutex;
    OsSchedLock();
    
    /* Assign a free mutex control block */
    if(MutexFreeID < CFG_MAX_MUTEX )
    {
        id  = MutexFreeID++;
        OsSchedUnlock();
        pMutex = &MutexTbl[id];
        pMutex->hipriTaskID  = INVALID_ID;
        pMutex->originalPrio = 0xff;
        pMutex->mutexFlag    = MUTEX_FREE;  /* Mutex is free,not was occupied */
        pMutex->taskID       = INVALID_ID;
        pMutex->waittingList = Co_NULL;
        return id;                      /* Return mutex ID                    */			
    }	
    
    OsSchedUnlock();	 
    return E_CREATE_FAIL;               /* No free mutex control block        */	
}
コード例 #5
0
ファイル: mbox.c プロジェクト: JoeSc/CooCox_lpc1114
/**
 *******************************************************************************
 * @brief      Accept a mailbox	 
 * @param[in]  id    Event ID.  	 
 * @param[out] perr  A pointer to error code.  
 * @retval     NULL
 * @retval     A pointer to mailbox accepted.			 
 *
 * @par Description
 * @details    This function is called to accept a mailbox. 
 * @note 
 *******************************************************************************
 */
void* CoAcceptMail(OS_EventID id,StatusType* perr)
{
    P_ECB pecb;
    void* pmail;
#if CFG_PAR_CHECKOUT_EN >0
    if(id >= CFG_MAX_EVENT)	                
    {
        *perr = E_INVALID_ID;             /* Invalid 'id'                     */
        return NULL;
    }
#endif
    pecb = &EventTbl[id];
    
#if CFG_PAR_CHECKOUT_EN >0
    if(pecb->eventType != EVENT_TYPE_MBOX)/* Invalid event control block type */
    {
        *perr = E_INVALID_ID;	
        return NULL;
    }
#endif
	OsSchedLock();
    if(pecb->eventCounter == 1)             /* If there is already a message  */
    {
        *perr = E_OK;
        pmail = pecb->eventPtr;             /* Get the message                */
        pecb->eventPtr     = NULL;          /* Clear the mailbox              */
        pecb->eventCounter = 0;
		OsSchedUnlock();
        return pmail;                       /* Return the message received    */		
    }
    else                                    /* If the mailbox is empty        */
    {	
		OsSchedUnlock();
        *perr = E_MBOX_EMPTY;               /* Mailbox is empty,return NULL   */
        return NULL;	
    }
}
コード例 #6
0
ファイル: event.c プロジェクト: cxjlante/at91sam3s
/**
 *******************************************************************************
 * @brief      Delete a event	  
 * @param[in]  pecb     Pointer to event control block which will be deleted. 
 * @param[in]  opt      Delete option.
 * @arg        == OPT_DEL_ANYWAY     Delete event always   
 * @arg        == OPT_DEL_NO_PEND	 Delete event only when no task pending on.
 * @param[out] None  	 
 * @retval     E_INVALID_PARAMETER   Parameter passed is invalid,deleted fail.
 * @retval     E_TASK_WAITTING       These are one more tasks waitting event.  
 * @retval     E_OK                  Delete event control block successful.
 *		  	
 * @par Description
 * @details    This function is called to delete a event from the event wait list
 *             use specify option.
 *
 * @note       This is a internal function of Coocox CoOS,user can't call.		
 *******************************************************************************
 */
StatusType DeleteEvent(P_ECB pecb,U8 opt)
{
    P_OSTCB ptcb;
    if(opt == OPT_DEL_NO_PEND)          /* Do delete event when no task pend? */
    {
        if(pecb->eventTCBList != NULL)  /* Yes,is there task pend this event? */
        {
            return E_TASK_WAITING;      /* Yes,error return                   */
        }
        else
        {
            ReleaseECB(pecb);           /* No,release resource that event hold*/
        }
    }
    else if(opt == OPT_DEL_ANYWAY)      /* Do delete event anyway?            */
    {
        OsSchedLock();                      /* Lock schedule                  */
        while(pecb->eventTCBList != NULL)   /* Is there task pend this event? */
        {                                   /* Yes,remove it                  */
            ptcb = pecb->eventTCBList;/* Get first task in event waiting list */
            if(ptcb->delayTick != INVALID_VALUE) /* Is task in delay list?    */
            {
                RemoveDelayList(ptcb);    /* Yes,remove task from delay list  */
            }

            /* Set next item as event waiting list head */
            pecb->eventTCBList = ptcb->waitNext; 
            ptcb->waitNext     = NULL;  /* Clear link for event waiting list  */
            ptcb->eventID      = INVALID_ID;  /* Sign that not to use.        */

			InsertToTCBRdyList(ptcb);         /* Insert task into ready list  */
        }
        OsSchedUnlock();                  /* Unlock schedule                  */
        ReleaseECB(pecb);                 /* Release resource that event hold */
    }
    return E_OK;                          /* Return OK                        */
}
コード例 #7
0
ファイル: timer.c プロジェクト: PrinceBalabis/mahm3lib
/**
 *******************************************************************************
 * @brief      Remove a timer from the timer list	  
 * @param[in]  tmrID    Specify ID for a timer which removed form timer list.	 
 * @param[out] None 
 * @retval     None
 *
 * @par Description
 * @details    This function is called to remove a timer from the timer list. 
 *******************************************************************************
 */
static void RemoveTmrList(OS_TCID tmrID)
{
    P_TmrCtrl pTmr;
    
    pTmr = &TmrTbl[tmrID];
    
    OsSchedLock();                      /* Lock schedule                      */
    
    /* Is there only one item in timer list?                                  */
    if((pTmr->tmrPrev == NULL) && (pTmr->tmrNext == NULL))
    {		
        TmrList = NULL;                 /* Yes,set timer list as NULL         */ 	
    }
    else if(pTmr->tmrPrev == NULL)      /* Is the first item in timer list?   */
    {   /* Yes,remove timer from list,and reset timer list                    */
        TmrList  = pTmr->tmrNext;
        TmrList->tmrPrev = NULL;
        pTmr->tmrNext->tmrCnt += pTmr->tmrCnt;
        pTmr->tmrNext    = NULL;  
    }
    else if(pTmr->tmrNext == NULL)      /* Is the last item in timer list?    */
    {
        /* Yes,remove timer form list */
        pTmr->tmrPrev->tmrNext = NULL;	
        pTmr->tmrPrev = NULL;
    }
    else                                /* No, remove timer from list         */
    {
        pTmr->tmrPrev->tmrNext  =  pTmr->tmrNext;
        pTmr->tmrNext->tmrPrev  =  pTmr->tmrPrev;
        pTmr->tmrNext->tmrCnt  += pTmr->tmrCnt;
        pTmr->tmrNext = NULL;
        pTmr->tmrPrev = NULL;
    }
    OsSchedUnlock();                    /* Unlock schedule                    */
}
コード例 #8
0
ファイル: mm.c プロジェクト: inf3ct3d/fmtr
/**
 *******************************************************************************
 * @brief      Delete a memory partition	  
 * @param[in]  mmID     Specify	memory partition that want to delete.	
 * @param[out] None
 * @retval     E_INVALID_ID   The memory partition id passed was invalid,delete fail.
 * @retval     E_OK           Delete successful.			 
 *
 * @par Description
 * @details    This function is called to Delete a memory partition.
 *******************************************************************************
 */
StatusType CoDelMemoryPartition(OS_MMID mmID)
{
    P_MM  memCtl;
#if CFG_PAR_CHECKOUT_EN >0              /* Check validity of parameter        */
    if(mmID >= CFG_MAX_MM)
    {
        return E_INVALID_ID;
    }
    if( ((1<<mmID)&MemoryIDVessel) == 0)
    {
        return E_INVALID_ID;
    }
#endif	
    OsSchedLock();                      /* Lock schedule                      */
    memCtl = &MemoryTbl[mmID];          /* Release memory control block       */
    MemoryIDVessel &= ~(1<<mmID);
    OsSchedUnlock();                    /* Unlock schedule                    */
    
    memCtl->memAddr   = NULL;
    memCtl->freeBlock = NULL;	
    memCtl->blockSize = 0;
    memCtl->blockNum  = 0;	
    return E_OK;                        /* Return OK                          */
}
コード例 #9
0
ファイル: sem.c プロジェクト: AlexeySinushkin/gd25q32
/**
 *******************************************************************************
 * @brief       Post a semaphore	 
 * @param[in]   id   id of event control block associated with the desired semaphore.	 	 
 * @param[out]  None   
 * @retval      E_INVALID_ID   Parameter id passed was invalid event ID.
 * @retval      E_SEM_FULL     Semaphore full. 
 * @retval      E_OK           Semaphore had post successful.
 *
 * @par Description
 * @details    This function is called to post a semaphore to corresponding event. 
 *
 * @note 
 *******************************************************************************
 */
StatusType CoPostSem(OS_EventID id)
{
    P_ECB pecb;
#if CFG_PAR_CHECKOUT_EN >0
    if(id >= CFG_MAX_EVENT)	                  
    {
        return E_INVALID_ID;
    }
#endif

    pecb = &EventTbl[id];
#if CFG_PAR_CHECKOUT_EN >0
    if(pecb->eventType != EVENT_TYPE_SEM) /* Invalid event control block type */
    {
        return E_INVALID_ID;	
    }
#endif

    /* Make sure semaphore will not overflow */
    if(pecb->eventCounter == pecb->initialEventCounter) 
    {
        return E_SEM_FULL;    /* The counter of Semaphore reach the max number*/
    }
    OsSchedLock();
	if(pecb->eventTCBList != Co_NULL)
    {
    	EventTaskToRdy(pecb);
    	OsSchedUnlock();
    	return E_OK;
    }
    pecb->eventCounter++;     /* Increment semaphore count to register event  */
    EventTaskToRdy(pecb);     /* Check semaphore event waiting list           */
    OsSchedUnlock();
    return E_OK;
		
}
コード例 #10
0
ファイル: time.c プロジェクト: AlexeySinushkin/gd25q32
/**
 *******************************************************************************
 * @brief      Delay current task for specify ticks number	  
 * @param[in]  ticks    Specify system tick number which will delay.			 
 * @param[out] None  
 * @retval     E_CALL   Error call in ISR.
 * @retval     E_OK     The current task was insert to DELAY list successful,it
 *                      will delay specify time.		 
 * @par Description
 * @details    This function delay specify ticks for current task.
 *
 * @note       This function be called in ISR,do nothing and return immediately.
 *******************************************************************************	
 */
StatusType CoTickDelay(U32 ticks)
{
    if(OSIntNesting >0)	                /* Is call in ISR?                    */
    {
        return E_CALL;                  /* Yes,error return                   */
    }
    
    if(ticks == INVALID_VALUE)          /* Is tick==INVALID_VALUE?            */
    {
        return E_INVALID_PARAMETER;     /* Yes,error return                   */
    }	
    if(ticks == 0)                      /* Is tick==0?                        */
    {
        return E_OK;                    /* Yes,do nothing ,return OK          */
    }
    if(OSSchedLock != 0)                /* Is OS lock?                        */
    {
        return E_OS_IN_LOCK;            /* Yes,error return                   */
    }	
    OsSchedLock();                      /* Lock schedule                      */
    InsertDelayList(TCBRunning,ticks);	/* Insert task in DELAY list          */
    OsSchedUnlock();                /* Unlock schedule,and call task schedule */
    return E_OK;                        /* Return OK                          */
}
コード例 #11
0
ファイル: core.c プロジェクト: jiezhi320/quadfork
/**
 *******************************************************************************
 * @brief      Lock schedule
 * @param[in]  None
 * @param[out] None
 * @retval     None
 *
 * @par Description
 * @details    This function is called in application code to lock schedule.
 *
 * @note
 *******************************************************************************
 */
void CoSchedLock(void) {
	OsSchedLock();                      /* Lock schedule                      */
}
コード例 #12
0
ファイル: queue.c プロジェクト: PrinceBalabis/mahm3lib
/**
 *******************************************************************************
 * @brief      Pend for a mail	 
 * @param[in]  id       Event ID.	 
 * @param[in]  timeout  The longest time for writting mail.	
 * @param[out] perr     A pointer to error code.   
 * @retval     NULL	
 * @retval     A pointer to mail accept.	 
 *
 * @par Description
 * @details    This function is called to wait for a mail.		   	
 * @note 
 *******************************************************************************
 */
void* CoPendQueueMail(OS_EventID id,U32 timeout,StatusType* perr)
{
    P_ECB   pecb;
    P_QCB   pqcb;
    P_OSTCB curTCB;
    void*   pmail;
    if(OSIntNesting > 0)                /* If the caller is ISR               */
    {
        *perr = E_CALL;
        return NULL;
    }
#if CFG_PAR_CHECKOUT_EN >0
    if(id >= CFG_MAX_EVENT)	         
    {
        *perr = E_INVALID_ID;           /* Invalid event id,return error      */
        return NULL;
    }
#endif

    pecb = &EventTbl[id];
#if CFG_PAR_CHECKOUT_EN >0
    if(pecb->eventType != EVENT_TYPE_QUEUE) /* The event type is not queue    */
    {
        *perr = E_INVALID_ID;
        return NULL;	
    }
#endif	
    if(OSSchedLock != 0)                /* Judge schedule is locked or not?   */
    {	
        *perr = E_OS_IN_LOCK;           /* Schedule is locked,return error    */								 
        return NULL;          
    }	
    pqcb = (P_QCB)pecb->eventPtr;       /* Point at queue control block       */
	 
    if(pqcb->qSize != 0)            /* If there are any messages in the queue */
    {
        /* Extract oldest message from the queue                              */
        pmail = *(pqcb->qStart + pqcb->head);   
        pqcb->head++;                   /* Update the queue head              */ 
        pqcb->qSize--;          /* Update the number of messages in the queue */  
        if(pqcb->head == pqcb->qMaxSize)/* Check queue head                   */
        {
            pqcb->head = 0;	
        }
        *perr = E_OK;
        return pmail;                   /* Return message received            */
    }
    else                                /* If there is no message in the queue*/
    {
        curTCB = TCBRunning;
        if(timeout == 0)                /* If time-out is not configured      */
        {
            /* Block current task until the event occur                       */
            EventTaskToWait(pecb,curTCB); 
            
            /* Have recived message or the queue have been deleted            */
            pmail = curTCB->pmail;              
            curTCB->pmail = NULL;
            *perr = E_OK;
            return pmail;               /* Return message received or NULL    */
        }
        else                            /* If time-out is configured          */
        {
            OsSchedLock(); 
            
            /* Block current task until event or timeout occurs               */           
            EventTaskToWait(pecb,curTCB);       
            InsertDelayList(curTCB,timeout);
            OsSchedUnlock();
            if(curTCB->pmail == NULL)   /* If time-out occurred               */
            {
                *perr = E_TIMEOUT;
                return NULL;
            }
            else                        /* If event occured                   */
            {
                pmail = curTCB->pmail;
                curTCB->pmail = NULL;
                *perr = E_OK;
                return pmail;           /* Return message received or NULL    */
            }				
        }	
    }
}
コード例 #13
0
ファイル: timer.c プロジェクト: PrinceBalabis/mahm3lib
/**
 *******************************************************************************
 * @brief      Insert a timer into the timer list	   
 * @param[in]  tmrID    Specify timer ID which insertted.		 
 * @param[out] None  
 * @retval     E_INVALID_ID  Timer ID passed was invalid,insert fail.
 * @retval     E_OK          Insert successful.			 
 *
 * @par Description
 * @details    This function is called to insert a timer into the timer list.  
 *******************************************************************************
 */
static void InsertTmrList(OS_TCID tmrID)
{
    P_TmrCtrl pTmr;
    S32 deltaTicks;
    U32 tmrCnt;
    tmrCnt = TmrTbl[tmrID].tmrCnt;      /* Get timer time                     */
    
    if(tmrCnt == 0)                     /* Is timer time==0?                  */
    {
        return;                         /* Do nothing,return                  */
    }
    
    OsSchedLock();                      /* Lock schedule                      */
    if(TmrList == NULL)                 /* Is no item in timer list?          */
    {
        TmrList = &TmrTbl[tmrID];       /* Yes,set this as first item         */
    }
    else                  /* No,find correct place ,and insert inserted timer */
    {								    
      	pTmr       = TmrList; 
      	deltaTicks = (S32) tmrCnt;            /* Get timer tick                     */
      	
      	/* find correct place */
      	while(pTmr != NULL)
      	{				    
            deltaTicks -= (S32) (pTmr->tmrCnt); /* Get ticks with previous item       */
            if(deltaTicks < 0)          /* Is delta ticks<0?                  */  
            {	
                /* Yes,get correct place */
                if(pTmr->tmrPrev!= NULL)/* Is head item of timer list?        */
                {	
                    /* No,insert into */
                    pTmr->tmrPrev->tmrNext = &TmrTbl[tmrID]; 
                    TmrTbl[tmrID].tmrPrev  = pTmr->tmrPrev;
                    TmrTbl[tmrID].tmrNext  = pTmr;
                    pTmr->tmrPrev          = &TmrTbl[tmrID];
                }
                else                    /* Yes,set task as first item         */ 	
                {
                    TmrTbl[tmrID].tmrNext = TmrList;
                    TmrList->tmrPrev      = &TmrTbl[tmrID];
                    TmrList               = &TmrTbl[tmrID];
                }
                TmrTbl[tmrID].tmrCnt            = (U32)((S32)(TmrTbl[tmrID].tmrNext->tmrCnt) + deltaTicks);
                TmrTbl[tmrID].tmrNext->tmrCnt  -= TmrTbl[tmrID].tmrCnt; 
                break;	
            }
            /* Is last item in list? */									
            else if ((deltaTicks >= 0) && (pTmr->tmrNext == NULL))
            {	
                /* Yes,insert into */
                TmrTbl[tmrID].tmrPrev = pTmr;
                pTmr->tmrNext         = &TmrTbl[tmrID];	
                TmrTbl[tmrID].tmrCnt  = (U32) deltaTicks;
                break;	
            }
            pTmr = pTmr->tmrNext;       /* Get the next item in timer list    */	
      	}
    }
    OsSchedUnlock();                    /* Unlock schedule                    */
}
コード例 #14
0
ファイル: task.c プロジェクト: AlexeySinushkin/gd25q32
/**
 *******************************************************************************
 * @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 = Co_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 != Co_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;
}
コード例 #15
0
ファイル: mutex.c プロジェクト: AlexeySinushkin/gd25q32
/**
 *******************************************************************************
 * @brief      Leave from a critical area	 
 * @param[in]  mutexID 	Specify mutex id.	 
 * @param[out] None 
 * @retval     E_INVALID_ID  Invalid mutex id.
 * @retval     E_CALL        Error call in ISR.
 * @retval     E_OK          Exit a critical area successful.
 *
 * @par Description		 
 * @details    This function must be called when exiting from a critical area.	
 * @note 
 *******************************************************************************
 */
StatusType CoLeaveMutexSection(OS_MutexID mutexID)
{
    P_OSTCB ptcb;
    P_MUTEX pMutex;
    U8      prio;
    U8      taskID;
    
    if(OSIntNesting > 0)                /* If the caller is ISR               */
    {
        return E_CALL;
    }

#if CFG_PAR_CHECKOUT_EN >0
    if(mutexID >= MutexFreeID)
    {
        return E_INVALID_ID;            /* Invalid mutex id, return error     */
    }
#endif	
    OsSchedLock();
    pMutex = &MutexTbl[mutexID];        /* Obtain point of mutex control block*/   
    ptcb = &TCBTbl[pMutex->taskID];
	ptcb->mutexID = INVALID_ID;
	if(pMutex->waittingList == Co_NULL)    /* If the mutex waiting list is empty */
    {
        pMutex->mutexFlag = MUTEX_FREE; /* The mutex resource is available    */
        pMutex->taskID    = INVALID_ID;
        OsSchedUnlock();
    }	
    else              /* If there is at least one task waitting for the mutex */
    { 
        taskID = pMutex->taskID;        /* Get task ID of mutex owner         */
        
                                /* we havn't promoted current task's priority */
        if(pMutex->hipriTaskID == taskID)   
        {
            ptcb = pMutex->waittingList;/* Point to mutex first waiting task  */		
            prio = ptcb->prio; 
            while(ptcb != Co_NULL)         /* Find the highest priority task     */
            {
                if(ptcb->prio < prio)  		
                {
                    prio = ptcb->prio;
                    pMutex->hipriTaskID = ptcb->taskID;
                }
                ptcb = ptcb->TCBnext;					
            }
        }
        else                     /* we have promoted current task's priority  */
        {
			prio = TCBTbl[taskID].prio;
        }
        
        /* Reset the task priority */
		pMutex->taskID = INVALID_ID;	
		CoSetPriority(taskID,pMutex->originalPrio);
        
        /* Find first task in waiting list ready to run  */	
        ptcb                 = pMutex->waittingList; 		
        pMutex->waittingList = ptcb->TCBnext;	
        pMutex->originalPrio = ptcb->prio;
        pMutex->taskID       = ptcb->taskID;

#if CFG_ORDER_LIST_SCHEDULE_EN ==0
		if(prio != ptcb->prio)
		{
			DeleteTaskPri(ptcb->prio);
			ActiveTaskPri(prio);			
		}
#endif	

        ptcb->prio           = prio;    /* Raise the task's priority          */       
        				   
        /* Insert the task which acquire the mutex into ready list.           */
        ptcb->TCBnext = Co_NULL;
        ptcb->TCBprev = Co_NULL;

		InsertToTCBRdyList(ptcb);     /* Insert the task into the READY list  */
        OsSchedUnlock();
    }
    return E_OK;			
}
コード例 #16
0
ファイル: mutex.c プロジェクト: AlexeySinushkin/gd25q32
/**	
 *******************************************************************************		 	
 * @brief      Enter a critical area  
 * @param[in]  mutexID    Specify mutex. 	 
 * @param[out] None   
 * @retval     E_INVALID_ID  Invalid mutex id. 	
 * @retval     E_CALL        Error call in ISR.
 * @retval     E_OK          Enter critical area successful.
 *
 * @par Description
 * @details    This function is called when entering a critical area.	 
 * @note 
 *******************************************************************************
 */
StatusType CoEnterMutexSection(OS_MutexID mutexID)
{
    P_OSTCB ptcb,pCurTcb;
    P_MUTEX pMutex;

#if CFG_EVENT_EN >0
    P_ECB pecb;
#endif

    if(OSIntNesting > 0)                /* If the caller is ISR               */
    {
        return E_CALL;
    }
    if(OSSchedLock != 0)                /* Is OS lock?                        */
    {								 
        return E_OS_IN_LOCK;            /* Yes,error return                   */
    }	

#if CFG_PAR_CHECKOUT_EN >0
    if(mutexID >= MutexFreeID)          /* Invalid 'mutexID'                  */
    {
        return E_INVALID_ID;	
    }
#endif

    OsSchedLock();
    pCurTcb = TCBRunning;
    pMutex  = &MutexTbl[mutexID];
    
    pCurTcb->mutexID = mutexID;
    if(pMutex->mutexFlag == MUTEX_FREE)       /* If mutex is available        */	 
    {
        pMutex->originalPrio = pCurTcb->prio; /* Save priority of owning task */   
        pMutex->taskID       = pCurTcb->taskID;   /* Acquire the resource     */
        pMutex->hipriTaskID  = pCurTcb->taskID;
        pMutex->mutexFlag    = MUTEX_OCCUPY;      /* Occupy the mutex resource*/
    }
    /* If the mutex resource had been occupied                                */
    else if(pMutex->mutexFlag == MUTEX_OCCUPY)	 	
    {	
		ptcb = &TCBTbl[pMutex->taskID];
        if(ptcb->prio > pCurTcb->prio)  /* Need to promote priority of owner? */
        {
#if CFG_ORDER_LIST_SCHEDULE_EN ==0
			DeleteTaskPri(ptcb->prio);
			ActiveTaskPri(pCurTcb->prio);
#endif	
            ptcb->prio = pCurTcb->prio;	    /* Promote prio of owner          */
            
            /* Upgarde the highest priority about the mutex                   */
            pMutex->hipriTaskID	= pCurTcb->taskID;	
            if(ptcb->state == TASK_READY)   /* If the task is ready to run    */
            {
                RemoveFromTCBRdyList(ptcb); /* Remove the task from READY list*/
                InsertToTCBRdyList(ptcb);   /* Insert the task into READY list*/
            }
#if CFG_EVENT_EN >0
            /* If the task is waiting on a event                              */
            else if(ptcb->eventID != INVALID_ID) 
            {
                pecb = &EventTbl[ptcb->eventID];
                
                /* If the event waiting type is preemptive Priority           */
                if(pecb->eventSortType == EVENT_SORT_TYPE_PRIO)	
                {
                    /* Remove the task from event waiting list                */
                    RemoveEventWaittingList(ptcb);
                    
                    /* Insert the task into event waiting list                */ 	
                    EventTaskToWait(pecb,ptcb);		
                }	
            }
#endif	
        }
        
        pCurTcb->state   = TASK_WAITING;    /* Block current task             */
		TaskSchedReq     = Co_TRUE;
        pCurTcb->TCBnext = Co_NULL;
        pCurTcb->TCBprev = Co_NULL;
        
        ptcb = pMutex->waittingList;
        if(ptcb == Co_NULL)               /* If the event waiting list is empty  */
        {
            pMutex->waittingList = pCurTcb; /* Insert the task to head        */
        }
        else                        /* If the event waiting list is not empty */
        {            	
            while(ptcb->TCBnext != Co_NULL)    /* Insert the task to tail        */
            {
                ptcb = ptcb->TCBnext;		
            }
            ptcb->TCBnext    = pCurTcb;
            pCurTcb->TCBprev = ptcb;
            pCurTcb->TCBnext = Co_NULL;
        }
    }
    OsSchedUnlock();
    return E_OK;			
}
コード例 #17
0
ファイル: sem.c プロジェクト: chrisy/coos-test
/**
 *******************************************************************************
 * @brief       wait for a semaphore	   
 * @param[in]   id       Event ID.	
 * @param[in]   timeout  The longest time for writting semaphore.
 * @para        0        
 * @para        0x1~0xff 	 
 * @param[out]  None  
 * @retval      E_CALL         Error call in ISR.   
 * @retval      E_INVALID_ID   Invalid event ID.	
 * @retval      E_TIMEOUT      Semaphore was not received within the specified 
 *                             'timeout' time.
 * @retval      E_OK           The call was successful and your task owns the 
 *                             resource,or the event you are waiting for occurred.	
 * 
 * @par Description
 * @details    This function is called to waits for a semaphore. 
 * @note       IF this function is called in ISR,nothing to do and return immediately.
 *******************************************************************************
 */
StatusType CoPendSem(OS_EventID id,U32 timeout)
{
    P_ECB 	 pecb;
    P_OSTCB  curTCB;
    if(OSIntNesting > 0)                /* If the caller is ISR               */
    {
        return E_CALL;
    }
#if CFG_PAR_CHECKOUT_EN >0
    if(id >= CFG_MAX_EVENT)	            
    {
        return E_INVALID_ID;
    }
#endif

	  pecb = &EventTbl[id];
#if CFG_PAR_CHECKOUT_EN >0
    if(pecb->eventType != EVENT_TYPE_SEM)     
    {
       return E_INVALID_ID;	
    }
#endif
    if(OSSchedLock != 0)                /* Schdule is locked?                 */
    {
        return E_OS_IN_LOCK;            /* Yes,error return                   */
    }
    OsSchedLock();
    if(pecb->eventCounter > 0) /* If semaphore is positive,resource available */       
    {	
        pecb->eventCounter--;         /* Decrement semaphore only if positive */
        OsSchedUnlock();
        return E_OK;	
    }
    else                                /* Resource is not available          */
    {
        curTCB = TCBRunning;
        if(timeout == 0)                /* If time-out is not configured      */
        {
            EventTaskToWait(pecb,curTCB); /* Block task until event occurs    */ 
            pecb->eventCounter--;             
            curTCB->pmail = Co_NULL;
            OsSchedUnlock();
            return E_OK;
        }
        else                            /* If time-out is configured          */
        {
            /* Block task until event or timeout occurs                       */
            EventTaskToWait(pecb,curTCB);
            InsertDelayList(curTCB,timeout);
            
            OsSchedUnlock();
            if (curTCB->pmail == Co_NULL)  /* If pmail is Co_NULL, time-out occurred*/
            {
              return E_TIMEOUT;	
            }                               
            else                  /* Event occurred or event have been deleted*/    
            {
                OsSchedLock();
                curTCB->pmail = Co_NULL;
                pecb->eventCounter--; 
                OsSchedUnlock();
                return E_OK;	
            }				
        }		
    }
}
コード例 #18
0
ファイル: mbox.c プロジェクト: JoeSc/CooCox_lpc1114
/**
 *******************************************************************************
 * @brief      Wait for a mailbox	 
 * @param[in]  id       Event ID.	 
 * @param[in]  timeout  The longest time for writting mail.	    
 * @param[out] perr     A pointer to error code.	  
 * @retval     NULL	
 * @retval     A pointer to mailbox accept.
 *
 * @par Description
 * @details    This function is called to wait a mailbox.	 
 * @note 
 *******************************************************************************
 */
void* CoPendMail(OS_EventID id,U32 timeout,StatusType* perr)
{
    P_ECB pecb;
    void* pmail;
    P_OSTCB  curTCB;
     
    if(OSIntNesting > 0)                /* If the caller is ISR               */
    {
        *perr = E_CALL;
        return NULL;
    }
    
#if CFG_PAR_CHECKOUT_EN >0
    if(id >= CFG_MAX_EVENT)              
    {
        *perr = E_INVALID_ID;           /* Invalid 'id',retrun error          */
        return NULL;
    }
#endif

    pecb = &EventTbl[id];
#if CFG_PAR_CHECKOUT_EN >0
    if(pecb->eventType != EVENT_TYPE_MBOX)
    {
        *perr = E_INVALID_ID;       /* Invalid event type,not EVENT_TYPE_MBOX */
        return NULL;
    }
#endif

    if(OSSchedLock != 0)                /* Judge schedule is locked or not?   */
    {	
        *perr = E_OS_IN_LOCK;           /* Schedule is locked                 */								 
        return NULL;                    /* return NULL                        */
    }	
    if( pecb->eventCounter == 1)        /* If there is already a message      */
    {
        *perr = E_OK;
        pmail = pecb->eventPtr;         /* Get the message                    */
        pecb->eventPtr     = NULL;      /* Clear the mailbox                  */
        pecb->eventCounter = 0;             
        return pmail;                   /* Return the message received        */
    }
    else                       /* If message is not available, task will pend */ 
    {
        curTCB = TCBRunning;
        if(timeout == 0)                /* If time-out is not configured      */
        {
            EventTaskToWait(pecb,curTCB); /* Block task until event occurs    */
            *perr = E_OK;
            
            /* Have recived a message or the mailbox have been deleted        */
            pmail = curTCB->pmail;          
            curTCB->pmail = NULL;
            return pmail;               /* Return received message or NULL    */
        }
        else                            /* If time-out is configured          */
        {
            OsSchedLock();
            
            /* Block task until event or timeout occurs                       */
            EventTaskToWait(pecb,curTCB);   
            InsertDelayList(curTCB,timeout);
            OsSchedUnlock();
            if( curTCB->pmail == NULL)  /* Time-out occurred                  */
            {
                *perr = E_TIMEOUT;
                return NULL;	
            }
            else    /* Have recived a message or the mailbox have been deleted*/
            {
                *perr = E_OK;
                pmail = curTCB->pmail;
                curTCB->pmail = NULL;
                return pmail;           /* Return received message or NULL    */	
            }			
        }	
    }
}
コード例 #19
0
ファイル: flag.c プロジェクト: ChrelleP/autoquad
/**
 *******************************************************************************
 * @brief      WaitForSingleFlag
 * @param[in]  id        Flag ID.
 * @param[in]  timeout   The longest time for writting flag.
 * @param[out] None
 * @retval     E_CALL         Error call in ISR.
 * @retval     E_INVALID_ID   Invalid event ID.
 * @retval     E_TIMEOUT      Flag wasn't received within 'timeout' time.
 * @retval     E_OK           The call was successful and your task owns the Flag,
 *                            or the event you are waiting for occurred.
 *
 * @par Description
 * @details    This function is called to wait for only one flag,
 *             (1) if parameter "timeout" == 0,waiting until flag be set;
 *             (2) when "timeout" != 0,if flag was set or wasn't set but timeout
 *                 occured,the task will exit the waiting list,convert to READY
 *                 or RUNNING state.
 * @note
 *******************************************************************************
 */
StatusType CoWaitForSingleFlag(OS_FlagID id,U32 timeout)
{
    FLAG_NODE flagNode;
    P_FCB     pfcb;
    P_OSTCB   curTCB;

    if(OSIntNesting > 0)                /* See if the caller is ISR           */
    {
        return E_CALL;
    }
    if(OSSchedLock != 0)                /* Schedule is lock?                  */
    {
        return E_OS_IN_LOCK;            /* Yes,error return                   */
    }

#if CFG_PAR_CHECKOUT_EN >0
    if(id >= FLAG_MAX_NUM)              /* Judge id is valid or not?          */
    {
        return E_INVALID_ID;            /* Invalid 'id'                       */
    }
    if((FlagCrl.flagActive&(1<<id)) == 0 )/* Judge flag is active or not?       */
    {
        return E_INVALID_ID;            /* Flag is deactive ,return error     */
    }
#endif

   	OsSchedLock();
	pfcb = &FlagCrl;
    /* See if the required flag is set */
    if((pfcb->flagRdy&(1<<id)) != 0)    /* If the required flag is set        */
    {
        pfcb->flagRdy &= ~((pfcb->resetOpt&(1<<id))); /* Clear the flag       */
        OsSchedUnlock();
    }
    else                                /* If the required flag is not set    */
    {
        curTCB = TCBRunning;
        if(timeout == 0)                /* If time-out is not configured      */
        {
            /* Block task until the required flag is set                      */
            FlagBlock (&flagNode,(1<<id),OPT_WAIT_ONE);
            curTCB->state  = TASK_WAITING;
			TaskSchedReq   = Co_TRUE;
            OsSchedUnlock();

            /* The required flag is set and the task is in running state      */
            curTCB->pnode  = Co_NULL;
            OsSchedLock();

            /* Clear the required flag or not                                 */
            pfcb->flagRdy &= ~((1<<id)&(pfcb->resetOpt));
            OsSchedUnlock();
        }
        else                            /* If time-out is configured          */
        {
            /* Block task until the required flag is set or time-out occurs   */
            FlagBlock(&flagNode,(1<<id),OPT_WAIT_ONE);
            InsertDelayList(curTCB,timeout);

            OsSchedUnlock();
            if(curTCB->pnode == Co_NULL)     /* If time-out occurred             */
            {
                return E_TIMEOUT;
            }
            else                          /* If flag is set                   */
            {
                curTCB->pnode = Co_NULL;
                OsSchedLock();

                /* Clear the required flag or not                             */
                pfcb->flagRdy &= ~((1<<id)&(pfcb->resetOpt));
                OsSchedUnlock();
            }
        }
    }
    return E_OK;
}
コード例 #20
0
ファイル: event.c プロジェクト: cxjlante/at91sam3s
/**
 *******************************************************************************
 * @brief      Insert a task to event wait list 	  						  
 * @param[in]  pecb    Pointer to event control block corresponding to the event. 	
 * @param[in]  ptcb    Pointer to task that will be insert to event wait list.	 
 * @param[out] None   
 * @retval     None	 
 *
 * @par Description
 * @details   This function is called to insert a task by fllowing manner:
 *            opt == EVENT_SORT_TYPE_FIFO   By FIFO.
 *            opt == EVENT_SORT_TYPE_PRIO   By priority order,hghest priority 
 *                                          as head,lowest priority as end.
 *                                          (Highest-->...-->Lowest-->NULL)	
 *******************************************************************************
 */
void EventTaskToWait(P_ECB pecb,P_OSTCB ptcb)
{
    P_OSTCB ptcb1;
#if (CFG_EVENT_SORT == 2) || (CFG_EVENT_SORT == 3)
    P_OSTCB ptcb2;
#endif
    
    OsSchedLock();                  /* Lock schedule                          */
    ptcb1 = pecb->eventTCBList;     /* Get first task in event waiting list   */
    ptcb->eventID = pecb->id;       /* Set event ID for task                  */
    
#if CFG_EVENT_SORT == 3             /* Does event waiting list sort as FIFO?  */
                              
    if(pecb->eventSortType == EVENT_SORT_TYPE_FIFO)	
#endif
    
#if (CFG_EVENT_SORT == 1) || (CFG_EVENT_SORT == 3)
    {
        if(ptcb1 == NULL)                 /* Is no item in event waiting list?*/
        {
            pecb->eventTCBList = ptcb;    /* Yes,set task as first item       */
        }
        else
        {								
            while(ptcb1->waitNext != NULL)/* No,insert task in last           */
            {
                ptcb1 = ptcb1->waitNext;	
            }	
            ptcb1->waitNext = ptcb;       /* Set link for list                */
            ptcb->waitPrev  = ptcb1;	
        }
    }
#endif
    
#if CFG_EVENT_SORT ==3 /* Does event waiting list sort as preemptive priority?*/                           
    else if(pecb->eventSortType == EVENT_SORT_TYPE_PRIO)
#endif  
#if (CFG_EVENT_SORT == 2) || (CFG_EVENT_SORT == 3)
    {
        if(ptcb1 == NULL)               /* Is no item in event waiting list?  */
        {
            pecb->eventTCBList = ptcb;  /* Yes,set task as first item         */
        }
        /* Is PRI of task higher than list first item?                        */
        else if(ptcb1->prio > ptcb->prio) 
        {
            pecb->eventTCBList = ptcb;  /* Reset task as first item           */
            ptcb->waitNext     = ptcb1; /* Set link for list                  */
            ptcb1->waitPrev    = ptcb;	
        }
        else                            /* No,find correct place to insert    */
        {								
            ptcb2 = ptcb1->waitNext;
            while(ptcb2 != NULL)        /* Is last item?                      */
            {	                          
                if(ptcb2->prio > ptcb->prio)  /* No,is correct place?         */
                { 
                    break;                    /* Yes,break Circulation        */
                }
                ptcb1 = ptcb2;                /* Save current item            */
                ptcb2 = ptcb2->waitNext;      /* Get next item                */
            }
            ptcb1->waitNext = ptcb;           /* Set link for list            */
            ptcb->waitPrev  = ptcb1;
            ptcb->waitNext  = ptcb2;
            if(ptcb2 != NULL)
            {
                ptcb2->waitPrev = ptcb;	
            }
        }		
    }
#endif
    ptcb->state = TASK_WAITING;     /* Set task status to TASK_WAITING state  */
    TaskSchedReq = TRUE;
    OsSchedUnlock();                /* Unlock schedule,and call task schedule */
}
コード例 #21
0
ファイル: task.c プロジェクト: AlexeySinushkin/gd25q32
/**
 *******************************************************************************
 * @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 == Co_NULL)
    {
        return E_CREATE_FAIL;
    }
    if(stk == Co_NULL)
    {
        return E_CREATE_FAIL;
    }
    if(prio > CFG_LOWEST_PRIO)
    {
        return E_CREATE_FAIL;		
    }
#if CFG_STK_CHECKOUT_EN >0
    if(sktSz < 20)
    {
        return E_CREATE_FAIL;		
    }
#endif	  // CFG_STK_CHECKOUT_EN
#endif	  // CFG_PAR_CHECKOUT_EN

#if CFG_TASK_SCHEDULE_EN == 0
	if(TCBRunning != Co_NULL)
		 return E_CREATE_FAIL;	
#endif   

    stkTopPtr = InitTaskContext(task,argv,stk);   /* Initialize task context. */
    
    ptcb = AssignTCB();                 /* Get free TCB to use                */
    
    if(ptcb == Co_NULL)                    /* Is free TCB equal to Co_NULL?         */
    {
        return E_CREATE_FAIL;           /* Yes,error return                   */
    }
    
    ptcb->stkPtr = stkTopPtr;           /* Initialize TCB as user set         */
    ptcb->prio   = prio;
#if CFG_STK_CHECKOUT_EN >0
    ptcb->stack = stk+1 - sktSz; /* Set bottom stack for stack overflow check */
    *(U32*)(ptcb->stack) = MAGIC_WORD;
#endif	

#if CFG_TASK_WAITTING_EN >0
    ptcb->delayTick	= INVALID_VALUE;	
#endif		 

#if CFG_TASK_SCHEDULE_EN == 0
	ptcb->taskFuc = task;
	ptcb->taskStk = stk;
#endif     
    ptcb->TCBnext = Co_NULL;               /* Initialize TCB link in READY list  */
    ptcb->TCBprev = Co_NULL;

#if CFG_ROBIN_EN >0						/* Set task time slice for task robin */
    timeSlice = (parameter&0x7fff0000)>>20; 
    if(timeSlice == 0)
    {
        timeSlice = CFG_TIME_SLICE;
    }
    ptcb->timeSlice = timeSlice;
#endif

#if CFG_FLAG_EN > 0
    ptcb->pnode = Co_NULL;                 /* Initialize task as no flag waiting */
#endif

#if CFG_EVENT_EN > 0
    ptcb->eventID  = INVALID_ID;      	/* Initialize task as no event waiting*/
    ptcb->pmail    = Co_NULL;
    ptcb->waitNext = Co_NULL;
    ptcb->waitPrev = Co_NULL;
#endif

#if CFG_MUTEX_EN > 0
    /* Initialize task as no mutex holding or waiting                         */
    ptcb->mutexID = INVALID_ID; 
#endif 

#if CFG_ORDER_LIST_SCHEDULE_EN ==0
	ActiveTaskPri(prio);	
#endif	

	if((parameter>>31) == 0)			/* Is task in waitting state?         */
	{									/* No,set it into ready list          */
		OsSchedLock();                  /* Lock schedule                      */
		InsertToTCBRdyList(ptcb);       /* Insert into the READY list         */
	    OsSchedUnlock();                /* Unlock schedule                    */
	}
	else
	{									/* Yes,Set task status as TASK_WAITING*/
コード例 #22
0
ファイル: flag.c プロジェクト: ChrelleP/autoquad
/**
 *******************************************************************************
 * @brief      WaitForMultipleFlags
 * @param[in]  flags      Flags that waiting to active task.
 * @param[in]  waitType   Flags wait type.
 * @param[in]  timeout    The longest time for writting flag.
 * @param[out] perr       A pointer to error code.
 * @retval     0
 * @retval     springFlag
 *
 * @par Description
 * @details    This function is called to pend a task for waitting multiple flag.
 * @note
 *******************************************************************************
 */
U32 CoWaitForMultipleFlags(U32 flags,U8 waitType,U32 timeout,StatusType *perr)
{
    U32       springFlag;
    P_FCB     pfcb;
    FLAG_NODE flagNode;
    P_OSTCB   curTCB;


    if(OSIntNesting > 0)                /* If the caller is ISR               */
    {
        *perr = E_CALL;
        return 0;
    }
    if(OSSchedLock != 0)                /* Schedule is lock?                  */
    {
        *perr = E_OS_IN_LOCK;
        return 0;                       /* Yes,error return                   */
    }
#if CFG_PAR_CHECKOUT_EN >0
    if( (flags&FlagCrl.flagActive) != flags )
    {
        *perr = E_INVALID_PARAMETER;    /* Invalid 'flags'                    */
        return 0;
    }
#endif
    OsSchedLock();
	pfcb = &FlagCrl;
    springFlag = flags & pfcb->flagRdy;

    /* If any required flags are set  */
    if((springFlag != 0) && (waitType == OPT_WAIT_ANY))
    {
        pfcb->flagRdy &= ~(springFlag & pfcb->resetOpt);  /* Clear the flag   */
        OsSchedUnlock();
        *perr = E_OK;
        return springFlag;
    }

    /* If all required flags are set */
    if( (springFlag == flags) && (waitType == OPT_WAIT_ALL) )
    {
        pfcb->flagRdy &= ~(springFlag & pfcb->resetOpt);  /* Clear the flags  */
        OsSchedUnlock();
        *perr = E_OK;
        return springFlag;
    }

    curTCB = TCBRunning;
    if(timeout == 0)                    /* If time-out is not configured      */
    {
        /* Block task until the required flag are set                         */
        FlagBlock(&flagNode,flags,waitType);
        curTCB->state  = TASK_WAITING;
		TaskSchedReq   = Co_TRUE;
		OsSchedUnlock();

        curTCB->pnode  = Co_NULL;
        OsSchedLock();
        springFlag     = flags & pfcb->flagRdy;
        pfcb->flagRdy &= ~(springFlag & pfcb->resetOpt);/* Clear the flags    */
        OsSchedUnlock();
        *perr = E_OK;
        return springFlag;
    }
    else                                /* If time-out is configured          */
    {
        /* Block task until the required flag are set or time-out occurred    */
        FlagBlock(&flagNode,flags,waitType);
        InsertDelayList(curTCB,timeout);

        OsSchedUnlock();
        if(curTCB->pnode == Co_NULL)       /* If time-out occurred               */
        {
            *perr = E_TIMEOUT;
            return 0;
        }
        else                            /* If the required flags are set      */
        {
            curTCB->pnode = Co_NULL;
            OsSchedLock();
            springFlag    = flags & FlagCrl.flagRdy;

            /* Clear the required ready flags or not */
            pfcb->flagRdy &= ~(springFlag & pfcb->resetOpt);
            OsSchedUnlock();
            *perr = E_OK;
            return springFlag;
        }
    }
}