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

📄 emos_task.c

📁 emos是一个新的类似于ucos的内核
💻 C
📖 第 1 页 / 共 3 页
字号:
                       uint16     id,
                       EMOS_STK  *pbos,
                       uint32     stk_size,
                       void      *pext,
                       uint16     opt)
{
    void*     psp = NULL;
    uint8     err;
    uint16    i;
    EMOS_STK* pfill = NULL;


    if (prio > EMOS_LOWEST_PRIO)
    { 
    	/* Make sure priority is within allowable range */
        return (EMOS_PRIO_INVALID);
    }
    
    EMOS_ENTER_CRITICAL();
    if (gEmosTCBPrioTbl[prio] == (EMOS_TCB_T *)0) 
    { 
    	/* Make sure task doesn't already exist at this priority  */
        gEmosTCBPrioTbl[prio] = (EMOS_TCB_T *)1;    /* Reserve the priority to prevent others from doing ...  */
                                                    /* ... the same thing until task is created. */
        EMOS_EXIT_CRITICAL();
        
        if (opt & EMOS_TASK_OPT_STK_CHK) 
        {     
        	/* See if stack checking has been enabled */
            if (opt & EMOS_TASK_OPT_STK_CLR) 
            { 
            	/* See if stack needs to be cleared */
                pfill = pbos; /* Yes, fill the stack with zeros */
                for (i = 0; i < stk_size; i++) 
                {
                    #if EMOS_STK_GROWTH == 1
                    *pfill++ = (EMOS_STK)0;
                    #else
                    *pfill-- = (EMOS_STK)0;
                    #endif
                }
            }
        }

        /*two important init routine called by TaskCreate*/
        psp = (void *)emosTaskStkInit(task, pdata, ptos, opt); /* Initialize the task's stack */
        err = emosTCBInit(prio, (EMOS_STK *)psp, (EMOS_STK *)pbos, id, stk_size, pext, opt);         
        if (err == EMOS_NO_ERR) 
        {
            EMOS_ENTER_CRITICAL();
            gEmosTaskCtr++;                            /* Increment the #tasks counter */
            emosTaskCreateHook(gEmosTCBPrioTbl[prio]); /* Call user defined hook */
            EMOS_EXIT_CRITICAL();
            if (gEmosRunning) 
            {   
            	/* Find highest priority task if multitasking has started */
                emosSched();
            }
        } 
        
        else 
        {
            EMOS_ENTER_CRITICAL();
            gEmosTCBPrioTbl[prio] = (EMOS_TCB_T *)0;/* Make this priority available to others */
            EMOS_EXIT_CRITICAL();
        }
        
        return (err);
    } 

    else 
    {
        EMOS_EXIT_CRITICAL();
        return (EMOS_PRIO_EXIST);
    }
}
#endif


