当前位置: 首页 > news >正文

FreeRTOS学习(十):任务调度器挂起与恢复机制详解

FreeRTOS学习(十):任务调度器挂起与恢复机制详解


文章目录

  • FreeRTOS学习(十):任务调度器挂起与恢复机制详解
  • 简介
  • 一、 任务挂起与恢复的API函数
    • 1.1 任务挂起函数
    • 1.2 任务恢复函数
  • 二、重要特性
    • 与临界区的区别
    • 资源保护
  • 三、任务切换实例
    • 生活中的类比
    • 实际代码示例
      • 共享资源场景
    • 为什么需要任务挂起?
    • 数据一致性问题
    • 使用任务挂起后
    • 运行效果
  • 总结


简介

在FreeRTOS中,任务挂起和恢复是重要的任务管理机制。通过使用vTaskSuspendAll()和xTaskResumeAll()这两个API函数,我们可以实现任务的挂起和恢复操作


一、 任务挂起与恢复的API函数

1.1 任务挂起函数

vTaskSuspendAll();

这个函数用于挂起任务调度器。

1.2 任务恢复函数

xTaskResumeAll();

这个函数用于恢复任务调度器的运行。

二、重要特性

与临界区的区别

与临界区保护不同,任务挂起机制具有以下特点:

  • 挂起调度器时不会关闭中断
  • 更加灵活的任务管理方式
  • 适用于需要临时暂停任务调度的场景

资源保护

  • 任务挂起机制主要用于防止任务间的资源争夺
  • 中断仍然可以正常响应,不影响系统的实时性
  • 提供了一种轻量级的任务同步方式

三、任务切换实例

生活中的类比

想象你正在一家餐厅工作,需要同时处理多个任务:

  • 任务1:接待顾客点餐
  • 任务2:制作饮品
  • 任务3:结算账单
    就像一个服务员需要在这些工作之间切换一样,FreeRTOS也需要在不同的任务之间进行切换

实际代码示例

共享资源场景

假设我们有一个简单的温度监控系统,包含两个任务:

  • 温度采集任务
  • 数据显示任务
// 定义共享资源
float currentTemperature = 0.0;

// 温度采集任务
void vTaskTemperatureSample(void *pvParameters)
{
    float tempValue;
    
    while(1)
    {
        // 读取温度传感器
        tempValue = ReadTemperatureSensor();  // 假设这是读取传感器的函数
        
        // 更新共享资源前挂起调度器
        vTaskSuspendAll();
        currentTemperature = tempValue;  // 更新全局温度变量
        xTaskResumeAll();  // 恢复调度器
        
        vTaskDelay(pdMS_TO_TICKS(1000));  // 每秒采样一次
    }
}

// 显示任务
void vTaskDisplay(void *pvParameters)
{
    float tempToDisplay;
    
    while(1)
    {
        // 读取共享资源前挂起调度器
        vTaskSuspendAll();
        tempToDisplay = currentTemperature;  // 读取全局温度变量
        xTaskResumeAll();  // 恢复调度器
        
        // 显示温度值
        printf("Current Temperature: %.2f°C\n", tempToDisplay);
        
        vTaskDelay(pdMS_TO_TICKS(500));  // 每500ms更新一次显示
    }
}

// 主函数
int main(void)
{
    // 创建任务
    xTaskCreate(vTaskTemperatureSample, "TempSample", 1000, NULL, 2, NULL);
    xTaskCreate(vTaskDisplay, "Display", 1000, NULL, 1, NULL);
    
    // 启动调度器
    vTaskStartScheduler();
    
    return 0;
}

为什么需要任务挂起?

数据一致性问题

如果不使用任务挂起机制,可能会出现以下问题:

假设正在执行这样的操作序列:

  1. 温度采集任务正在更新currentTemperature
  2. 还没更新完,任务切换发生
  3. 显示任务读取了一个"更新到一半"的温度值
  4. 导致显示错误的数据

使用任务挂起后

使用vTaskSuspendAll()和xTaskResumeAll()后:

  1. 温度采集任务在更新温度时挂起调度器
  2. 确保温度更新操作不会被打断
  3. 显示任务在读取温度时也挂起调度器
  4. 确保读取到的是完整的温度数据

运行效果

Current Temperature: 25.30°C
Current Temperature: 25.31°C
Current Temperature: 25.32°C

每次显示的温度值都是完整的、一致的数据。


总结

FreeRTOS的任务挂起与恢复机制提供了一种灵活的任务管理方式,相比临界区保护更加轻量级,同时保持了中断响应能力。在需要防止任务切换但又不想完全关闭中断的场景下,可以很好的保证这个任务做完为止。

相关文章:

  • mysql中的聚簇索引,什么是聚簇索引和非聚簇索引
  • Android14 Settings应用添加有线网开关条目实现
  • Android设计模式之Builder模式
  • uniapp用户登录及获取用户信息(头像昵称)
  • 阿里云国际站代理商:如何通过Serverless调用GPU资源?
  • Python基础语法元素(学习笔记)
  • 李泽湘和中国硬科技创新十年 | 媒体报道
  • 高并发电商商详网关系统设计:架构、优化与实战
  • SQL Server 锁类型介绍
  • c++ primer 阅读手记 第五章
  • C++中使用CopyFromRecordset将记录集拷贝到excel中时,如果记录集为0个,函数崩溃,是什么原因
  • 基于ngnix配置本地代理到对应服务器
  • 使用Pygame构建贪吃蛇游戏:从零开始的Python游戏开发之旅
  • leetcode 46 全排列 | 回溯
  • Selenium 简单入门操作示例
  • Oracle-rman restore遭遇RMAN-03002与ORA-19563
  • Linux实现生产者消费者模型(基于阻塞队列)
  • VideoGrain:ICLR2025收录,无需训练,实现细粒度多层次视频编辑
  • MySQL 创建数据库
  • ESP32-S3-N16R8的麦金塔小智AI机器人及配套游戏机(教程及相关固件)
  • 民调显示特朗普执政百日支持率为80年来美历任总统最低
  • “富卫保险冠军赛马日”创双纪录,打造赛马旅游盛宴,印证香港联通国际优势
  • 核电开闸!国常会核准10台新机组,拉动超2000亿投资,新项目花落谁家?
  • 热点问答|第三轮间接谈判结束,美伊分歧还有多大?
  • 我驻阿巴斯总领馆:将持续跟踪港口爆炸事件进展,全力确保中方人员安全
  • 伊朗阿巴斯港港口爆炸已致47人受伤