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

📄 os_task.c

📁 ucos在三星s3c4419B上的移植
💻 C
📖 第 1 页 / 共 3 页
字号:
                        OS_STK  *pbos,
                        INT32U   stk_size,
                        void    *pext,
                        INT16U   opt)
{
#if OS_CRITICAL_METHOD == 3                  /* 为CPU状态寄存器分配存储变量               */
    OS_CPU_SR  cpu_sr;
#endif
    OS_STK    *psp;
    INT8U      err;


#if OS_ARG_CHK_EN > 0
    if (prio > OS_LOWEST_PRIO) 
    {                                           /* 确认优先级在许可范围之内           */
        return (OS_PRIO_INVALID);
    }
#endif
    OS_ENTER_CRITICAL();
    if (OSTCBPrioTbl[prio] == (OS_TCB *)0) 
    {                                                 /* 确认优先级未被其他任务占用  */
        OSTCBPrioTbl[prio] = (OS_TCB *)1;    /* 保留该优先级避免其他处理 ...  */
                                             /* ... 直到任务建立.              */
        OS_EXIT_CRITICAL();

        if (((opt & OS_TASK_OPT_STK_CHK) != 0x0000) ||   /* 如果使能堆栈检验     */
            ((opt & OS_TASK_OPT_STK_CLR) != 0x0000)) 
            {                                            /* 如果堆栈需要清零           */
            #if OS_STK_GROWTH == 1
            (void)memset(pbos, 0, stk_size * sizeof(OS_STK));
            #else
            (void)memset(ptos, 0, stk_size * sizeof(OS_STK));
            #endif
            }

        psp = (OS_STK *)OSTaskStkInit(task, pdata, ptos, opt); /* 初始化任务堆栈          */
        err = OS_TCBInit(prio, psp, pbos, id, stk_size, pext, opt);
        if (err == OS_NO_ERR) 
        {
            OS_ENTER_CRITICAL();
            OSTaskCtr++;                                       /* 增加任务计数器        */
            OS_EXIT_CRITICAL();
            if (OSRunning == TRUE) 
            {                           /* 如果多任务启动寻找最高优先级任务 */
                OS_Sched();
            }
        } 
        else 
        {
            OS_ENTER_CRITICAL();
            OSTCBPrioTbl[prio] = (OS_TCB *)0;                  /*  放弃该优先级   */
            OS_EXIT_CRITICAL();
        }
        return (err);
    }
    OS_EXIT_CRITICAL();
    return (OS_PRIO_EXIST);
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
*                                            删除任务
*
* 函数描述: 该函数为删除任务。调用的任务通过设定自身的优先级别可以删除自身。被删除的任务返回到睡眠状态,并
*           通过再次创建删除掉的任务来重新激活。
*
* 输入参数: prio   待删除任务的优先级。注意,如果不知当前任务的优先级可通过设定为OS_PRIO_SELF来删除当前任务。
*                   
*      
* 返回值    : OS_NO_ERR           调用成功
*             OS_TASK_DEL_IDLE    想删除 uC/OS-II 的空闲任务
*             OS_PRIO_INVALID     指定的优先级高于允许的最大值
*                                 (例如. >= OS_LOWEST_PRIO)或没有指定 OS_PRIO_SELF.
*             OS_TASK_DEL_ERR     想删除的任务不存在
*             OS_TASK_DEL_ISR     想从中断服务程序中删除任务
*
* 注释      : 1)为减少中断隐患, OSTaskDel() 将关闭该任务:
*                    a) 通过脱离就绪
*                    b) 通过从等待列表中移除
*                    c) 通过避免 OSTimeTick() 使任务就绪待运行。
*                 该任务能从 uC/OS-II 中的杂项结构中脱离。
*              2) OS_EXIT_CRITICAL() 后调用 OS_Dummy()的意义是因为在大多数处理器中,紧跟开中断指令的下
*                 一条指令常被忽略。
*              3) 中断服务程序不能删除任务
*              4) 如果当前任务正在被删除,由于它已从就绪列表中移出,所以,它将不能被调度,上锁嵌套计数器增加
*                 增加嵌套计数器是避免其他任务被调度。也就是一个中断服务程序将返回到当前正被删除的任务。
*                 删除剩余部分将完成。
*********************************************************************************************************
*/
/*$PAGE*/
#if OS_TASK_DEL_EN > 0
INT8U  OSTaskDel (INT8U prio)
{
#if OS_CRITICAL_METHOD == 3                      /* 为CPU状态寄存器分配存储变量           */
    OS_CPU_SR     cpu_sr;
#endif

#if OS_EVENT_EN > 0
    OS_EVENT     *pevent;
#endif    
#if (OS_VERSION >= 251) && (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0)
    OS_FLAG_NODE *pnode;
#endif
    OS_TCB       *ptcb;
    BOOLEAN       self;


	self = self;                                            // 预防编译警告
    if (OSIntNesting > 0)
     {                                                      /* 确保不是在ISR中删除一个程序   */
        return (OS_TASK_DEL_ISR);
     }
#if OS_ARG_CHK_EN > 0
    if (prio == OS_IDLE_PRIO) 
    {                                                                       /* 不允许删除空闲任务    */
        return (OS_TASK_DEL_IDLE);
    }
    if (prio >= OS_LOWEST_PRIO && prio != OS_PRIO_SELF) 
    {                                                            /* 任务优先级是否有效?              */
        return (OS_PRIO_INVALID);
    }
#endif
    OS_ENTER_CRITICAL();
    if (prio == OS_PRIO_SELF) 
    {                                                                         /* 是否请求删除自身?   */
        prio = OSTCBCur->OSTCBPrio;                                     /* 设定删除当前任务的优先级   */
    }
    ptcb = OSTCBPrioTbl[prio];
    
    if (ptcb != (OS_TCB *)0)                                         /* 要删除的任务是否存在?      */
    {                                       
        if ((OSRdyTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX) == 0x00) 
        {                                                            /* 使任务脱离就绪            */
            OSRdyGrp &= ~ptcb->OSTCBBitY;
        }
#if OS_EVENT_EN > 0
        pevent = ptcb->OSTCBEventPtr;                                /* 任务是否正在等待事件?        */
        if (pevent != (OS_EVENT *)0) 
        {                                                           
            if ((pevent->OSEventTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX) == 0)
            {                                                                    /* ... 移除任务 */
                pevent->OSEventGrp &= ~ptcb->OSTCBBitY;                        /* ... 从事件控制块 */
            }
        }
#endif
#if (OS_VERSION >= 251) && (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0)
        pnode = ptcb->OSTCBFlagNode;
        if (pnode != (OS_FLAG_NODE *)0) 
        {                                                         /* 任务是否在等事件标志?    */
            OS_FlagUnlink(pnode);                               /* 从等待列表中移除               */
        }
#endif
        ptcb->OSTCBDly  = 0;                                    /* 避免 OSTimeTick() 更新  */
        ptcb->OSTCBStat = OS_STAT_RDY;                          /* 防止任务重新开始     */
		if (OSLockNesting < 255) 
		{
            OSLockNesting++;
		}
        OS_EXIT_CRITICAL();                                     /* 打开中断忽略下一指令 */
        OS_Dummy();                                             /* ... 哑函数确保中断关闭 */
        OS_ENTER_CRITICAL();                                    /* ... 此处关闭中断                  */
		if (OSLockNesting > 0) 
		{
            OSLockNesting--;
		}
        OSTaskDelHook(ptcb);                                    /* 调用户定义的钩子函数              */
        OSTaskCtr--;                                            /* 任务数减一         */
        OSTCBPrioTbl[prio] = (OS_TCB *)0;                       /* 旧优先级任务清零            */
        if (ptcb->OSTCBPrev == (OS_TCB *)0) 
        {                                                        /* 从任务控制块链上移除               */
            ptcb->OSTCBNext->OSTCBPrev = (OS_TCB *)0;
            OSTCBList                  = ptcb->OSTCBNext;
        } 
        else 
        {
            ptcb->OSTCBPrev->OSTCBNext = ptcb->OSTCBNext;
            ptcb->OSTCBNext->OSTCBPrev = ptcb->OSTCBPrev;
        }
        ptcb->OSTCBNext = OSTCBFreeList;                        /* 把任务控制块返回到空余任务控制块         */
        OSTCBFreeList   = ptcb;
        OS_EXIT_CRITICAL();
        OS_Sched();                                             /* 寻找新的最高优先级任务      */
        return (OS_NO_ERR);
    }
    OS_EXIT_CRITICAL();
    return (OS_TASK_DEL_ERR);
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
*                                    请求删除自身
*
* 函数描述: 该函数用于:
*                   a) 通知任务删除自身
*                   b) 其他任务请求当前任务删除自身
*              首先,试图删除一个任务,但是该任务却占用着一些内存缓冲区、信号量、邮箱、队列等资源。
*              因为一些资源还未释放,任务不该被删。正在请求的任务调用 OSTaskDelReq() 来显示需要删除的任务。
*              例如,10号任务需被删除。请求删除的任务例如,5号,将调用 OSTaskDelReq(10)。当10号任务执行时,
*              它将调用 OSTaskDelReq(OS_PRIO_SELF),并检测函数的返回值。如果返回值是OS_TASK_DEL_REQ,则5号请
*              求删除10号任务。10号任务将如下:
*
*                   void Task(void *data)
*                   {
*                       .
*                       .
*                       while (1)
*                       {
*                           OSTimeDly(1);
*                           if (OSTaskDelReq(OS_PRIO_SELF) == OS_TASK_DEL_REQ) 
*                           {
*                               Release any owned resources;
*                               De-allocate any dynamic memory;
*                               OSTaskDel(OS_PRIO_SELF);
*                           }
*                       }
*                   }
*
* 输入参数  : prio    被删除的任务的优先级
*
* Returns    : OS_NO_ERR          如果任务存在,请求许可注册
*              OS_TASK_NOT_EXIST  是否任务已被删除。允许调用函数知道请求是否执行。
*              OS_TASK_DEL_IDLE   请求删除的任务是否是 uC/OS-II的空闲任务
*              OS_PRIO_INVALID    指定的优先级是否高于允许的最大值。
*                                 (例如 >= OS_LOWEST_PRIO) 或没有指定为 OS_PRIO_SELF.
*              OS_TASK_DEL_REQ    一个任务(可能是其他任务) 是否请求删除正在运行的任务
*********************************************************************************************************
*/
/*$PAGE*/
#if OS_TASK_DEL_EN > 0
INT8U  OSTaskDelReq (INT8U prio)
{
#if OS_CRITICAL_METHOD == 3                      /* 为CPU状态寄存器分配存储变量           */
    OS_CPU_SR  cpu_sr;
#endif
    BOOLEAN    stat;
    INT8U      err;
    OS_TCB    *ptcb;


#if OS_ARG_CHK_EN > 0
    if (prio == OS_IDLE_PRIO) 
    {                                                                    /* 不允许删除空闲任务     */
        return (OS_TASK_DEL_IDLE);
    }
    if (prio >= OS_LOWEST_PRIO && prio != OS_PRIO_SELF) 
    {                                                                 /* 任务优先级是否有效 ?               */
        return (OS_PRIO_INVALID);
    }
#endif
    if (prio == OS_PRIO_SELF) 
    {                                                             /* 是否一个任务正在请求 ...  */
        OS_ENTER_CRITICAL();                                    /* ... 这个任务要删除自身      */
        stat = OSTCBCur->OSTCBDelReq;                           /* 返回给调用函数的请求状态     */
        OS_EXIT_CRITICAL();
        return (stat);
    }
    OS_ENTER_CRITICAL();
    ptcb = OSTCBPrioTbl[prio];
    if (ptcb != (OS_TCB *)0) 
    {                                                            /* 要删除的任务必须存在           */
        ptcb->OSTCBDelReq = OS_TASK_DEL_REQ;                    /* 设定标志显示任务被删除 */
        err               = OS_NO_ERR;

⌨️ 快捷键说明

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