FreeRTOS入门教程(任务优先级,Tick)

简介: FreeRTOS入门教程(任务优先级,Tick)

前言

本篇文章将带大家学习FreeRTOS中的任务优先级,并且了解什么是任务优先级,

一、什么是任务优先级

在FreeRTOS中,任务优先级用于确定任务的执行顺序和调度顺序。任务优先级越高,任务被调度执行的频率越高。FreeRTOS支持使用整数值来表示任务优先级,整数值越高,优先级越高。

FreeRTOS中任务优先级的范围通常是从0到configMAX_PRIORITIES-1,其中configMAX_PRIORITIES是一个配置常量,表示系统中支持的最大任务优先级数量。

在FreeRTOSconfig.h中可以查看到任务优先级的配置宏:

二、FreeRTOS如何分辨出优先级最高可运行的任务

1.通用方法:

使用C函数实现,对所有的架构都是同样的代码。对configMAX_PRIORITIES的取值没有限制。但

是configMAX_PRIORITIES的取值还是尽量小,因为取值越大越浪费内存,也浪费时间

configUSE_PORT_OPTIMISED_TASK_SELECTION被定义为0、或者未定义时,使用此方法。

2.架构相关的优化的方法:

架构相关的汇编指令,可以从一个32位的数里快速地找出为1的最高位。使用这些指令,可以快速

找出优先级最高的、可以运行的任务。

使用这种方法时,configMAX_PRIORITIES的取值不能超过32。

configUSE_PORT_OPTIMISED_TASK_SELECTION被定义为1时,使用此方法

三、FreeRTOS中的时钟节拍Tick

FreeRTOS中的时钟节拍(Tick)是一个基本的时间单位,用于管理任务调度和时间相关功能。时钟节拍的概念在实时操作系统中非常重要,因为它提供了时间的基本度量单位,允许任务和定时器按照预定的时间间隔执行。

以下是有关FreeRTOS中时钟节拍的重要信息:

1.时钟节拍的单位:时钟节拍是一个抽象的时间单位,通常表示为一个整数值。它可以映射到实际时间,但时钟节拍的精度和长度是可配置的。在大多数情况下,时钟节拍是以毫秒为单位的,但它可以配置为更短或更长的时间间隔,具体取决于应用程序的需求。

2.时钟节拍计数器:FreeRTOS维护一个时钟节拍计数器,用于跟踪已经过去的时钟节拍数。这个计数器通常是一个32位的值,可以支持大范围的时间跟踪。

3.任务调度:任务的调度和切换通常发生在时钟节拍的倍数上。当时钟节拍计数器达到任务的时间间隔(通常称为任务的延迟或周期)时,任务可能会被置于就绪状态,以便在下一个任务切换点执行。

4.定时器:时钟节拍也用于定时器功能。通过设置定时器的周期为时钟节拍的倍数,可以实现定时任务和事件的触发。

5.配置和定制:FreeRTOS允许用户配置时钟节拍的频率和精度,以适应特定应用的需求。这可以通过修改FreeRTOS配置文件中的参数来完成。例如,可以配置时钟节拍为1毫秒,10毫秒,甚至更短的时间间隔,以满足实时性要求。

6.时钟节拍在FreeRTOS中扮演了关键的角色,它不仅用于任务调度,还用于实现定时等待、超时操作和时间相关的功能。

FreeRTOS中的Tick值通常被配置为1ms:

四、什么是时间片

时间片(Time slice)是操作系统调度算法中的概念,用于分配处理器时间给多个可运行的任务。它是指操作系统将处理器的执行时间划分为固定长度的小段,每个任务在一个时间片内获得处理器的执行时间。

五、相同优先级任务怎么进行切换

在FreeRTOS默认采用了时间片轮转调度的策略,给每一个任务都分配一个固定的时间片,这个时间片的大小也就是1ms,可以通过修改configTICK_RATE_HZ这个宏来修改时间片的大小。

时间片大小(毫秒) = 1秒 / configTICK_RATE_HZ

Task1执行完一个时间片后会发生一次tick中断,然后进入tick中断处理函数中,在tick中断中选择要执行的下一个中断,当执行完tick中断后就切换Task2执行。

六、任务优先级实验

// 任务句柄
TaskHandle_t Task1Handle;
TaskHandle_t Task2Handle;
// 任务函数
void Task1(void* pvParameters) {
  while (1) {
    vTaskDelay(1000);
    printf("Task1 is running\n");
  }
}
void Task2(void* pvParameters) {
  while (1) {
    vTaskDelay(1000);
    printf("Task2 is running\n");
  }
}
int main(void) {
  // 创建两个任务
  xTaskCreate(Task1, "Task1", configMINIMAL_STACK_SIZE, NULL, 1, &Task1Handle);
  xTaskCreate(Task2, "Task2", configMINIMAL_STACK_SIZE, NULL, 2, &Task2Handle);
  // 启动调度器
  vTaskStartScheduler();
  while (1) {
    // 主循环为空,所有的任务由 FreeRTOS 调度
  }
}

因为任务2的优先级比任务1的优先级高所以会先打印Task2 is running,然后再打印Task1 is running,以此往复。

七、修改任务优先级

uxTaskPriorityGet() 和 vTaskPrioritySet() 是FreeRTOS中用于获取和设置任务优先级的函数。

