uCOS-Ⅲ学习笔记: 任务挂起&恢复

举报
JeckXu666 发表于 2022/01/17 23:20:03 2022/01/17
【摘要】 任务挂起&恢复 一、简介二、设置挂起恢复有关函数以及变量挂起恢复有关变量(TCB中)编写调度函数任务挂起函数任务挂起恢复函数 三、调用流程 一、简介 任务的挂起:即将任...

一、简介

任务的挂起:即将任务从就绪列表中暂时移除,不再参与运行,恢复即把任务从新插入到就绪列表,继续运行

二、设置挂起恢复有关函数以及变量

挂起恢复有关变量(TCB中)

  • 任务TCB添加有关变量储存任务状态以及记录任务挂起的次数(挂起多少次就要恢复多少次才能继续插入就绪列表)
  • OS_STATE TaskState(记入任务状态)
  • OS_STATE u8类型重定义类型
  • SuspendCtr(挂起次数计数器)

编写调度函数

任务挂起函数

	OSTaskSuspend
	(
	    OS_TCB *tcb 
	    OS_ERR *err
	)//(任务挂起函数格式,以及其传递进去函数形式)

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  1. 创建临界段调用参数
CPU_SR_ALLOC();
//展开(头文件中的定义)
/* 定义一个局部变量,用于保存CPU中断状态 */
#define  CPU_SR_ALLOC()             CPU_SR  cpu_sr = (CPU_SR)0
#else
#define  CPU_SR_ALLOC()
#endif

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  1. 是否开启屏蔽
  • 根据宏定义判断一些任务的可执行性
  • ISR程序中不可调用挂起,否则报错
  • 中断处理函数不能挂起,否则报错
  • 空闲任务不能挂起,否则报错
#if 0 /* 屏蔽开始 */
#ifdef OS_SAFETY_CRITICAL
/* 安全检查,OS_SAFETY_CRITICAL_EXCEPTION()函数需要用户自行编写 */
    if (p_err == (OS_ERR *)0) {
        OS_SAFETY_CRITICAL_EXCEPTION();
        return;
    }
#endif

#if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u
/* 不能在ISR程序中调用该函数 */
    if (OSIntNestingCtr > (OS_NESTING_CTR)0) {             
       *p_err = OS_ERR_TASK_SUSPEND_ISR;
        return;
    }
#endif

/* 不能挂起空闲任务 */
    if (p_tcb == &OSIdleTaskTCB) {                         
        *p_err = OS_ERR_TASK_SUSPEND_IDLE;
        return;
    }

#if OS_CFG_ISR_POST_DEFERRED_EN > 0u
/* 不能挂起中断处理任务 */
    if (p_tcb == &OSIntQTaskTCB) {                          
        *p_err = OS_ERR_TASK_SUSPEND_INT_HANDLER;
        return;
    }
#endif

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  1. 进入临界段
CPU_CRITICAL_ENTER();

  
 
  • 1
  1. 判断传入TCB==0?
  • 若等于0,则令TCB=OSTCBCurPtr
  • 不为0,判断若为OSTCBCurPtr ,则根据一个调度器宏定义变量判断,若调度器锁住,退出临界段,并报错
	/* 是否挂起自己 */
    if (p_tcb == (OS_TCB *)0) 
	{                             
        p_tcb = OSTCBCurPtr;
    }
    if (p_tcb == OSTCBCurPtr) 
	{
        /* 如果调度器锁住则不能挂起自己 */
		if (OSSchedLockNestingCtr > (OS_NESTING_CTR)0) 
		{
            CPU_CRITICAL_EXIT();
            *p_err = OS_ERR_SCHED_LOCKED;
            return;
        }
  }
    *p_err = OS_ERR_NONE;

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  1. 判断传入TCB的状态 switch判断
  • 非挂起状态进行挂起操作(状态切换为当前状态+挂起),挂起数目1,退出临界段和判断
  • 已经挂起的任务执行default,挂起数目+1,退出临界段和判断
