学习总结(一)——FreeRTOS - 黑夜里的黑喵

时间:2024-04-16 15:50:04

学习总结(一)——FreeRTOS

一、为什么是FreeRTOS

  首先我们来看看什么是RTOS(实时操作系统)。顾名思义,实时操作系统是和分时操作系统区相对的,和分时操作系统相比,RTOS要求实时响应并安全可靠,分时操作系统则要求的是及时性而非实时,这也是两种操作系统最大的区别。因此,RTOS在要求实时性和可靠性高的军工、汽车电子、工业控制等领域很有前景。

  RTOS系统有很多种,常见的有uc/OS-III、RTX、RTThread、FreeRTOS等,为什么选择FreeRTOS呢。FreeRTOS是专为小型嵌入式系统设计的可扩展的实时内核。我认为选用RTOS的原因有以下几个:

1. Free,即免费开源

2. 用户(开发者)众多

3. 容易学习,官网上提供了很多资料

4. 系统小巧却齐全,仅需占用十几k RAM

  了解了FreeRTOS后,接下来就开始FreeRTOS的学习吧。

二、任务管理

  在我的理解中,RTOS其实就是用于完成一系列任务(或者说线程)的一种方法。一个应用中一般会包含多个任务,对于MCU而言,它实际上只能同时执行一个任务,因此需要通过调度来实现任务的切换,这就是任务管理。

2.1,任务状态

  通过RTOS对任务的管理方式可以看出,任务的一个任务可能的状态有4个:

1. 运行,即这个任务正在被CPU执行

2. 就绪,即任务处于可以被执行但还未被执行的状态

3. 阻塞,若一个任务正在等待一个时序或者中断,则该任务处于阻塞状态

4. 挂起,只有被相应的函数调用才任务才会被挂起或者解除挂起

   任务被创建后就处于这四个状态的一个,直至执行完毕。后面我们将针对这些状态进行深入分析。

2.2,任务函数

  在FreeRTOS中,任务是由C语言实现的。一个任务函数的结构如下:

void ATaskFunction(void *pvParameters)
{
    int Example=0;
    for( ; ; )
    {
         //任务代码
    }
    vTaskDelete(NULL);  //该函数的作用是删除任务
}

  一个任务函数可以有多个任务,一般任务函数处于死循环中。创建任务由xTaskCreate函数来实现,返回值有两个可能,pdTRUE代表成功,errCOUNLD_NOT_ALLOCATE_REQUIRED_MEMORY代表内存空间不足无法创建任务:

dataType xTaskCreate(
   TaskFunction_t pxTaskCode,        //要创建的任务函数
    const char * const pcName,        //任务名
    const uint16_t usStackDepth,     //需要的栈空间
    void * const pvParameters,        //传递到任务中的值
    UBaseType_t uxPriority,             //任务的优先级
    TaskHandle_t * const pxCreatedTask );   //用于传出任务的句柄

2.3,任务优先级

  由xTaskCreate函数可以看出,任务的优先级由uxPriority来设定,优先级没有上限,通过configMAX_PRIORITIES常量来设置,0代表最低,但是为了节省内存一般使用可能用到的最小值。在设定优先级后,调度器总是选择所有任务中优先级最高的任务来运行。如果两个任务优先级一致,那么两个任务将会交替执行,执行时间为一个时钟心跳(tick),心跳通过configTICK_RATE_HZ来设定。当任务A优先级比任务B高时,将总执行任务A,这样任务B永远没有执行机会,这是我们所不希望的,合理使用将任务控制在不同的状态才能使得我们的程序切实有用。

  任务优先级通过vTaskPrioritySet()函数来改变。

2.4,空闲任务

  当创建的任务都处于阻塞或挂起态时,将没有任务被执行,但是CPU需要任务来执行,调度器会创建一个空闲任务去执行,它总是拥有最低优先级以保证不干扰正常任务。回调函数会被一直被空闲任务调用,里面一般是后台功能代码,一般是将cpu设定为低功耗模式。

2.5,调度算法

  FreeRTOS支持一下三种调度算法:

  (1)抢占式调度算法

    任务有不同优先级,高优先级任务会一直被执行直至遇到阻塞或者中断

  (2)协作式调度

    任务永远不会被抢占,即使优先级相同也不会切换,除非任务遇到阻塞或者显式调用taskYIELD()时,才会进行任务切换。

  (3)选择任务优先级

    根据各个任务的周期来分配一个唯一的优先级。