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

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(vTask
### FreeRTOS抢占式调度与时间片调度的工作原理及区别 #### 抢占式调度 在 FreeRTOS抢占式调度机制下,CPU 始终由就绪状态下的最高优先级任务占有。这意味着如果某个更高优先级的任务进入就绪态(例如从阻塞状态唤醒),调度器会立即切换到这个高优先级任务的上下文中执行[^2]。 这种模式的优点在于能够快速响应重要的事件处理需求,从而提升系统的实时性表现。然而,在频繁发生任务切换的情境下可能会增加一定的上下文切换开销。 ##### 使用场景 - 实时性强的应用场合,比如工业自动化设备中的紧急信号检测。 - 对延迟敏感的操作环境,例如音频流播放或网络通信协议栈实现。 #### 时间片调度 相比之下,时间片轮转策略仅适用于具有相同优先级的任务之间。即使存在多个同级别任务等待运行,只要当前被执行的任务尚未耗尽其分配的时间片段长度,即便有另一个同等重要性的新到来者也不会立刻打断前者[^1]。 要激活这一特性,开发者需确保 `FreeRTOSConfig.h` 文件里包含了如下定义: ```c #define configUSE_TIME_SLICING 1 ``` 当启用此项之后,对于那些共享相等权重等级的任务来说,它们将轮流获得处理器使用权;每次切换都将依据预设好的 tick 计数来决定何时再次给予其它候选对象机会去消耗计算资源。 ##### 使用场景 - 当应用中有若干个不区分轻重缓急且希望公平对待的小型后台作业时较为合适。 - 数据采集系统中不同传感器读取操作可以视为平等对待而无需特别关注谁先完成的情况。 --- ### 主要差异对比表 | 特性 | 抢占式调度 | 时间片调度 | |-------------------|------------------------------------|----------------------------------| | **适用范围** | 不同情境下的异步任务 | 同一优先级内的多任务 | | **切换条件** | 更高的优先级任务变为可运行状态 | 达到设定的时间片限制 | | **实时性能** | 高 | 中 | | **复杂度/成本** | 上下文切换较多可能导致额外负担 | 相对较低 | --- ### 示例代码展示两种调度方式的效果 下面给出一段简单的例子演示这两种不同的行为: ```c #include "FreeRTOS.h" #include "task.h" void vHighPriorityTask(void *pvParameters){ while(1){ printf("This is High Priority Task\n"); vTaskDelay(pdMS_TO_TICKS(500)); //模拟工作负载 } } void vLowOrEqualPriorityTask(void *pvParameters){ while(1){ printf("This is Low or Equal Priority Task\n"); vTaskDelay(pdMS_TO_TICKS(700)); //模拟更长时间的工作量 } } int main(){ /* Create tasks here */ xTaskCreate(vHighPriorityTask,"HP_Task",configMINIMAL_STACK_SIZE,NULL,tasksHIGHEST_PRIORITY,&pxCreatedTaskHandle); xTaskCreate(vLowOrEqualPriorityTask,"LP_Task",configMINIMAL_STACK_SIZE,NULL,tasksLOWEST_PRIORITY,&pxCreatedTaskHandle); // Start the scheduler. vTaskStartScheduler(); return 0; } ``` 在这个案例里面,“HP_Task”拥有更高的优先级所以总是能够在自己准备好之后马上得到 CPU 控制权除非它主动让出了自己的时间段(`vTaskDelay`)。“LP_Task”则只能在其间歇期利用剩余的机会打印消息出来。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

陌上花开缓缓归以

你的鼓励将是我创作的最大动力,

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值