文章目录
一、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;

最低0.47元/天 解锁文章
1220

被折叠的 条评论
为什么被折叠?



