freertos 任务调度—抢占式, 时间片

news2024/9/25 3:19:41

FreeRTOS 操作系统支持三种调度方式: 抢占式调度,时间片调度和合作式调度。 实际应用主要是抢占式调度和时间片调度,合作式调度用到的很少.

1,抢占式调度
每个任务都有不同的优先级, 任务会一直运行直到被高优先级任务抢占或者遇到阻塞式的 API 函数,比如 vTaskDelay(延迟,事件标志等待,信号量等待)才会切换到其他任务。抢占式调度要掌握的最关键一点是: 每个任务都被分配了不同的优先级, 抢占式调度器会获得就绪列表中优先级最高的任务,并运行这个任务

FreeRTOS 操作系统是设置的数值越小任务优先级越低, 数值越大任务优先级越高,由于任务2的优先级高于任务1,因此任务2将首先运行。

#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"

#define TASK1_PRIORITY   (tskIDLE_PRIORITY + 1)
#define TASK2_PRIORITY   (tskIDLE_PRIORITY + 2)

// 任务函数原型
void vTask1(void *pvParameters);
void vTask2(void *pvParameters);

// 任务1函数
void vTask1(void *pvParameters) {
    const char *pcTaskName = (const char *)pvParameters;

    for (;;) {
        // 打印任务名
        printf("%s is running\n", pcTaskName);

        // 延时一段时间,模拟任务的工作负载
        vTaskDelay(pdMS_TO_TICKS(1000));
    }
}

// 任务2函数
void vTask2(void *pvParameters) {
    const char *pcTaskName = (const char *)pvParameters;

    for (;;) {
        // 打印任务名
        printf("%s is running\n", pcTaskName);

        // 延时一段时间,模拟任务的工作负载
        vTaskDelay(pdMS_TO_TICKS(500));
    }
}

int main(void) {
    // 创建任务
    xTaskCreate(vTask1, "Task 1", configMINIMAL_STACK_SIZE, "Task 1", TASK1_PRIORITY, NULL);
    xTaskCreate(vTask2, "Task 2", configMINIMAL_STACK_SIZE, "Task 2", TASK2_PRIORITY, NULL);

    // 启动调度器
    vTaskStartScheduler();

    // 如果调度器启动失败,将不会到达这里
    for (;;);
}

Task 2 is running
Task 1 is running
Task 2 is running
Task 1 is running
Task 2 is running
Task 1 is running
Task 2 is running
Task 1 is running
Task 2 is running
Task 1 is running
Task 2 is running

 抢占式调度算法实现。

#include <stdio.h>
#include <stdbool.h>

#define NUM_TASKS 3

typedef struct {
    int priority;
    bool isRunning;
} Task;

void initTask(Task *task, int priority) {
    task->priority = priority;
    task->isRunning = false;
}

void runTask(Task *task) {
    if (task->isRunning) {
        printf("Task with priority %d is running.\n", task->priority);
    }
}

void scheduleTasks(Task *tasks, int numTasks) {
    int highestPriority = -1;
    int highestPriorityTaskIndex = -1;

    // Find the highest priority task that is ready to run
    for (int i = 0; i < numTasks; ++i) {
        if (tasks[i].priority > highestPriority && !tasks[i].isRunning) {
            highestPriority = tasks[i].priority;
            highestPriorityTaskIndex = i;
        }
    }

    // Preempt lower priority tasks
    for (int i = 0; i < numTasks; ++i) {
        tasks[i].isRunning = false;
    }

    // Run the highest priority task
    if (highestPriorityTaskIndex != -1) {
        tasks[highestPriorityTaskIndex].isRunning = true;
        runTask(&tasks[highestPriorityTaskIndex]);
    }
}

int main() {
    Task tasks[NUM_TASKS];

    initTask(&tasks[0], 1);
    initTask(&tasks[1], 2);
    initTask(&tasks[2], 3);

    // Initially, the highest priority task is running
    tasks[2].isRunning = true;

    // Simulate scheduling
    printf("Initial scheduling:\n");
    scheduleTasks(tasks, NUM_TASKS);

    // Now, a higher priority task becomes ready
    printf("\nAfter a higher priority task becomes ready:\n");
    tasks[1].priority = 4; // Increase the priority of task 1
    scheduleTasks(tasks, NUM_TASKS);

    return 0;
}

 2, 时间片调度
每个任务都有相同的优先级, 任务会运行固定的时间片个数或者遇到阻塞式的 API 函数,比如
vTaskDelay, 才会执行同优先级任务之间的任务切换。

