UCOS学习笔记——任务1

一. 任务的基本概念

从应用程序的角度来看,UCOS中的任务就是一个线程,就是一个用来解决用户问题的C语言函数和与之相关的数据结构而构成的实体。

从任务的存储结构来看,UCOS的任务有三个组成部分:任务程序代码,任务堆栈,任务控制块。

ucos的任务分为两种:系统任务,用户任务。

UCos将每一个任务作为一个节点并连接成一个链表。ucos最多可管理64个任务。


1.任务的状态

睡眠状态:任务只是以代码的形式驻留在存储空间(RAM或ROM),并没有交给操作系统管理。

就绪状态:系统为任务配备了任务控制块且在任务登记表中登记过。

运行状态:任务经调度器判断获得了使用权

等待状态:正在运行的任务需要等待一段时间或者等待某个事件的发生,cpu将使用权交给另一个任务

中断服务状态:一个正在运行的任务响应中断去执行中断服务程序


2.用户任务代码的结构

用户任务代码结构:类似与一个C语言函数,但又区别于C语言函数,它是一个任务,因为该函数不能被main函数调用,只能被操作系统调用。

void MyTask()
{
for(;;)	
{
可以被中断的用户代码;
OS_ENTER_CRITICAL();//进入临界区(关中断)
临界区;
OS_EXIT_CRITICAL;//退出临界区(开中断)
可以被中断的用户代码;
}
}

应用程序代码结构:

void MyTask1();void MyTask2();void MyTask3();
void main()
{
.........
OS_Init();
.........
OS_TaskCreate(MyTask1,.........);
OS_TaskCreate(MyTask2,.........);
OS_TaskCreate(MyTask3,.........);
.........
OS_Start();
.........
}

3.系统任务

ucos为应用程序预定义了两个系统任务:空闲任务和统计任务。

空闲任务:OSTaskIdle()使cpu在没有任务运行时有事可做。

统计任务:系统任务OSTaskStat()每秒计算一次CPU在单位时间内被使用的时间,并将计算结果放在变量OSCPUUsage中,若应用程序需要使用该任务,需要将定义在OS_CFG.H中的系统配置常数OS_TASK_STAT_EN设置为1,并且必须在创建统计任务之前调用OSStartInit()对统计任务进行初始化。


4.任务的优先权和优先级别:

通过设置OS_CFG.H中的OS_LOWEST_PRIO来说明应用程序中任务优先级别的数目,0号任务优先级最高,OS_LOWEST_PRIO号任务分配给空闲任务,若有统计任务,将统计任务分配给OS_LOWEST_PRIO-1号。


二.任务堆栈


1.任务堆栈的创建:即创建一个数组

typedef unsigned int OS_STK //为了方便任务堆栈的定义而专门定义的数据类型,该类型长度为16位
#define TASK_STK_SIZE 512;//定义堆栈的长度(1024字节)
OS_STK TaskSTK[TASK_STK_SIZE];//定义一个数组作为任务堆栈

 

当调用OS_TaskCreate()来创建任务时,把数组的指针传递给函数中的堆栈栈顶参数ptos,就可以把该数组与任务关联起来而成为该任务的任务堆栈。

INT8U OSTaskCreate(//创建任务函数原型
void (* task)(void* pd);//指向任务指针
void *pdata;//传递给任务的参数
OS_STK *ptos;//任务堆栈指针
INT8U PRIO;)//中断优先级		

由于处理机不同,堆栈的增长方向可能不同,通过OS_CFG.H函数中的OS_STK_GROUTH作为选择开关来选择不同的增长方式

#define MyTaskStkN 64;
OS_STK TaskSTK[MyTaskStkN];

void main()
{
#if OS_STK_GROUTH ==1
OS_TaskCreate(MyTask,&MyTaskAgu,&MyTaskStk[0],20);
#else
OS_TaskCreate(MyTask,&MyTaskAgu,&MyTaskStk[MyTaskStkN-1],20);
#endif
}

2.任务堆栈的初始化

