μC/OS-Ⅱ源码学习(2)---多任务系统的实现(下)

快速回顾

        在之前的文章中讲解了μC/OSⅡ的多任务模型以及初始化的源码:

μC/OS-Ⅱ中的多任务

μC/OS-Ⅱ源码学习(1)---多任务系统的实现

        本文继续探究任务生命周期的其它函数源码。

任务的挂起

        任务挂起是一个动作,通过主动使用函数OSTaskSuspend(prio)可以使对应优先级的任务处于挂起状态,暂时无法被调度器调度:

//os_task.c
INT8U  OSTaskSuspend (INT8U prio)
{
    BOOLEAN    self;
    OS_TCB    *ptcb;
    INT8U      y;
#if OS_CRITICAL_METHOD == 3u      /* 初始化临界区变量 */
    OS_CPU_SR  cpu_sr = 0u;
#endif



#if OS_ARG_CHK_EN > 0u
    if (prio == OS_TASK_IDLE_PRIO) {      /* 不允许挂起空闲任务 */
        return (OS_ERR_TASK_SUSPEND_IDLE);
    }
    if (prio >= OS_LOWEST_PRIO) {      /* 要挂起的优先级不允许超出设定的最低优先级 */
        if (prio != OS_PRIO_SELF) {
            return (OS_ERR_PRIO_INVALID);
        }
    }
#endif
    OS_ENTER_CRITICAL();           //进入临界区,关闭其它中断,只保留NMI和Hardfault中断
    if (prio == OS_PRIO_SELF) {         /* 检查是否要挂起自己 */
        prio = OSTCBCur->OSTCBPrio;
        self = OS_TRUE;
    } else if (prio == OSTCBCur->OSTCBPrio) {      /* 是否等于当前运行任务的优先级,和上面的判断是一样的 */
        self = OS_TRUE;
    } else {
        self = OS_FALSE;      /* self为TRUE表示要挂起自己,否则为挂起其它任务 */
    }
    ptcb = OSTCBPrioTbl[prio];
    if (ptcb == (OS_TCB *)0) {        /* 任务不能是空,必须存在 */
        OS_EXIT_CRITICAL();
        return (OS_ERR_TASK_SUSPEND_PRIO);
    }
    if (ptcb == OS_TCB_RESERVED) {       /* 任务控制块不能是OS_TCB_RESERVED状态 */
        OS_EXIT_CRITICAL();
        return (OS_ERR_TASK_NOT_EXIST);
    }
    y            = ptcb->OSTCBY;        //获取要挂起任务的优先级组下标
    OSRdyTbl[y] &= (OS_PRIO)~ptcb->OSTCBBitX;       /* 将任务的组内优先级就绪状态清空 */
    if (OSRdyTbl[y] == 0u) {      //如果挂起该任务后,整个组内没有就绪任务,则将该组的就绪状态清空
        OSRdyGrp &= (OS_PRIO)~ptcb->OSTCBBitY;
    }
    ptcb->OSTCBStat |= OS_STAT_SUSPEND;      /* 将任务状态切换为挂起状态 */
    OS_EXIT_CRITICAL();
    if (self == OS_TRUE) {       /* 如果要挂起的任务就是自身,则进行上下文切换(停止运行当前任务) */
        OS_Sched();       /* 切换任务 */
    }
    return (OS_ERR_NONE);
}

       可以看到,挂起任务并不会将任务控制块丢弃或清空,只是将任务状态转换为SUSPEND而已,在这之后,任务将不会永远不会被加入到就绪队列中(除非被恢复)。

        这里面有一些宏定义要额外提一下:

  • 任务的状态,注意这些状态是可以按位进行组合的,即一个任务可能同时存在多种状态。
//ucos_ii.h
#define  OS_STAT_RDY           0x00u  /* 就绪 */
#define  OS_STAT_SEM           0x01u  /* 等待信号量 */
#define  OS_STAT_MBOX          0x02u  /* 等待邮箱 */
#define  OS_STAT_Q             0x04u  /* 等待消息队列 */
#define  OS_STAT_SUSPEND       0x08u  /* 已被悬起 */
#define  OS_STAT_MUTEX         0x10u  /* 等待互斥锁 */
#define  OS_STAT_FLAG          0x20u  /* 等待事件标志组 */
#define  OS_STA
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值