/*********************************************************************************************************
* DELETE A TASK
*
* Description: This function allows you to delete a task.  The calling task can delete itself by 
*              its own priority number.  The deleted task is returned to the dormant state and can be
*              re-activated by creating the deleted task again.
* Arguments  : prio    is the priority of the task to delete.  Note that you can explicitely delete
*                      the current task without knowing its priority level by setting 'prio' to
*                      EMOS_PRIO_SELF.
* Returns    : EMOS_NO_ERR           if the call is successful
*              EMOS_TASK_DEL_IDLE    if you attempted to delete uC/OS-II's idle task
*              EMOS_PRIO_INVALID     if the priority you specify is higher that the maximum allowed 
*                                  (i.e. >= EMOS_LOWEST_PRIO) or, you have not specified EMOS_PRIO_SELF.
*              EMOS_TASK_DEL_ERR     if the task you want to delete does not exist
*              EMOS_TASK_DEL_ISR     if you tried to delete a task from an ISR
* Notes      : 1) To reduce interrupt latency, OSTaskDel() 'disables' the task:
*                    a) by making it not ready
*                    b) by removing it from any wait lists
*                    c) by preventing OSTimeTick() from making the task ready to run.
*                 The task can then be 'unlinked' from the miscellaneous structures in uC/OS-II.
*              2) The function OSDummy() is called after EMOS_EXIT_CRITICAL() because, on most processors, 
*                 the next instruction following the enable interrupt instruction is ignored.  You can 
*                 replace OSDummy() with a macro that basically executes a NO OP (i.e. EMOS_NOP()).  The 
*                 NO OP macro would avoid the execution time of the function call and return.
*              3) An ISR cannot delete a task.
*              4) The lock nesting counter is incremented because, for a brief instant, if the current
*                 task is being deleted, the current task would not be able to be rescheduled because it
*                 is removed from the ready list.  Incrementing the nesting counter prevents another task
*                 from being schedule.  This means that the ISR would return to the current task which is
*                 being deleted.  The rest of the deletion would thus be able to be completed.
*********************************************************************************************************/
#if EMOS_TASK_DEL_EN
uint8 emosTaskDel (uint8 prio)
{
    EMOS_TCB_T* ptcb = NULL;
    EMOS_EVENT_T* pevent = NULL;


    if (prio == EMOS_IDLE_PRIO)
    {  
    	/* Not allowed to delete idle task*/
        return (EMOS_TASK_DEL_IDLE);
    }
    
    if (prio >= EMOS_LOWEST_PRIO && prio != EMOS_PRIO_SELF) 
    {   
    	/* Task priority valid ?*/
        return (EMOS_PRIO_INVALID);
    }
    
    EMOS_ENTER_CRITICAL();
    if (gEmosIntNesting > 0) 
    { 
    	/* See if trying to delete from ISR    */
        EMOS_EXIT_CRITICAL();
        return (EMOS_TASK_DEL_ISR);
    }
    
    if (prio == EMOS_PRIO_SELF) 
    {  
    	/* See if requesting to delete self    */
        prio = gEmosTCBCur->osTCBPrio; /* Set priority to delete to current   */
    }
    
    if ((ptcb = gEmosTCBPrioTbl[prio]) != (EMOS_TCB_T *)0) 
    {   
    	/* Task to delete must exist*/
        if ((gEmosRdyTbl[ptcb->osTCBY] &= ~ptcb->osTCBBitX) == 0) 
        {
        	 /* Make task not ready*/
            gEmosRdyGrp &= ~ptcb->osTCBBitY;
        }
        
        if ((pevent = ptcb->osTCBEventPtr) != (EMOS_EVENT_T *)0) 
        {  
        	/* If task is waiting on event */
            if ((pevent->osEventTbl[ptcb->osTCBY] &= ~ptcb->osTCBBitX) == 0)
            { 
            	/* ... remove task from */
                pevent->osEventGrp &= ~ptcb->osTCBBitY; /* ... event ctrl block */
            }
        }
        
        ptcb->osTCBDly  = 0;                                    /* Prevent OSTimeTick() from updating  */
        ptcb->osTCBStat = EMOS_STAT_RDY;                          /* Prevent task from being resumed     */
        gEmosLockNesting++;
        EMOS_EXIT_CRITICAL();                                     /* Enabling INT. ignores next instruc. */
        emosDummy();                                              /* ... Dummy ensures that INTs will be */
        EMOS_ENTER_CRITICAL();                                    /* ... disabled HERE!                  */
        gEmosLockNesting--;
        emosTaskDelHook(ptcb);                                    /* Call user defined hook              */
        gEmosTaskCtr--;                                            /* One less task being managed         */

        gEmosTCBPrioTbl[prio] = (EMOS_TCB_T *)0;                       /* Clear old priority entry            */
        if (ptcb->osTCBPrev == (EMOS_TCB_T *)0)
        { 
        	/* Remove from TCB chain*/
            ptcb->osTCBNext->osTCBPrev = (EMOS_TCB_T *)0;
            gEmosTCBList  = ptcb->osTCBNext;
        } 
        else 
        {
            ptcb->osTCBPrev->osTCBNext = ptcb->osTCBNext;
            ptcb->osTCBNext->osTCBPrev = ptcb->osTCBPrev;
        }
        
        ptcb->osTCBNext = gEmosTCBFreeList; /* Return TCB to free TCB list         */
        gEmosTCBFreeList   = ptcb;
        EMOS_EXIT_CRITICAL();
        emosSched();           /* Find new highest priority task*/
        return (EMOS_NO_ERR);
    } 

    /*deleteing task does not exist*/
    else 
    {
        EMOS_EXIT_CRITICAL();
        return (EMOS_TASK_DEL_ERR);
    }
}
#endif

