ucos任务调度理解

一、ucos任务

1.1 ucos任务简介

  • 一个任务通常是一个无限的循环。
    一个任务就像是一个C函数,它可以带有形参,但是其绝不会有返回值。故返回类型为void。如下
void YourTask (void *pdata) 
{
   
    
	 for (;;) {
   
    
		 /* 用户代码 */ 
		 调用uC/OS-II的某种系统服务: 
		 OSMboxPend(); 
		 OSQPend(); 
		 OSSemPend(); 
		 OSTaskDel(OS_PRIO_SELF); 
		 OSTaskSuspend(OS_PRIO_SELF); 
		 OSTimeDly(); 
		 OSTimeDlyHMSM(); 
		 /* 用户代码 */ 
 	} 
}
  • 不同的是,当任务完成以后,任务可以自我删除。
    注意任务代码并非真的删除了,μC/OS-Ⅱ只是简单地不再理会这个任务了,这个任务的代码也不会再运行,
    如果任务调用了 OSTaskDel(),这个任务绝不会返回什么。
void YourTask (void *pdata) 
 {
   
    
 /* 用户代码 */ 
 OSTaskDel(OS_PRIO_SELF); 
 }
  • μC/OS-Ⅱ可以管理多达 64 个任务,用户可以操作的最多只有 56 个应用任务
    μC/OS-Ⅱ可以管理多达 64 个任务,但作者保留了优先级为 0、 1、 2、 3、 OS_LOWEST_PRIO-3、 OS_LOWEST_PRI0-2,OS_LOWEST_PRI0-1 以及 OS_LOWEST_PRI0 这 8 个任务以被将来使用。所有我们用户还可以自定义剩下的56个任务。
  • μC/OS-Ⅱ任务优先级,任务的优先级号就是任务编号(ID)。
    必须给每个任务赋以不同的优先级,优先级可以从 0 到OS_LOWEST_PR10-2。
    优先级号越低,任务的优先级越高。μC/OS-Ⅱ总是运行进入就绪态的优先级最高的任务。

1.2 任务状态

从用户的观点来看,任务可以是有 5 种状态,休眠状态,就绪状态,运行状态,挂起状态,中断状态 。
在任一给定的时刻,任务的状态一定是在这五种状态之一。如下图:
在这里插入图片描述

  • 睡眠态(DORMANT)
    指任务驻留在程序空间之中,还没有交给μC/OS-Ⅱ管理。
    一个任务可以通过调用 OSTaskDel()返回到睡眠态,或通过调用该函数让另一个任务进入睡眠态。
  • 就绪态
    当任务一旦建立,这个任务就进入就绪态准备运行。
    任务的建立可以是在多任务运行开始之前,也可以是动态地被一个运行着的任务建立。
    如果一个任务是被另一个任务建立的,而这个任务的优先级高于建立它的那个任务,则这个刚刚建立的任务将立即得到 CPU 的控制权。
  • 运行态
    调用 OSStart()可以启动多任务。OSStart()函数运行进入就绪态的优先级最高的任务。该任务进入了运行态。
    就绪的任务只有当所有优先级高于这个任务的任务转为等待状态,或者是被删除了,才能进入运行态。
  • 等待/挂起
    ■ 正在运行的任务需要自身延迟时,进入等待态
      调用以下两个函数:OSTimeDly()、 OSTimeDlyHMSM() 之一将自身延迟一段时间。这个任务于是进入等待状态,等待这段时间过去,下一个优先级最高的、并进入了就绪态的任务立刻被赋予了 CPU 的控制权。等待的时间过去以后,系统服务函数 OSTimeTick()使延迟了的任务进入就绪态。
    ■ 正在运行的任务期待某一事件的发生时需要等待时,进入挂起态
      调用以下 3 个函数之一:OSSemPend(),OSMboxPend(),或 OSQPend(),任务就进入挂起状态(WAITING)。当任务因等待事件被挂起(Pend),下一个优先级最高的任务立即得到了 CPU 的控制权。当事
    件发生了,被挂起的任务进入就绪态。
  • 中断服务态
    正在运行的任务是可以被中断的,响应中断时,正在执行的任务被挂起,中断服务子程序控制了 CPU 的使用权。中断服务子程序可能会报告一个或多个事件的发生,而使一个或多个任务进入就绪态。在这种情况下,从中断服务子程序返回之前,μC/OS-Ⅱ要判定,被中断的任务是否还是就绪态任务中优先级最高的。如果中断服务子程序使一个优先级更高的任务进入了就绪态,则新进入就绪态的这个优先级更高的任务将得以运行,否则原来被中断了的任务才能继续运行。

1.3 任务控制块

任务控制块是被 uC/OS-III 用于维护任务的一个结构体。 每个任务都必须有自的己 TCB 。TCB 中的一些变量可以根据具体应用进行裁剪。

typedef struct os_tcb {
   
    
	OS_STK *OSTCBStkPtr; //OSTCBStkPtr 是指向当前任务栈顶的指针。
#if OS_TASK_CREATE_EXT_EN 
	void *OSTCBExtPtr; //OSTCBExtPtr 指向用户定义的任务控制块扩展。
	OS_STK *OSTCBStkBottom; //OSTCBStkBottom 是指向任务栈底的指针
	INT32U OSTCBStkSize; //OSTCBStkSize 存有栈中可容纳的指针元数目而不是用字节(Byte)表示的栈容量总数。
	INT16U OSTCBOpt; //选择项
	INT16U OSTCBId; //OSTCBId 用于存储任务的识别码。
#endif 
	//OSTCBNext,OSTCBPrev 用于任务控制块OS_TCBs的双重链接,双重连接的链表使得任一成员都能被快速插入或删除。
	struct os_tcb *OSTCBNext; 
	struct os_tcb *OSTCBPrev; 
#if (OS_Q_EN && (OS_MAX_QS >= 2)) || OS_MBOX_EN || OS_SEM_EN 
	OS_EVENT *OSTCBEventPtr; //OSTCBEventPtr 是指向事件控制块的指针
#endif 
#if (OS_Q_EN && (OS_MAX_QS >= 2)) || OS_MBOX_EN 
	void *OSTCBMsg; //OSTCBMsg 是指向传给任务的消息的指针。
#endif
	INT16U OSTCBDly; //这个变量保存的是任务允许等待事件发生的最多时钟节拍数。如果这个变量为 0,表示任务不延时
	INT8U OSTCBStat; //OSTCBStat 是任务的状态字。当.OSTCBStat 为 0,任务进入就绪态。
	INT8U OSTCBPrio; //OSTCBPrio 是任务优先级。高优先级任务的.OSTCBPrio 值小。
	
	//.OSTCBX, .OSTCBY, .OSTCBBitX 和 .OSTCBBitY 用于加速任务进入就绪态的过程或进入等待事件发生状态的过程
	INT8U OSTCBX; 
	INT8U OSTCBY; 
	INT8U OSTCBBitX; 
	INT8U OSTCBBitY; 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值