FreeRTOS 操作系统学习(二) 任务

                                                                                        FreeRTOS 操作系统学习

http://wiki.csie.ncku.edu.tw/embedded/FreeRTOS_Melot.pdf

1. 任务 

1.1  FreeRTOS 中的任务

       只要硬件和内存足够,FreeRTOS 运行的任务数量不受限制,作为一个实时操作系统,FreeRTOS  同时支持循环和非循环任务。在 RTOS 中,任务由一个简单的C函数定义,参数为 void*  类型,无返回值  (void)。

      用些函数用于对任务的管理 : 任务创建(vTaskCreate()),任务销毁((vTaskDelete()),优先级管理(uxTaskPriorityGet(),   vTaskPrioritySet())   延迟/恢复((vTaskDelay(), vTaskDelayUntil(),vTaskSuspend(), vTaskResume(),vTaskResumeFromISR()

      为了便于调试,用户可以选择很多操作,例如创建关键序列或对任务进行监控。、

1.1.1 任务的生命周期

     本节更详细地讲解任务从创建至销毁的整个发展过程。此时,我们假设只有一个内核,在指定的时间内只运行一个任务,每个人物只有“ 运行 (Running) ” “ 不运行 (Not Running) ”两种状态,由于我们假设是单核运行,且任意时刻有且只有一个任务在运行,那么其他的未运行的任务一定是处于“不运行 (Not Running)”状态. 图1  给出了这种情形下生命周期的简单示意图

     当一个任务从 非运行状态 进入运行状态,称之为“切入”,反之,成为“切出”。

                                                                            

                                                                                                   图1 生命周期示意图

     由于存在一些原因导致任务无法运行,由于“未运行”状态可以展开,如图2所示,当任务处于延迟或等待事件触发时,高优先级任务可以抢占低优先级任务(调度在第2节中介绍)。当任务正在处理器资源准的过程中,这个状态称之为“就绪(Ready)”态。当任务处于等待另一个任务完成(例如 等待信号量同步完成或互斥量)被延后执行,处于等待的状态称之为“阻塞。(Blocked)”。总之,调用vTaskSuspend()   、   vTaskResume()   、 xTaskResumeFromISR() 这些函数,可以使任务进入或退出“挂起 (Suspend)”状态。
     强调任务能自行退出“运行(Running)”态是非常重要的(即进入延迟、挂起或事件等待),只有调度器能使任务重新“切入”运行状态,当一个任务试图重新进入“运行”态,它的状态应为“就绪(Ready)”,只有任务调度器能决定当前的时间片分配给哪个就绪任务。

                                                        

 

                                                                                                    图2 任务的生命周期

1.2  创建 和 删除任务

       由一个简单的C函数定义的任务,它带有一个void *参数并且不返回任何内容(请参见 文本1)

                   void ATaskFunction( void *pvParameters );

                                                                       文本1: 一个典型的任务函数

      一个任务在销毁(Destroy)之前会一直运行。任务通常是一个死循环函数,或在到达最后一个大括号之前调用vTaskDestroy(NULL),由于死循环中的任何代码都可能失败并导致退出此循环,即使是重复性任务,在最后的大括号之前调用vTaskDelete()也更安全。文本3 是一个任务实现的典型例子

     可以使用vTaskCreate()创建任务(文本2)。 此函数参数列表如下:

  •      pvTaskCode:        一个指向任务实现函数的指针.
  •      pcName:              任务名.  这对FreeRTOS没用,但仅用于调试目的
  •      usStackDepth:     以字为单位的此任务的堆栈长度. 堆栈的实际大小取决于微控制器. 如果堆栈为32位(4字节),而usStackDepth的值为100,则将为任务分配400字节(4乘以100).
  •      pvParameters:     任务的指针参数. 较好的做法是创建一个专用的结构体变量,实例化并赋值,然后将其指针交给任务。.
  •      uxPriority:            任务优先级,    赋值范围从  0   到  ( MAX_PRIORITIES–1).   在第2节中将对此进行讨论
  •      pxCreatedTask:   指向可以处理任务标识符的指针. 如果任务标识符将来不会被修改,则可以将其设为NULL。 

   

    文本 2: 任务创建例程

portBASE_TYPE xTaskCreate  (       pdTASK_CODE                        pvTaskCode,           

                                                           const signed portCHAR  *         const pcName,                                 

                                                           unsigned portSHORT               usStackDepth,                                 

                                                           void                                           * pvParameters,                                  

                                                           unsigned                                   portBASE_TYPE uxPriority,               

                                                           xTaskHandle                            *pxCreatedTask   );  

 
文本 3: 一个典型的任务 (from “Using the FreeRTOS Real Time Kernel”).

void ATaskFunction( void *pvParameters ) 

      /* 

          可以按照常规函数声明变量的方法对变量进行声明。.  

          每个使用此函数创建的任务 ,会重新创建一个iVariableExample 变量.  

          如果变量是静态变量,所有此任务的实例将共享变量的存储,一个实例修改将导致所有实例的这个变量值都发生改变 

     */ 

       

      int iVariableExample = 0;      

 

     /* 死循环中为任务的具体实现. */    

     for( ;; )    

     {          

          /* 任务功能实现代码. */   

     }    

 

     /* 

        应该在不打破上述循环的前提下执行任务,然后才能删除该任务。

         传递给vTaskDelete()函数的NULL参数表示要删除的任务是当前正在调用的任务。

     */     

 

     vTaskDelete( NULL ); 

          当任务创建后可以使用xTaskDestroy()例程销毁任务。 参数为pxCreatedTask,例程见文本4中给出,示例参考文本3

                 

文本4 删除一个任务
void vTaskDelete( xTaskHandle pxTask );  

          删除任务后,空闲任务将释放所有释放所有分配给该任务的内存资源。注意,所有动态分配的内存必须手动释放。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章