【Freertos基础入门】freertos任务的优先级

简介: 【Freertos基础入门】freertos任务的优先级

前言


本系列基于stm32系列单片机来使用freerots

任务管理是实时操作系统(RTOS)的核心功能之一,它允许开发者以并发的方式组织和管理多个任务。FreeRTOS 是一个流行的开源RTOS,它提供了强大的任务管理功能,让开发者能够轻松创建和控制任务。本文将介绍 FreeRTOS 的任务管理功能,包括任务的创建、删除、挂起、恢复和优先级控制等方面的内容。


一、任务优先级


想象一下你在等候一个重要电话,同时又有其他事情要处理,比如看电视、吃饭或打扫房间。这时候,你可能会根据电话的重要性来决定优先处理的事情。


在计算机中,“优先级”是用来决定任务执行顺序的一个指标。就像你有很多事情要做,计算机也有很多任务要处理,比如读取数据、计算、响应用户操作等等。但是,由于计算机资源有限,它不可能同时处理所有任务。于是,我们可以将任务设置优先级,告诉计算机哪些任务更重要或更紧急。


比如说,你有两个任务,一个是检测火灾的传感器,另一个是播放音乐的任务。显然,当火灾传感器检测到火情时,它的任务优先级应该更高,因为这是一个紧急的情况,需要立即处理。而播放音乐的任务优先级相对较低,它不是那么紧急,可以稍后再处理。


通过设置任务的优先级,计算机可以根据任务的重要性来分配处理时间。高优先级的任务会被优先执行,确保重要任务能够及时完成。而低优先级的任务则会在高优先级任务得到处理之后再执行,以避免重要任务被延迟。


总之,优先级就是一种设置任务相对重要性的方式,让计算机可以根据任务的优先级来合理地分配处理时间,确保重要任务得到优先处理。


优先级的取值范围是:0~(configMAX_PRIORITIES – 1),数值越大优先级越高。

FreeRTOS的调度器可以使用2种方法来快速找出优先级最高的、可以运行的任务。使用不同的方法时,

configMAX_PRIORITIES 的取值有所不同。

通用方法

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

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

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

架构相关的优化的方法

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

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

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

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


在学习调度方法之前,你只要初略地知道:

FreeRTOS会确保最高优先级的、可运行的任务,马上就能执行

对于相同优先级的、可运行的任务,轮流执行


这无需记忆,就像我们举的例子:

厨房着火了,当然优先灭火

喂饭、回复信息同样重要,轮流做。


1.Tick

对于同优先级的任务,它们“轮流”执行。怎么轮流?你执行一会,我执行一会。

"一会"怎么定义?

人有心跳,心跳间隔基本恒定。

FreeRTOS中也有心跳,它使用定时器产生固定间隔的中断。这叫Tick、滴答,比如每10ms发生一次时

钟中断。

如下图:

假设t1、t2、t3发生时钟中断

两次中断之间的时间被称为时间片(time slice、tick period)

时间片的长度由configTICK_RATE_HZ 决定,假设configTICK_RATE_HZ为100,那么时间片长度就

是10ms

ac8a2ca799e540f790716fb1df8b1ddf.png

相同优先级的任务怎么切换呢?请看下图:

任务2从t1执行到t2

在t2发生tick中断,进入tick中断处理函数:

选择下一个要运行的任务

执行完中断处理函数后,切换到新的任务:任务1

任务1从t2执行到t3

从图中可以看出,任务运行的时间并不是严格从t1,t2,t3哪里开始。

5d56d00dd5574817a697d14dcb05e7c7.png

有了Tick的概念后,我们就可以使用Tick来衡量时间了,比如:

vTaskDelay(2); // 等待2个Tick,假设configTICK_RATE_HZ=100, Tick周期时10ms, 等待20ms
// 还可以使用pdMS_TO_TICKS宏把ms转换为tick
vTaskDelay(pdMS_TO_TICKS(100)); // 等待100ms


注意,基于Tick实现的延时并不精确,比如 vTaskDelay(2) 的本意是延迟2个Tick周期,有可能经过1个

Tick多一点就返回了。

注意,基于Tick实现的延时并不精确,比如 vTaskDelay(2) 的本意是延迟2个Tick周期,有可能经过1个

Tick多一点就返回了。


我们可以写出下面的示例代码:

void Task(void *p)
{
  int32_t *i = (int*)p;
  while(1)
  {
    printf("Count:%d\r\n",*i);
   (*i)++;
    vTaskDelay(pdMS_TO_TICKS(500));
  }
  vTaskDelete(NULL);
}
void Task2(void *p)
{
  while(1)
  {
  }
  vTaskDelete(NULL);
}
uint32_t count = 0;
TaskHandle_t mytaskHandle;
void TaskTest(void)
{
  xTaskCreate(Task,"MyTask",50,&count,1,&mytaskHandle);
  xTaskCreate(Task2,"MyTask2",50,&count,3,&mytaskHandle);
  vTaskStartScheduler();
}


MyTask2的优先级高于MyTask,所以会先执行MyTask2,当他执行MyTask2时,没有延时,他就会一直执行,因为没有比他更高优先级的任务了,只有他延时了,才会执行优先级更低的任务,而这里并没有,所以MyTask会一直不执行,就像下面这样,没有任何打印:

