ucos-II(二)

来源:互联网 发布:手机制作同学录软件 编辑:程序博客网 时间:2024/04/30 01:51
2.1任务的基本概念
2.1.1任务及其内存结构 在设计一个较为复杂的程序时,通常把一个大型任务分解为多个小任务,然后在计算机中通过运行小任务,最终达到完成大人物的目的。这种方法可以使系统并发运行多个任务,从而提高处理器的利用率,加快程序的执行速度,因此现代操作系统几乎都是多任务操作系统。 在uC/OS-II中,与上述小任务对应的程序实体叫“任务”,而uC/OS-II就是一个能对这些小任务的运行进行管理和调度的多任务操作系统。 从代码上看,uC/OS-II的任务是一个函数; 从任务的存储结构上看,uC/OS-II任务由:任务程序代码(函数)、任务堆栈和任务控制块组成。
uC/OS-II任务的组成 
进程:具有私有空间的任务 
线程:没有私有空间的任务   
uC/OS-II中的任务属于线程。 
uC/OS-II用任务控制块链表对任务进行管理
用户任务:由应用程序设计者编写的任务(为了解决应用问题)
uC/OS-II任务
系统任务:由系统提供的任务(为应用程序提供某种服务或系统本身服务的)  
目前,在uC/OS-II中,最多可以含有64个任务(包括用户任务和系统任务)     
2.1.2 任务的状态  
uC/OS-II任务的5种状态:睡眠、就绪、运行、等待、中断服务 
2.1.3 用户任务代码的一般结构
1.用户任务代码的一般结构   
任务的执行代码是一个无线循环结构,在循环当中可以响应中断,这种结构也叫做超循环结构。
void MyTask(void *pdata)   
{
    for(;;)
    {
         可以被中断的用户代码;
         OS_ENTER_CRITICAL();  //进入临界段(关中断)
         不可以被中断的用户代码;
         OS_EXIT_CRITICAL();  //退出临界段(开中断)
         可以被中断的用户代码;
    }
}   
 
OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()是uC/OS-II定义的两个宏。
2.用户应用程序的一般结构
用户任务是C语言函数,不由主函数main()调用,何时运行及何时中止由操作系统来调度。
main()函数是程序运行的入口,虽不用调度任务,但要负责任务的创建并将它们交给系统。
 
用户应用程序的结构:
void MyTask1(void *pdata)      //定义用户任务1
{
     for(;;)
     {
          ……
     }
}
void MyTask2(void *pdata)      //定义用户任务2
{
     for(;;)
     {
          ……
     }
}
void MyTask23void *pdata)      //定义用户任务3
{
     for(;;)
     {
          ……
     }
}
 
void main()
{
……
OSInit();                   //初始化uC/OS-II
……
OSTaskCreate(MyTask1,……);  //创建用户任务1
OSTaskCreate(MyTask2,……);  //创建用户任务2
OSTaskCreate(MyTask3,……);  //创建用户任务3
……
OSSTART();                //启动uC/OS-II
 
……
}
 
2.1.4系统任务
  空闲任务:每个应用程序必须使用的
  统计任务:应用程序根据实际需要来选择使用
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 ”,是为了防止编译器报错而使用的程序设计技巧。
 
2.统计任务
   该任务每秒计算一次CPU在单位时间内被使用的时间,并把计算结果以百分比的形式存放在变量OSCPUsage中,以便其他应用程序来了解CPU的利用率。
   如果用户应用程序决定要使用统计任务,则必须把定义在系统头文件OS_CFG.H中的系统配置常数OS_TASK_STAT_EN设置为1,并且在程序中要调用函数OSStatInit()来统计任务进行初始化。
 
2.1.5 任务的优先权及优先级别
uC/OS-II在系统配置文件OS_CFG.H中定义了一个用来表示最低优先级别常数OS_LOWEST_PRIO,如果用户为其赋了值,则系统中可供使用的优先级别为0、1、2、……、OS_LOWEST_PRIO,对应的,任务的总数不能超过OS_LOWEST_PRIO + 1个。
用户任务的优先级别要由用户创建一个任务时显式地定义。


2.2任务堆栈
所谓堆栈,就是在存储器中按数据“后进先出(LIFO)”的原则组织的连续存储空间。
 
2.2.1 任务堆栈的创建
   为了定义任务堆栈方便,在文件OS_CPU.H中专门定义了一个数据类型OS_STK:
   typedef  unsigned  int  OS_STK;  //该类型长度为16位 
  这样,在定义任务堆栈的栈区时,只需定义一个OS_STK类型的数组即可。例如:
  #define      TASK_STK_SIZE      512   //定义堆栈的长度(1024字节)
  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  MyTaskStk    N   64
 OS_STK  MyTaskStk[MyTaskStkN];
 
 void main()
 {
  ……
 OSTaskCreate(
            MyTask,        //任务的指针
            &MyTaskAgu,   //传递给任务的参数
            & MyTaskStk[MyTaskStkN - 1],  //任务堆栈栈顶地址
            20             //任务的优先级别
           );
  ……
  } 
  堆栈的增长方式是随系统所使用的处理器不同而不同的。
  为了增强应用程序的可移植性,可将上述代码改为:
#define  MyTaskStk    N   64
OS_STK  MyTaskStk[MyTaskStkN];
 
void main()
{
……
  #if OS_STK_GROWTH == 1
OSTaskCreate(
            MyTask,        //任务的指针
            &MyTaskAgu,   //传递给任务的参数
            & MyTaskStk[MyTaskStkN - 1],  //任务堆栈栈顶地址
            20             //任务的优先级别
           );
  #else
OSTaskCreate(
            MyTask,        //任务的指针
            &MyTaskAgu,   //传递给任务的参数
            & MyTaskStk[0],  //任务堆栈栈顶地址
            20             //任务的优先级别
           );
 #endif
……
}  


2.2.2 任务堆栈的初始化
函数原型如下:
OS_STK * OSTaskStkInit(
                     void (* task)(void * pd),
                     void * pdato,
                     OS_STK * ptos,
                     INT16U opt
                  );
0 0