在 FreeRTOS 操作系统中只有同优先级任务才会使用时间片调度, 另外还需要用户在
FreeRTOSConfig.h 文件中使能宏定义:#define configUSE_TIME_SLICING 1

每个任务分配的时间片大小是 5 个系统时钟节拍。而在时间片轮询的过程中如果调用了阻塞式 API 函数, 调用函数时, 虽然 5 个系统时钟节拍的时间片大小还没有用完, 此时依然会通过时间片调度切换到下一个任务。

FreeRTOSConfig中:
configUSE_PREEMPTION=0关闭抢占,只有阻塞/挂起/运行的任务调用 taskYIELD()/ISR才会切换下文的任务

configUSE_TIME_SLICING=0关闭时间片,相同优先级的任务不会在tick间隔后切换。

#include "FreeRTOS.h"
#include "task.h"
#include<stdio.h>
#include "timers.h"

void vApplicationMallocFailedHook() {
	while(1);
}
 
void vApplicationStackOverflowHook(TaskHandle_t xTask, char * pcTaskName ) {
	while(1);
}

#define TASK_PRIORITY 1
#define TASK_STACK_SIZE 256
#define TIME_SLICE_MS 1000

// 任务句柄
TaskHandle_t taskHandles[2] = {NULL, NULL};

// 时间片定时器回调函数
void vTimerCallback(TimerHandle_t xTimer) {
    // 交换两个任务的优先级,以实现时间片调度
    vTaskPrioritySet(taskHandles[0], TASK_PRIORITY + 1);
    vTaskPrioritySet(taskHandles[1], TASK_PRIORITY);
}

// 任务函数
void vTaskFunction(void *pvParameters) {
    const char *pcTaskName = (const char *)pvParameters;
    UBaseType_t uxPriority;

    // 获取当前任务的优先级
    uxPriority = uxTaskPriorityGet(NULL);

    for (;;) {
        // 执行任务的工作
        printf("%s is running\n", pcTaskName);

        // 延时,模拟任务工作负载
        vTaskDelay(pdMS_TO_TICKS(TIME_SLICE_MS / 2));
    }
}

int main(void) {
    // 创建两个任务
    xTaskCreate(vTaskFunction, "Task 1", TASK_STACK_SIZE, "Task 1", TASK_PRIORITY, &taskHandles[0]);
    xTaskCreate(vTaskFunction, "Task 2", TASK_STACK_SIZE, "Task 2", TASK_PRIORITY, &taskHandles[1]);

    // 创建一个定时器,用于周期性地切换任务优先级
    TimerHandle_t xTimer = xTimerCreate(
        "Timer", pdMS_TO_TICKS(TIME_SLICE_MS), pdTRUE, (void *)0, vTimerCallback);

    // 启动定时器
    xTimerStart(xTimer, 0);

    // 启动调度器
    vTaskStartScheduler();

    // 如果调度器启动失败,将不会到达这里
    for (;;);
}

Task 1 is running
Task 2 is running
Task 1 is running
Task 2 is running
Task 1 is running
Task 2 is running

时间片c语言实现算法:

#include <stdio.h>
#include <stdbool.h>

#define NUM_TASKS 2
#define TIME_SLICE 5

typedef struct {
    int priority;
    int timeSliceCount;
    bool isRunning;
} Task;

void initTask(Task *task, int priority) {
    task->priority = priority;
    task->timeSliceCount = 0;
    task->isRunning = false;
}

void runTask(Task *task) {
    if (task->isRunning) {
        printf("Task with priority %d is running for time slice %d.\n", task->priority, task->timeSliceCount);
    }
}

void scheduleTasks(Task *tasks, int numTasks) {
    static int currentTaskIndex = 0;

    // Stop the current task
    tasks[currentTaskIndex].isRunning = false;
    tasks[currentTaskIndex].timeSliceCount = 0;

    // Move to the next task
    currentTaskIndex = (currentTaskIndex + 1) % numTasks;

    // Start the next task
    tasks[currentTaskIndex].isRunning = true;
    tasks[currentTaskIndex].timeSliceCount++;

    // Run the next task
    runTask(&tasks[currentTaskIndex]);
}