/**********************************************************************************************************
* REQUEST THAT A TASK DELETE ITSELF
* Description: This function is used to:
*                   a) notify a task to delete itself.
*                   b) to see if a task requested that the current task delete itself.
*              This function is a little tricky to understand.  Basically, you have a task that needs
*              to be deleted however, this task has resources that it has allocated (memory buffers,
*              semaphores, mailboxes, queues etc.).  The task cannot be deleted otherwise these
*              resources would not be freed.  The requesting task calls OSTaskDelReq() to indicate that
*              the task needs to be deleted.  Deleting of the task is however, deferred to the task to
*              be deleted.  For example, suppose that task #10 needs to be deleted.  The requesting task
*              example, task #5, would call OSTaskDelReq(10).  When task #10 gets to execute, it calls
*              this function by specifying EMOS_PRIO_SELF and monitors the returned value.  If the return
*              value is EMOS_TASK_DEL_REQ, another task requested a task delete.  Task #10 would look like
*              this:
*
*                   void Task(void *data)
*                   {
*                       .
*                       .
*                       while (1) {
*                           OSTimeDly(1);
*                           if (OSTaskDelReq(EMOS_PRIO_SELF) == EMOS_TASK_DEL_REQ) {
*                               Release any owned resources;
*                               De-allocate any dynamic memory;
*                               OSTaskDel(EMOS_PRIO_SELF);
*                           }
*                       }
*                   }
* Arguments  : prio    is the priority of the task to request the delete from
* Returns    : EMOS_NO_ERR          if the task exist and the request has been registered
*              EMOS_TASK_NOT_EXIST  if the task has been deleted.  This allows the caller to know whether
*                                 the request has been executed.
*              EMOS_TASK_DEL_IDLE   if you requested to delete uC/OS-II's idle task
*              EMOS_PRIO_INVALID    if the priority you specify is higher that the maximum allowed 
*                                 (i.e. >= EMOS_LOWEST_PRIO) or, you have not specified EMOS_PRIO_SELF.
*              EMOS_TASK_DEL_REQ    if a task (possibly another task) requested that the running task be 
*                                 deleted.
**********************************************************************************************************/
#if EMOS_TASK_DEL_EN
uint8 emosTaskDelReq (uint8 prio)
{
    bool     stat;
    uint8    err;
    EMOS_TCB_T* ptcb = NULL;


    if (prio == EMOS_IDLE_PRIO) 
    {  
    	/* Not allowed to delete idle task*/
        return (EMOS_TASK_DEL_IDLE);
    }
    
    if (prio >= EMOS_LOWEST_PRIO && prio != EMOS_PRIO_SELF) 
    {  
    	/* Task priority valid ? */
        return (EMOS_PRIO_INVALID);
    }
    
    if (prio == EMOS_PRIO_SELF) 
    { 
    	/* See if a task is requesting to ...  */
        EMOS_ENTER_CRITICAL(); /* ... this task to delete itself */
        stat = gEmosTCBCur->osTCBDelReq;  /* Return request status to caller*/
        EMOS_EXIT_CRITICAL();
        return (stat);
    } 
    else 
    {
        EMOS_ENTER_CRITICAL();
        if ((ptcb = gEmosTCBPrioTbl[prio]) != (EMOS_TCB_T *)0) 

⌨️ 快捷键说明

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