如何将CPU中各寄存器的值初始化放入堆栈中?这就需要使用OSTaskStkInit()函数

OS_STK OSTaskStkInit(
void *task(void *pdata);
void *pdata;
OS_STK *ptos;
INT16U opt;)

该函数的具体实现与处理器有关,实现该函数的细节将在后续的移植过程中介绍。


三. 任务控制块及任务控制块链表

UCOS中用来记录任务的堆栈指针,任务的当前状态,任务的优先级别等一些与任务管理有关的属性的表就叫做任务控制块(OS_TCB)


1.任务控制块的结构

任务控制块是一个结构类型的数据结构,当调用OSTaskCreate()函数创建一个任务时,这个函数就会对该数据结构的所有成员赋值,并驻留在内存中。

typedef struct os_tcb{
OS_Stk *OSTCBStkPtr;//指向任务堆栈栈顶的指针

#if OS_TASK_CREATE_EXT_EN
void  *OSTCBExtPtr;//指向任务控制块扩展的指针
OS_STK *OSTCBStkBottom;//指向任务堆栈栈底的指针
INT32U OSTCBStkSize;//任务堆栈的长度
INT16U OSTCBOpt;//创建任务时的选择项
INT16U OSTCBId;//目前该域未被使用
#endif

struct os_tcb *OSTCBNext;//指向后一个任务控制块的指针
struct os_tcb *OSTCBPrev;//指向前一个任务控制块的指针

#if(OS_Q_EN&&(OS_MAX_OS>=2))||OS_MBOX_EN||OS_Sem_EN
OS_EVENT *OSTCBEventPtr;//指向事件控制块的指针
#endif

#if(OS_Q_EN&&(OS_MAX_QS>=2))||OS_MBOX_EN
void *OSTCBMsg;//指向传递给任务消息的指针
#endif

INT16U OSTCBDly;//任务等待的时限
INT8U OSTCBStat;//任务的当前状态标志
INT8U OSTCBPrio;//任务的优先级别

INT8U OSTCBX;//用于快速访问就续表的数据
INT8U OSTCBY;//用于快速访问就续表的数据
INT8U OSTCBBitX;//用于快速访问就续表的数据
INT8U OSTCBBitY;//用于快速访问就续表的数据

#if OS_TASK_DEL_EN
BOOLEAN OSTCBDelReg;
#endif
}OS_TCB;
2.任务控制块链表

UCOS提供两个任务控制块链表:空任务控制块链表,任务控制块链表,调用OSInit()时建立空任务控制块链表,调用OSTaskCreate()时建立任务控制块链表。

调用OSInit()时,现在RAM中建立一个OS_TCB类型的数组OS_TCBtl[],每个数组元素就是一个任务控制块,然后将这些元素链接成一个链表,就构成了空任务控制块链表。

OS_CFG.H中的OS_MAX_TASKS的值指定了最大的用户任务数,UCOS_II.H中的OS_N_SYS_TASKS的值指定了最大的系统任务数。

每当系统创建一个任务时,系统就将空任务控制块链表表头指针OSTCBFreeList指向的任务控制块分配给该任务,完成任务控制块中各个值得初始化后,按任务控制块表头指针OSTCBList将其加入到任务控制块链表中。

为了加快对任务控制块的访问速度,除了使用双向链表之外,在UCOS_II.H中还专门定义了OS_TCB*类型的数组OSTCBTbl[],专门以优先级的顺序存放任务控制块指针。

为了随时访问正在运行的任务,UCOS_II.H中定义了OS_TCB* OSTCBCur。

可使用OSTaskDel()删除一个任务,实质上就是将该任务的任务控制块从任务控制块链表中删除,并将其归还到空任务控制块链表。

3. 任务控制块的初始化

系统调用OSTaskCreate()函数创建任务时,系统会自动调用OSTCBInit()函数对任务控制块进行初始化,该函数首先为创建的任务从空任务控制块链表中分配一个任务控制块,并用任务的属性对其中的参数进行初始化,然后将该控制块链接到任务控制块链表中。












  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值