uc/os-II笔记(一)

 uC/OS-II中的任务(1)
1.1 概念
   从应用程序设计的角度看,uC/OS-II的任务就是一个线程,就是一个用来解决用户问题的C语言函数和与之相关联的一些数据结构而构成的一个实体.
从任务存储结构来看,任务由三个部分构成:
1)任务程序代码:  任务的执行部分
2)任务堆栈:      用来保存任务工作环境
3)任务控制块:    用来保存任务的属性
uC/OS-II最多可以有64个任务(包括用户任务和系统任务).
任务的五种状态: 睡眠,就绪,运行,等待,中断服务状态

1.2 用户任务代码一般结构
   任务的执行代码通常是一个无限循环结构,并且在这个循环中可以响应中断,这种结构也叫做超循环结构
例:一个用C语言编写的任务
void MyTask(void *pdata)
{
    for(;;)
    {
        可以被中断的用户代码;
 OS_ENTER_CRITICAL();     //进入临界段(关中断)
        不可以被中断的用户代码;
 OS_EXIT_CRITICAL();      //退出临界段(开中断)
 可以被中断的用户代码;
    }
}
为了可以传递各种不同类型的数据甚至是函数,任务的参数是一个void类型的指针.因此可以说,uC/OS-II任务的代码结构是一个带有临界段的无限循环.
   用户应用程序的一般结构包括:初始化任务,创建任务,启动任务.
void MyTask1(void *pdata)

  for(;;)
  {
    ......
  }
}
void MyTask2(void *pdata)

  for(;;)
  {
    ......
  }
}
void main()
{
   for(;;)
   OSInit();
   ......
   OSTaskCreate(MyTask1,......);
   OSTaskCreate(MyTask2,......);
   ......
   OSStart();
   ......
 
}

1.3 系统任务两个(空闲任务和统计任务)
1)空闲任务是每个应用程序必须使用的,而统计任务则是应用程序可以根据实际需要来选择使用的.
void OSTaskIdle(void *pdata)
{
  #if OS_CRITICAL_METHOD==3
      OS_CPU_SR cpu_sr;
  #endif
   
   pdata = pdata;
   for(;;)
   {
      OS_ENTER_CRITICAL();
       OSdleCtr ++;    //计数
      OS_EXIT_CRITICAL();

   }
}
pdata = pdata主要是为了使用下这个参数防止有的编译器报错.空闲任务基本不做什么事情,只是对系统定义的一个空闲任务运行次数计数器OSdleCtr进行加1操作.当然用户认为有必要也可以在空闲任务中编写一些做用户工作的代码.
uC/OS-II规定,一个用户应用程序必须使用这个空闲任务,而且这个任务是不能用软件来删除的.

2)统计任务OSTaskStat()
这个统计任务每秒计算一次CPU在单位时间内被使用的时间,并把计算结果以百分比的形式存放在变量OSCPUuage中,以便应用程序来访问它来了解CPU的利用率.如果用户程序要使用这个统计任务,则必须在系统头文件OS_CFG.H中的系统配置常数OS_TASK_STAT_EN设置为1,并且必须在创建统计任务之前调用函数OSStatInit()对统计任务进行初始化.

1.4 任务的优先权及优先级别
  uC/OS-II的每个任务都必须具有一个唯一的优先级别.它把任务的优先权分为64个优先级别,每个优先级别用一个数字来表示,数字0表示优先级最高,数字越大优先级越低.通常一个应用程序的任务数小于64.为了节省内存,用户可以根据需要在文件OS_CFG.H中通过给表示最低优先级别的常数OS_LOWEST_PRIO赋值的方法来说明应用程序中任务优先级别的数目.这常数一旦定义下来意味着系统中可供使用优先级别为O,1,...,OS_LOWEST_PRIO,共OS_LOWEST_PRIO+1个.固定地,系统总是把最低优先级别OS_LOWEST_PRIO自动赋值给空闲任务.如果系统使用了统计任务,则系统把优先级别OS_LOWEST_PRIO-1自动赋值给统计任务.

1.5 任务堆栈
  为方便定义任务堆栈,在文件OS_CPU.H中专门定义了一个数据类型OS_STK;
typedef unsigned int OS_STK;
这样,在应用程序中定义任务堆栈的栈区就非常简单,即定义一个OS_STK类型的一个数组即可.例:
#define TASK_STK_SIZE 512
OS_STK TaskStk[TASK_STK_SIZE];
------------------------------------------
创建任务函数OSTaskCreate()的原型如下:
INT8U OSTaskCreate(
 void (* task)(void *pd),//指向任务的指针
 void *pdata,            //传递给任务的参数
 OS_STK *ptos,           //任务堆栈栈顶的指针
 INT8U prio  //指定任务优先级别的参数
                  );
创建一个任务,该任务的代码如下所示,堆栈的长度为128字节,优先级别为20,任务参数pdata实参为MyTaskAgu;
#define MyTaskStkN  64
OS_STK MyTaskStk[MyTaskStkN];

void main(void)
{
   ...
   OSTaskCreate(
  MyTask,  //任务指针
  &MyTaskAgu, //传递给任务的参数
  &MyTaskStk[MyTaskStkN-1],
  20
  );
   ...
}
这里要注意一个问题:堆栈递增方向是向上还是向下,根据处理器不同而不同.上例中是堆栈递增方向为向下的类型.
若假设使用了支持堆栈向上增长方式的处理器,则设置函数的参加ptos.则调用函数OSTaskCreate()创建任务时应写如下形式:
OSTaskCreate(MyTask,&MyTaskAgu,&MyTaskStk[0],20);
为了提高应用程序的可移植性可以在代码OS_CFG.H文件中常数OS_STK_GROWTH作为选择开关,使用户可通过定义该常数的值来选择相应的代码段,以适应不同的堆栈增长方式的需要.任务堆栈初始化由OSTaskStkInit()来完成.

1.6 任务控制块及任务控制块链表
1) 定义:记录任务的堆栈指针,任务的当前状态,任务的优先级别等一些与任务管理有关的属性就叫做任务控制块(OS_TCB)
  任务控制块是一个结构类型数据,当用户应用程序调用OSTaskCreate()函数创建一个用户任务时,这个函数就会对任务控制块中的所有成员赋于该任务相关的数据,并驻留在RAM中.


2)uC/OS-II用两条链表来管理任务控制块.一条是空任务块链表(其中所有任务控制块还没分配给任务);另一条是任务块链表(其中所有任务控制块已经分配给任务).空任务块链表是在应用程序调用函数OSInit()对uC/OS-II系统进行初始化时建立的;而任务块链表则是在调用函数OSTaskCreate()创建任务时建立的.建立任务控制块的具体做法是,从空任务控制块链表摘取一个空任务控制块,然后填充上任务属性后,再形成新的链表.
任务控制块初始化由OSTCBInit()来完成.

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值