int main() {
    Task tasks[NUM_TASKS];

    initTask(&tasks[0], 1);
    initTask(&tasks[1], 2);

    // Simulate round-robin scheduling
    printf("Round-robin scheduling:\n");
    for (int i = 0; i < TIME_SLICE * NUM_TASKS; ++i) {
        scheduleTasks(tasks, NUM_TASKS);
    }

    return 0;
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2126306.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

使用 ShuffleNet 模型在 CIFAR-100 数据集上的图像分类

简介 在深度学习领域&#xff0c;图像分类任务是衡量算法性能的重要基准。本文将介绍我们如何使用一种高效的卷积神经网络架构——ShuffleNet&#xff0c;来处理 CIFAR-100 数据集上的图像分类问题。 CIFAR-100 数据集简介 CIFAR-100 数据集是一个广泛使用的图像分类数据集&…

使用了@Bean启动成功还能注入失败?秒级解决 定位分析

文章目录 Bean 断点跟不进去为什么需要多个同类型bean怎么友好处理同类型bean【任选一种】彩蛋 Bean 断点跟不进去 结论&#xff1a;你的其他代码 或者底层依赖&#xff0c;一定有改类型的自动注入代码&#xff0c;在Spring 机制中&#xff0c;默认拒绝Bean重写&#xff0c;你…

2024年一区SCI-极光优化算法 Polar Lights Optimization-附Matlab免费代码

引言 本期介绍了一种名为极光优化算法 Polar Lights Optimization (PLO)的元启发式算法。极光是一种独特的自然奇观&#xff0c;当来自太阳风的高能粒子在地磁场和地球大气层的影响下汇聚在地球两极时&#xff0c;就会发生极光。该成果于2024年8月最新发表在国际顶级JCR 1区、…

python画图|3D直方图基础教程

前述已经完成了直方图和3D图的基本学习&#xff0c;链接如下&#xff1a; 直方图&#xff1a;python画图|水平直方图绘制-CSDN博客 3D图&#xff1a;python画图|水平直方图绘制-CSDN博客 现在我们尝试把二者结合&#xff0c;画3D直方图。 【1】官网教程 首先&#xff0c;依…

微信开放标签【wx-open-launch-weapp】使用方法,亲测好用

如果你按照微信开放标签的文档来集成&#xff0c;那么恭喜你&#xff0c;绝对&#xff08;99%&#xff09;报错&#xff0c;今天在这里给大家演示一下在vue3中正确使用wx-open-launch-weapp的方法。 第一步&#xff1a; 配置wx.config&#xff0c;这个就不过多介绍了&#xff…

上海宝钢阿赛洛引领“绿能革命”:二期屋顶光伏项目赋能“双碳”目标新篇章

在“双碳”战略的宏伟蓝图下&#xff0c;一场能源革命的浪潮正席卷而来&#xff0c;分布式光伏以其独特的魅力成为这场变革中的璀璨明星。上海宝钢阿赛洛激光拼焊有限公司积极响应国家号召&#xff0c;携手上海宝钢节能环保技术有限公司&#xff0c;于近日宣布其屋顶光伏发电项…

SpringSecurity原理解析(五):HttpSecurity 类处理流程

1、SpringSecurity 在spring boot中与SSM项目中基于配置文件的区别 通过前边的笔记我们可以知道&#xff0c;在传统的SSM项目中 SpringSecurity的使用是基于配置文件 的&#xff0c;然后spring 容器初始化的时候将 SpringSecurity 中的各种标签解析成对应的Bean对象&#xff0c…

Cortex-M3架构学习:

异常类型 Cortex-M3 在内核水平上搭载了一个异常响应系统&#xff0c;支持为数众多的系统异常和外部中断。其 中&#xff0c;编号为 1 &#xff0d; 15 的对应系统异常&#xff0c;大于等于 16 的则全是外部中断。 Cortex-M3支持的中断源数目为 240 个&#xff0c;做成芯片后…

TensorFlow深度学习框架改进K-means、SOM自组织映射聚类算法及上海招生政策影响分析研究|附代码数据

全文链接&#xff1a;https://tecdat.cn/?p37652 原文出处&#xff1a;拓端数据部落公众号 分析师&#xff1a;Chen Zhang 在教育政策研究领域&#xff0c;准确评估政策对不同区域和学生群体的影响至关重要。2021 年上海市出台的《上海市初中学业水平考试实施办法》对招生…

PDF转Excel小达人养成记

在现代职场&#xff0c;数据管理与格式转换可谓是日常任务的重头戏&#xff1b;有时我们手头有一份PDF文件&#xff0c;但需要将其中的数据整理成Excel表格&#xff0c;这该如何是好&#xff1f;别急&#xff0c;今天我就来给大家介绍几款好用的PDF转Excel工具&#xff0c;以及…

使用您自己的图像微调 FLUX.1 LORA 并使用 Azure 机器学习进行部署

目录 介绍 了解 Flux.1 模型系列 什么是 Dreambooth&#xff1f; 先决条件 使用 Dreambooth 微调 Flux 的步骤 步骤 1&#xff1a;设置环境 第 2 步&#xff1a;加载库 步骤 3&#xff1a;准备数据集 3.1 通过 AML 数据资产&#xff08;URI 文件夹&#xff09;将图像上传到…

minio集群

1 集群部署 minio集群的搭建并不复杂&#xff0c;别人也有很多的例子&#xff0c;这里只是先把自己的集群搭建记录下来&#xff0c;重点是后面的章节&#xff0c;遇到问题如何解决。 1.1 修改主机名 hostnamectl set-hostname minio1 hostnamectl set-hostname minio2 hostna…

【深度学习】训练过程中一个OOM的问题,太难查了

现象&#xff1a; 各位大佬又遇到过ubuntu的这个问题么&#xff1f; 现象是在训练过程中&#xff0c;ssh 上不去了&#xff0c;能ping通&#xff0c;没死机&#xff0c;但是ubunutu 的pc侧的显示器&#xff0c;鼠标啥都不好用了。只能重启。 问题原因&#xff1a; OOM了95G&a…

【C++】C++11-基础

目录 1、统一的列表初始化 1.1 {}初始化 1.2 std::initializer_list 2、声明 2.1 auto 2.2 decltype 2.3 nullptr 3、范围for 4、智能指针 5、STL中的一些变化 5.1 新容器 5.2 新方法 1、统一的列表初始化 1.1 {}初始化 在C98中&#xff0c;标准允许使用花括号{}…

光伏发电量如何计算?

真实光伏发电情况&#xff0c;需要根据几十种复杂因素&#xff0c;再通过鹧鸪云算法&#xff0c;快速计算出实际发电量情况。 1、自研算法&#xff0c;技术创新引领未来 鹧鸪云光伏发电量自研算法&#xff0c;是研发团队历经8个月&#xff0c;基于深度学习、大数据分析等前沿技…

Aqara澳门体验店开业 品牌实力与市场前景备受瞩目

在全球经济持续波动的背景下&#xff0c;许多品牌选择采取保守策略。然而&#xff0c;Aqara却还能稳步前行&#xff0c;展现出了强劲的发展势头。7月20日&#xff0c;Aqara在澳门市场迈出了重要一步&#xff0c;开设了该地区首家标准4S智能家居体验馆。这一战略性的布局不仅凸显…

跟《经济学人》学英文:2024年09月07日这期 Can IKEA disrupt the furniture business again?

Can IKEA disrupt the furniture business again? It wants to help you sell your Billy bookcase disrupt&#xff1a; 颠覆&#xff0c;彻底改变 这里的 “disrupt” 是指“颠覆”或“彻底改变”某个行业或市场的现有运作方式&#xff0c;通常通过引入创新的做法或技术来…

Django-Celery-Flower实现异步和定时爬虫及其监控邮件告警

1 Django中集成celery # Django --->python 的web框架-web项目--》用浏览器访问 # celery--->分布式异步任务框架-定时任务-延迟任务-异步任务1.1 安装模块 #官方文档&#xff1a;https://docs.celeryq.dev/en/stable/django/first-steps-with-django.htmlpip install …

JavaEE:文件内容操作(二)

文章目录 文件内容操作读文件(字节流)read介绍read() 使用read(byte[] b) 使用 read(byte[] b, int off, int len) 使用 写文件(字节流)write介绍write(int b) 使用write(byte[] b) 使用write(byte[] b, int off, int len) 使用 读文件(字符流)read() 使用read(char[] cbuf) 使…

[产品管理-6]:NPDP新产品开发 - 4 - 战略 - 创新支持战略,支持组织的总体创新战略(平台战略、技术战略、营销战略、知识产权战略、能力建设战略)

目录 一、创新支持战略概述 二、平台战略&#xff1a;大平台小产品战略 2.1 概述 1、平台战略的定义 2、平台战略的特点 3、平台战略的应用领域 4、平台战略的成功案例 5、平台战略的发展趋势 2.2 大平台小产品战略 1&#xff09;大平台的建设 2&#xff09;、小产品…