/* 根据任务的状态来决定挂起的动作 */
    switch (p_tcb->TaskState) 
	{
        case OS_TASK_STATE_RDY:
             OS_CRITICAL_ENTER_CPU_CRITICAL_EXIT();
             p_tcb->TaskState  =  OS_TASK_STATE_SUSPENDED;
             p_tcb->SuspendCtr = (OS_NESTING_CTR)1;
             OS_RdyListRemove(p_tcb);
             OS_CRITICAL_EXIT_NO_SCHED();
             break;

        case OS_TASK_STATE_DLY:
             p_tcb->TaskState  = OS_TASK_STATE_DLY_SUSPENDED;
             p_tcb->SuspendCtr = (OS_NESTING_CTR)1;
             CPU_CRITICAL_EXIT();
             break;

        case OS_TASK_STATE_PEND:
             p_tcb->TaskState  = OS_TASK_STATE_PEND_SUSPENDED;
             p_tcb->SuspendCtr = (OS_NESTING_CTR)1;
             CPU_CRITICAL_EXIT();
             break;

        case OS_TASK_STATE_PEND_TIMEOUT:
             p_tcb->TaskState  = OS_TASK_STATE_PEND_TIMEOUT_SUSPENDED;
             p_tcb->SuspendCtr = (OS_NESTING_CTR)1;
             CPU_CRITICAL_EXIT();
             break;

        case OS_TASK_STATE_SUSPENDED:
        case OS_TASK_STATE_DLY_SUSPENDED:
        case OS_TASK_STATE_PEND_SUSPENDED:
        case OS_TASK_STATE_PEND_TIMEOUT_SUSPENDED:
             p_tcb->SuspendCtr++;
             CPU_CRITICAL_EXIT();
             break;

        default:
             CPU_CRITICAL_EXIT();
             *p_err = OS_ERR_STATE_INVALID;
             return;
    }

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  1. 任务切换(任务状态改变后都要进行任务切换)
    /* 任务切换 */
	OSSched();

  
 
  • 1
  • 2

任务挂起恢复函数

	OSTaskResume
	{
	   OS_TCB *p_tcb
	   OS_TCB *p_err
	}
	//(任务恢复函数,用于恢复被挂起的任务,无法恢复自己,函数形式如上)

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  1. 创建临界段调用参数
    (同挂起函数)
  2. 是否开启屏蔽
    - 根据宏定义判断一些任务的可执行性
    - ISR程序中不可调用挂起,否则报错
    - 不能挂起当前任务自己
    (同上,因为没有空闲任务挂起,所以少一个)
  3. 判断任务状态,执行对应的恢复动作(switch判断)任务挂起数目递减;同时判断若挂起数量等于0,则将任务恢复到挂起之前状态(就绪、延迟、等待、等待+超时),再退出临界段
	/* 根据任务的状态来决定恢复的动作 */
    switch (p_tcb->TaskState) 
	{
        case OS_TASK_STATE_RDY:
        case OS_TASK_STATE_DLY:
        case OS_TASK_STATE_PEND:
        case OS_TASK_STATE_PEND_TIMEOUT:
             CPU_CRITICAL_EXIT();
             *p_err = OS_ERR_TASK_NOT_SUSPENDED;
             break;

        case OS_TASK_STATE_SUSPENDED:
             OS_CRITICAL_ENTER_CPU_CRITICAL_EXIT();
             p_tcb->SuspendCtr--;
             if (p_tcb->SuspendCtr == (OS_NESTING_CTR)0) {
                 p_tcb->TaskState = OS_TASK_STATE_RDY;
                 OS_TaskRdy(p_tcb);
             }
             OS_CRITICAL_EXIT_NO_SCHED();
             break;

        case OS_TASK_STATE_DLY_SUSPENDED:
             p_tcb->SuspendCtr--;
             if (p_tcb->SuspendCtr == (OS_NESTING_CTR)0) {
                 p_tcb->TaskState = OS_TASK_STATE_DLY;
             }
             CPU_CRITICAL_EXIT();
             break;

        case OS_TASK_STATE_PEND_SUSPENDED:
             p_tcb->SuspendCtr--;
             if (p_tcb->SuspendCtr == (OS_NESTING_CTR)0) {
                 p_tcb->TaskState = OS_TASK_STATE_PEND;
             }
             CPU_CRITICAL_EXIT();
             break;

        case OS_TASK_STATE_PEND_TIMEOUT_SUSPENDED:
             p_tcb->SuspendCtr--;
             if (p_tcb->SuspendCtr == (OS_NESTING_CTR)0) {
                 p_tcb->TaskState = OS_TASK_STATE_PEND_TIMEOUT;
             }
             CPU_CRITICAL_EXIT();
             break;

        default:
             CPU_CRITICAL_EXIT();
             *p_err = OS_ERR_STATE_INVALID;
             return;
    }

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  1. 任务切换

三、调用流程

  1. 初始化
    - 任务TCB、创建变量;
*/
struct os_tcb
{
//任务状态标志
OS_STATE             TaskState;
#if OS_CFG_TASK_SUSPEND_EN > 0u
/* 任务挂起函数OSTaskSuspend()计数器 */
    OS_NESTING_CTR       SuspendCtr;
#endif

};

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  1. 调用
    - 在任务中直接根据需求使用
//挂起
	OSTaskSuspend(&Task1TCB,&err);	
//恢复
	OSTaskResume(&Task1TCB,&err);

  
 
  • 1
  • 2
  • 3
  • 4

文章来源: blog.csdn.net,作者:JeckXu666,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/qq_45396672/article/details/109960631

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。