uxTaskPriorityGet() 函数用于获取任务的当前优先级。它接受一个参数,即任务句柄,返回一个 UBaseType_t 类型的值,表示任务的当前优先级。

vTaskPrioritySet() 函数用于设置任务的优先级。它接受两个参数,第一个参数是要设置优先级的任务句柄,第二个参数是要设置的优先级值。这个函数没有返回值。

以下是一个使用 uxTaskPriorityGet() 和 vTaskPrioritySet() 函数的示例代码:

TaskHandle_t Task1Handle;
TaskHandle_t Task2Handle;
void Task1(void* pvParameters) {
  while (1) {
    // 获取任务优先级
    UBaseType_t priority = uxTaskPriorityGet(NULL);
    printf("Task1 priority: %u\n", priority);
    vTaskDelay(pdMS_TO_TICKS(1000));
  }
}
void Task2(void* pvParameters) {
  while (1) {
    // 获取任务优先级
    UBaseType_t priority = uxTaskPriorityGet(NULL);
    printf("Task2 priority: %u\n", priority);
    // 设置任务优先级
    vTaskPrioritySet(Task1Handle, 2);
    vTaskDelay(pdMS_TO_TICKS(5000));
    // 恢复任务优先级
    vTaskPrioritySet(Task1Handle, 1);
  }
}
int main(void) {
  xTaskCreate(Task1, "Task1", configMINIMAL_STACK_SIZE, NULL, 1, &Task1Handle);
  xTaskCreate(Task2, "Task2", configMINIMAL_STACK_SIZE, NULL, 2, &Task2Handle);
  vTaskStartScheduler();
  while (1) {
    // 主循环为空,所有的任务由 FreeRTOS 调度
  }

在这个示例代码中,我们创建了两个任务 Task1 和 Task2,并使用 uxTaskPriorityGet() 和 vTaskPrioritySet() 进行任务优先级的获取和设置。

在 Task1 中,我们首先使用 uxTaskPriorityGet(NULL) 获取当前任务的优先级,并通过 printf 打印出来。然后使用 vTaskDelay() 延迟1秒钟。

在 Task2 中,我们首先获取当前任务的优先级,然后通过 vTaskPrioritySet(Task1Handle, 2) 将 Task1 的优先级设置为2。接着延迟5秒钟后,再通过 vTaskPrioritySet(Task1Handle, 1) 恢复 Task1 的优先级为1。

通过运行这个示例代码,将会看到在任务的执行过程中,任务的优先级获取和设置操作被执行,并通过打印语句输出任务的优先级信息。

注意,在使用 uxTaskPriorityGet() 和 vTaskPrioritySet() 函数时,需要确保任务句柄是正确的,并且函数的调用时机是合适的,以避免潜在的问题和不一致性。

总结

本篇文章就讲解到这里。


相关文章
|
传感器 调度 开发者
【Freertos基础入门】freertos任务的优先级
【Freertos基础入门】freertos任务的优先级
502 0
|
6月前
|
消息中间件 调度
FreeRTOS入门教程(任务状态)
FreeRTOS入门教程(任务状态)
243 0
|
5月前
|
传感器 物联网 调度
从0入门FreeRTOS之第一节 什么是FreeRTOS?
FreeRTOS(Free Real-Time Operating System)是一款开源的实时操作系统(RTOS),专为嵌入式系统设计。由Real Time Engineers Ltd.开发和维护,FreeRTOS以其小巧、高效、易于使用的特点广受欢迎。FreeRTOS支持多种微控制器和微处理器平台,提供丰富的实时操作系统功能,使开发者能够轻松构建高效、实时响应的应用程序。
341 0
|
调度 开发者
【Freertos基础入门】2个Freertos的Delay函数
【Freertos基础入门】2个Freertos的Delay函数
802 1
|
6月前
|
API
FreeRTOS软件定时器的原理以及使用实例
FreeRTOS软件定时器的原理以及使用实例
140 0
|
6月前
|
缓存
muduo源码剖析之Timer定时器
Timer 类是 muduo 网络库中的一个定时器类,用于在指定的时间间隔后执行某个任务。Timer 类提供了一系列的方法来创建、启动、停止和删除定时器,以及设置定时器的时间间隔和回调函数等。在 muduo 网络库中,Timer 类被广泛应用于各种网络任务中,例如定期发送心跳包、更新缓存、清理资源等。通过使用 Timer 类,我们可以方便地实现定时任务,提高网络应用程序的可靠性和稳定性。:启动定时器,在指定的时间间隔后调用回调函数。:停止定时器,不再执行定时任务。
112 0
|
6月前
|
调度
FreeRTOS深入教程(空闲任务和Tick中断深入分析)
FreeRTOS深入教程(空闲任务和Tick中断深入分析)
283 0
|
6月前
|
算法 调度 开发者
FreeRTOS入门教程(空闲任务和钩子函数及任务调度算法)
FreeRTOS入门教程(空闲任务和钩子函数及任务调度算法)
477 0
|
6月前
|
数据采集 API 数据处理
FreeRTOS入门教程(软件定时器)
FreeRTOS入门教程(软件定时器)
178 0
|
6月前
|
存储 消息中间件 API
FreeRTOS深入教程(软件定时器源码分析)
FreeRTOS深入教程(软件定时器源码分析)
230 0