973adb20790846ebae2c7d5cb626f74d.png

所以我们尽量在任务中延时一下,以便其他任务的执行。


2.修改任务优先级

使用uxTaskPriorityGet来获得任务的优先级:

UBaseType_t uxTaskPriorityGet( const TaskHandle_t xTask );//参数为任务句柄


使用vTaskPrioritySet 来设置任务的优先级:

void vTaskPrioritySet( TaskHandle_t xTask,
UBaseType_t uxNewPriority );//参数1:任务句柄,参数2:新的优先级


根据上面的函数分析可得下面的代码:

通过按键更改优先级,在这里我直接用定义好的函数检测:if(key_scan(0) == KEY0_PRES)

如果大家想自己写也可以的!

uint32_t count = 0;
TaskHandle_t mytaskHandle;
TaskHandle_t mytaskHandle2;
void Task(void *p)
{
  int32_t *i = (int*)p;
  while(1)
  {
    printf("Count:%d\r\n",*i);
   (*i)++;
    vTaskDelay(pdMS_TO_TICKS(500));
  }
  vTaskDelete(NULL);
}
void Task2(void *p)
{
  uint8_t Priority = 1;
  while(1)
  {
    if(key_scan(0) == KEY0_PRES)
    {
      Priority++;
      vTaskPrioritySet(mytaskHandle,Priority);
    }
    vTaskDelay(20);
  }
  vTaskDelete(NULL);
}
void TaskTest(void)
{
  xTaskCreate(Task,"MyTask",50,&count,1,&mytaskHandle);
  xTaskCreate(Task2,"MyTask2",50,&count,3,&mytaskHandle2);
  vTaskStartScheduler();
}


实验效果:当我们按下按键0,他的优先级会++,在串口里会看到count的数量打印。

e5ec51da6498466cbfe44e67fc8332bb.png


总结


任务管理是 FreeRTOS 提供的一个强大功能,它允许开发者以并发的方式组织和管理多个任务。通过任务的创建、删除、挂起、恢复和优先级控制等操作,开发者可以灵活地控制任务的执行顺序和调度策略,从而实现复杂的系统功能。任务通信与同步机制进一步增强了任务的协同工作能力,使任务之间能够高效地共享数据和协调操作。借助 FreeRTOS 提供的任务管理功能,开发者可以更加方便地构建实时嵌入式系统,并具备可靠性和高效性。


需要注意的是,在使用 FreeRTOS 进行任务管理时,开发者需要注意任务的资源管理、优先级设置和调度策略等方面,以确保系统能够稳定地运行,并满足实时性和响应性的要求。

相关文章
|
API
FreeRTOS学习笔记—FreeRTOS移植
本文学习了如何移植FreeRTOS到自己的STM32工程。最后,根据正点原子提供的测试main函数,测试了移植效果。
534 0
FreeRTOS学习笔记—FreeRTOS移植
|
数据可视化 中间件 API
FreeRTOS记录(一、熟悉开发环境以及CubeMX下FreeRTOS配置)
熟悉 在 STM32 CubeMX 下面的 FreeRTOS 使用
1654 1
FreeRTOS记录(一、熟悉开发环境以及CubeMX下FreeRTOS配置)
|
6月前
|
消息中间件 算法 编译器
【FreeRTOS(一)】FreeRTOS新手入门——初识FreeRTOS
【FreeRTOS(一)】FreeRTOS新手入门——初识FreeRTOS
|
7月前
|
消息中间件 调度
FreeRTOS入门教程(任务状态)
FreeRTOS入门教程(任务状态)
253 0
|
6月前
|
传感器 物联网 调度
从0入门FreeRTOS之第一节 什么是FreeRTOS?
FreeRTOS(Free Real-Time Operating System)是一款开源的实时操作系统(RTOS),专为嵌入式系统设计。由Real Time Engineers Ltd.开发和维护,FreeRTOS以其小巧、高效、易于使用的特点广受欢迎。FreeRTOS支持多种微控制器和微处理器平台,提供丰富的实时操作系统功能,使开发者能够轻松构建高效、实时响应的应用程序。
358 0
|
6月前
|
存储 安全 算法
从0入门FreeRTOS之第二节FreeRTOS的体系结构
FreeRTOS的体系结构设计精巧且高效,专为嵌入式系统量身打造。理解FreeRTOS的体系结构对开发高效、稳定的嵌入式应用至关重要。下面,我们详细介绍FreeRTOS的核心组件、内核机制、中断管理和内存管理等内容。
210 0
|
调度 开发者
【Freertos基础入门】2个Freertos的Delay函数
【Freertos基础入门】2个Freertos的Delay函数
843 1
|
7月前
|
算法 调度
FreeRTOS入门教程(任务优先级,Tick)
FreeRTOS入门教程(任务优先级,Tick)
574 0
|
7月前
|
API 调度
FreeRTOS深入教程(中断管理)
FreeRTOS深入教程(中断管理)
316 0
|
7月前
FreeRTOS入门教程(信号量的具体使用)
FreeRTOS入门教程(信号量的具体使用)
156 0