我的FreeRTOS学习记录 —— 什么是FreeRTOS以及任务调度

什么是 RTOS

RTOS(Real-Time Operating System,实时操作系统) 是一种专为实时应用设计的操作系统,它能够确保任务在严格的时间限制内完成。RTOS 通常用于对响应时间要求较高的嵌入式系统中,例如工业控制、医疗设备、航空航天系统和消费电子设备。

RTOS 具有实时性、多任务、任务优先级调度、低延迟、资源管理等特点。

RTOS 由内核、任务、调度器、中断服务、同步与通信机制、定时器组成。

RTOS 与通用操作系统(如 Linux)的区别:

特性

RTOS

通用操作系统(如 Linux)

实时性

严格满足实时性要求

通常只追求高吞吐量,非实时

任务调度

优先级抢占

时间片轮转+优先级

占用资源

占用少,适合资源受限设备

占用多,需要较高硬件配置

中断响应时间

极低

较高

应用领域

嵌入式、工业控制等

桌面系统、服务器

常见的 RTOS 有:FreeRTOS、RT-Thread、uCOS 、Vxworks 等

介绍FreeRTOS

FreeRTOS是一个嵌入式系统使用的开源实时操作系统。FreeRTOS内核具有小巧、高效、可裁剪的特点,可以在资源有限的嵌入式系统中运行。它支持多任务、抢占式调度、时间片轮转、任务挂起、任务通知、消息队列、信号量、事件组等特性,为开发者提供了丰富的功能和灵活的配置选项。它提供了一个可移植、可扩展且免费的内核,被广泛应用于各种嵌入式设备和应用领域,包括工业控制、汽车电子、医疗设备、消费电子等。其源代码可以免费获取,并且提供了丰富的文档、示例代码和技术支持,使得开发者能够快速上手并构建稳定可靠的嵌入式系统。

FreeRTOS官网地址:点击前往

多任务系统

裸机开发时,需要执行的任务一般在main的while(1)死循环中,每个任务都是排队等待执行。这导致这系统的实时性很差,不管任务多紧急都是排队等候,不能提前执行。

多任务系统核心目标是“大事化小,小事化了”,把大任务分为很多小任务,接着把小任务解决掉。

FreeRTOS是一个抢占式实时操作系统,对于不同优先级的任务调度器是抢占式的——高优先级的任务可以打断低优先级任务的运行。对于相同优先级的任务是时间片轮转的调度,每个任务运行一个时间片,一个时间片过去后,操作系统自动切换到下一个任务执行。FreeRTOS的时间片有configTICK_RATE_HZ这个变量设置,使能时间片调度是通过configUSE_TIME_CLICING这个变量(默认是使能的)。

任务优先级

在FreeRTOS中每个任务可以有一个优先级从0到(configMAX_PRIORITIES-1),其中的 configMAX_PRIORITIES 在 FreeRTOSConfig.h 中定义。优先级数值越大,优先级越高,一般不超过32。当宏configUSE_TIME_CLICING定义为1时,多个任务可以共用一个优先级,数量不限。 空闲任务的优先级为零 (tskIDLE_PRIORITY)。

如果 configUSE_TIME_SLICING未经定义, 或者如果 configUSE_TIME_SLICING 设置为 1,则相同优先级的就绪状态任务 将使用时间切片轮询调度方案共享可用的处理时间 。

任务状态

FreeRTOS中的任务状态分为4种——运行态、就绪态、阻塞态、挂起态。

  • 运行态(Running):一个任务处于运行态时,说明该任务正在运行,也是当前正在使用处理器的任务。如果处理器为单核处理器(STM32),那么不管什么时候都只有一个任务处于运行态。
  • 就绪态(Ready):一个任务处于就绪态时,说明该任务随时可以进入处理器运行,并且没有被阻塞或者挂起。注意处于就绪态的任务并没有运行。
  • 挂起态(Suspended):任务在明确被挂起时进入挂起态,表示任务被暂停,直到被显式恢复。挂起状态的任务不会等待任何事件或时间的到来。
    • 触发条件:
      • vTaskSuspend(TaskHandle_t xTask) 将任务挂起
      • 任务自身调用 vTaskSuspend(NULL),可以将自己挂起
    • 回复条件:只有通过 vTaskResume(TaskHandle_t xTask)vTaskResumeFromISR(TaskHandle_t task)明确回复,任务才能从挂起态进入就绪态
  • 阻塞态(Blocked):任务在等待某个事件时会进入阻塞态,例如等待队列消息、等待信号量、等待任务通知或者调用 vTaskDelay 来等待时间。
    • 触发条件:当任务请求的条件还没有满足时,任务会进入阻塞态,比如
      • 等待某个队列消息 xQueueReceive
      • 等待某个信号量 xSemaphoreTake
      • 显示一段时间 vTaskDelay / vTaskDelayUntil
      • 等待事件标志组中的事件发生 xEcentGroupWaitBits
    • 恢复条件:
      • 等待的队列、信息量、任务通知等事件满足
      • 延时时间结束
      • 其他任务或中断向该任务发送通知和信号量

FreeRTOS系统任务调度

三种任务调度方式
  • 抢占式调度:主要针对优先级不同的任务,每个任务都有一个优先级,优先级高的任务抢占优先级低的任务
  • 时间片调度:主要针对优先级相同的任务,当多个任务的优先级相同时,任务调度器会在每一次系统时钟节拍到的时候切换任务。
  • 协程式调度(支持但不再更新):当前执行任务会一直运行,同时高优先级的任务不会抢占低优先级的任务
任务替换

FreeRTOS中有几种情况可能导致正在运行的任务被替换:

  • 抢占性调度:任务的优先级高于当前运行任务的任务被唤醒并准备好运行。如果在任务挂起期间发生了更高优先级任务的任务通知,则当前运行任务可能会被替换。
  • 时间片轮转调度:如果启用了时间片轮转调度并且任务时间片用尽,则当前运行任务可能会被替换。
  • 任务挂起和恢复:当任务挂起并稍后恢复时,如果挂起的任务具有更高的优先级或已经等待较长时间,则可能会导致当前运行任务被替换。
  • 等待事件或信号量:如果任务等待事件、信号量或队列时,如果其他任务释放了这些资源,则等待任务可能会被唤醒并准备好运行,导致当前运行任务被替换。
  • 中断处理程序的优先级:如果中断处理程序的优先级高于当前运行任务的优先级,并且中断处理程序唤醒了一个等待资源的任务,则当前运行任务可能会被替换。