FreeRTOS 中delay、xtestdelay、xtestdelayUntil的区别

        在 FreeRTOS 中,延迟功能对于任务调度至关重要。vTaskDelayvTaskDelayUntilxtestdelay 是常用的延迟函数,但它们在功能和适用场景上有所不同。本文将简要说明它们的区别,并通过示例代码展示每个函数的典型用法。每个函数的具体细节请参考本期刊的其它文章!

FreeRTOS 延迟函数概述

vTaskDelay

    vTaskDelay 是 FreeRTOS 提供的标准延迟函数,用于将当前任务阻塞指定的时间。它的主要作用是让任务在一段时间内不参与调度,从而让其他任务有机会运行。

语法
void vTaskDelay(const TickType_t xTicksToDelay);
  • xTicksToDelay:延迟的时间长度,以系统时钟节拍 (ticks) 为单位。
示例代码
void vTaskA(void *pvParameters)
{
    for( ;; )
    {
        // 执行任务操作
        // ...

        // 延迟 1000 个 ticks
        vTaskDelay(pdMS_TO_TICKS(1000)); // 延迟 1 秒
    }
}

        在这个例子中,vTaskA 每次循环时会延迟 1000 个时钟节拍 (1 秒),然后再继续执行。

vTaskDelayUntil

  vTaskDelayUntil 是 FreeRTOS 的另一种延迟机制,用于创建精确的周期性延迟。它确保任务每隔固定时间间隔运行,不受其他任务执行时间的影响。

语法
BaseType_t xTaskDelayUntil(TickType_t * const pxPreviousWakeTime, const TickType_t xTimeIncrement);
  • pxPreviousWakeTime:一个保存上一次唤醒时间的变量的指针。
  • xTimeIncrement:任务间隔的时间,以系统时钟节拍 (ticks) 为单位。
示例代码
void vTaskB(void *pvParameters)
{
    TickType_t xLastWakeTime;
    const TickType_t xFrequency = pdMS_TO_TICKS(1000); // 1 秒

    // 初始化上一次唤醒时间
    xLastWakeTime = xTaskGetTickCount();

    for( ;; )
    {
        // 等待下一个周期
        vTaskDelayUntil(&xLastWakeTime, xFrequency);

        // 执行任务操作
        // ...
    }
}

        在这个例子中,vTaskB 在每次循环时会精确地延迟 1 秒,无论其他任务的执行情况如何,都能保证固定周期运行。

xtestdelay

  xtestdelay 通常不是标准的 FreeRTOS API 函数,而可能是某些示例代码或用户定义的函数。它的功能和 vTaskDelay 类似,用于延迟任务的执行,但通常用于测试或调试目的,或在某些特定场景下用作简单的延迟函数。

示例代码

假设 xtestdelay 是用户自定义的简单延迟函数:

void xtestdelay(TickType_t xTicksToDelay)
{
    // 实现一个简单的延迟
    TickType_t xCurrentTime = xTaskGetTickCount();
    while ((xTaskGetTickCount() - xCurrentTime) < xTicksToDelay)
    {
        // 忙等待
    }
}

void vTaskC(void *pvParameters)
{
    for( ;; )
    {
        // 执行任务操作
        // ...

        // 延迟 500 个 ticks
        xtestdelay(pdMS_TO_TICKS(500)); // 延迟 500 毫秒
    }
}

区别

  • vTaskDelay:让任务延迟指定的时间,从调用时刻开始计算,适合简单的延迟场景。
  • vTaskDelayUntil:提供精确的周期性延迟,从上次唤醒时间开始计算,适用于需要严格周期控制的任务。
  • xtestdelay:通常是用户自定义的延迟函数,用于测试或特定场景下的简单延迟,可能通过忙等待实现,不建议用于实际生产环境。

完整代码示例

        以下是完整代码示例,展示如何在 FreeRTOS 中使用 vTaskDelayvTaskDelayUntilxtestdelay

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

// 任务 A 使用 vTaskDelay
void vTaskA(void *pvParameters)
{
    for( ;; )
    {
        // 打印任务 A 的信息
        printf("Task A is running\n");

        // 延迟 1000 个 ticks
        vTaskDelay(pdMS_TO_TICKS(1000)); // 延迟 1 秒
    }
}

// 任务 B 使用 vTaskDelayUntil
void vTaskB(void *pvParameters)
{
    TickType_t xLastWakeTime;
    const TickType_t xFrequency = pdMS_TO_TICKS(1000); // 1 秒

    // 初始化上一次唤醒时间
    xLastWakeTime = xTaskGetTickCount();

    for( ;; )
    {
        // 等待下一个周期
        vTaskDelayUntil(&xLastWakeTime, xFrequency);

        // 打印任务 B 的信息
        printf("Task B is running\n");
    }
}

// xtestdelay 函数实现
void xtestdelay(TickType_t xTicksToDelay)
{
    TickType_t xCurrentTime = xTaskGetTickCount();
    while ((xTaskGetTickCount() - xCurrentTime) < xTicksToDelay)
    {
        // 忙等待
    }
}

// 任务 C 使用 xtestdelay
void vTaskC(void *pvParameters)
{
    for( ;; )
    {
        // 打印任务 C 的信息
        printf("Task C is running\n");

        // 延迟 500 个 ticks
        xtestdelay(pdMS_TO_TICKS(500)); // 延迟 500 毫秒
    }
}

int main(void)
{
    // 创建任务
    xTaskCreate(vTaskA, "TaskA", configMINIMAL_STACK_SIZE, NULL, 3, NULL);
    xTaskCreate(vTaskB, "TaskB", configMINIMAL_STACK_SIZE, NULL, 3, NULL);
    xTaskCreate(vTaskC, "TaskC", configMINIMAL_STACK_SIZE, NULL, 3, NULL);

    // 启动调度器
    vTaskStartScheduler();

    // 调度器应该永不返回
    for( ;; );
}

        在这个示例中,我们创建了三个任务,每个任务使用不同的延迟机制。vTaskA 使用 vTaskDelay 进行简单延迟,vTaskB 使用 vTaskDelayUntil 进行周期性延迟,vTaskC 使用自定义的 xtestdelay 进行忙等待延迟。这些示例展示了如何在 FreeRTOS 中实现任务调度和延迟。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

STM32-PWR和WDG看门狗

本内容基于江协科技STM32视频学习之后整理而得。 文章目录 1. PWR1.1 PWR简介1.2 电源框图1.3 上电复位和掉电复位1.4 可编程电压监测器1.5 低功耗模式1.6 模式选择1.7 睡眠模式1.8 停止模式1.9 待机模式1.10 库函数 2. WDG看门狗2.1 WDG简介2.2 IWDG框图2.3 IWDG键寄存器2.4 …

ACM ICPS独立出版 | 2024年第三届计算与人工智能国际会议(ISCAI 2024)

会议简介 Brief Introduction 2024年第三届计算与人工智能国际会议(ISCAI 2024) 会议时间&#xff1a;2024年11月22 -24日 召开地点&#xff1a;中国大理 大会官网&#xff1a;www.iscai.org 2024年第三届计算与人工智能国际会议(ISCAI 2024)将围绕“计算与人工智能”的最新研究…

排序 -- 冒泡排序和快速排序

一、 交换排序 1、基本思想 所谓交换&#xff0c;就是根据序列中两个记录键值的比较结果来对换这两个记录在序列中的位置&#xff0c;交换排序的特点是&#xff1a;将键值较大的记录向序列的尾部移动&#xff0c;键值较小的记录向序列的前部移动。 2、常见的交换排序 1、冒泡…

Java Selenium入门程序

需求&#xff1a;使用chrome浏览器打开百度首页 1.配置浏览器驱动 &#xff08;1&#xff09;下载浏览器驱动&#xff0c;浏览器版本需与驱动版本一致&#xff1b; &#xff08;2&#xff09;编辑系统环境变量-->编辑Path-->填入浏览器驱动路径&#xff1a; 2.maven工…

【反悔贪心 反悔堆】1642. 可以到达的最远建筑

本文涉及知识点 反悔贪心 反悔堆 LeetCode1642. 可以到达的最远建筑 给你一个整数数组 heights &#xff0c;表示建筑物的高度。另有一些砖块 bricks 和梯子 ladders 。 你从建筑物 0 开始旅程&#xff0c;不断向后面的建筑物移动&#xff0c;期间可能会用到砖块或梯子。 当…

刷题之删除有序数组中的重复项(leetcode)

删除有序数组中的重复项 这题简单题&#xff0c;双指针&#xff0c;一个指针记录未重复的数的个数&#xff0c;另一个记录遍历的位置。 以下是简单模拟&#xff0c;可以优化&#xff1a; class Solution { public:int removeDuplicates(vector<int>& nums) {int l0…

STL--求交集,并集,差集(set_intersection,set_union,set_difference)

set_intersection(重要) 求两个有序的序列的交集. 函数声明如下: template<class InputIterator1, class InputIterator2, class OutputIterator>OutputIterator set_intersection(InputIterator1 _First1, //容器1开头InputIterator1 _Last1, //容器2结尾(不包含)Inp…

ChatGPT4深度解析:探索智能对话新境界

大模型chatgpt4分析功能初探 目录 1、探测目的 2、目标变量分析 3、特征缺失率处理 4、特征描述性分析 5、异常值分析 6、相关性分析 7、高阶特征挖掘 1、探测目的 1、分析chat4的数据分析能力&#xff0c;提高部门人效 2、给数据挖掘提供思路 3、原始数据&#xf…

Navicat终于免费了, 但是这个结果很奇葩

个人用下载地址: 点呀 好家伙, 每个机构最多5个用户, 对于正在审计的公司…

DAY1: 实习前期准备

文章目录 VS Code安装的插件C/CCMakeGitHub CopilotRemote-SSH收获 VS Code 下载链接&#xff1a;https://code.visualstudio.com 安装的插件 C/C 是什么&#xff1a;C/C IntelliSense, debugging, and code browsing. 为什么&#xff1a;初步了解如何在VS Code里使用C输出…

Vulnhub-Os-hackNos-1(包含靶机获取不了IP地址)

https://download.vulnhub.com/hacknos/Os-hackNos-1.ova #靶机下载地址 题目&#xff1a;要找到两个flag user.txt root.txt 文件打开 改为NAT vuln-hub-OS-HACKNOS-1靶机检测不到IP地址 重启靶机 按住shift 按下键盘字母"E"键 将图中ro修改成…

筛选Github上的一些优质项目

每个项目旁都有标签说明其特点&#xff0c;如今日热捧、多模态、收入生成、机器人、大型语言模型等。 项目涵盖了不同的编程语言和领域&#xff0c;包括人工智能、语言模型、网页数据采集、聊天机器人、语音合成、AI 代理工具集、语音转录、大型语言模型、DevOps、本地文件共享…

7-6 每日升学消息汇总

复旦附中清北比例大涨&#xff0c;从统计数据来看&#xff0c;今年复附的清北人数将创历史新高&#xff0c;达到前所未有年进43人。离上海7月9号中考出分&#xff0c;还有3天。小道消息说&#xff0c;画狮的数游天下又回来了&#xff0c;目前还未官方消息。2024第二届国际数学夏…

安卓虚拟位置修改1.25beta支持路线模拟、直接定位修改

导语:更新支持安卓14/15&#xff0c;支持路线模拟、直接定位修改&#xff0c;仅支持单一版本 无root需根据教程搭配下方链接所提供的虚拟机便可进行使用 有root且具备XP环境可直接真机运行 如你有特殊需求 重启问题设置打开XP兼容 针对具有虚拟机检测的软件 建议如下 度娘搜索…

多表查询sql

概述&#xff1a;项目开发中,在进行数据库表结构设计时,会根据业务需求及业务模块之间的关系,分析并设计表结构,由于业务之间相互关联,所以各个表结构之间也存在着各种联系&#xff0c;分为三种&#xff1a; 一对多多对多一对一 一、多表关系 一对多 案例&#xff1a;部门与…

在CMD中创建虚拟环境并在VSCode中使用和管理

1. 使用Conda创建虚拟环境 在CMD或Anaconda Prompt中执行以下代码以创建一个新的虚拟环境&#xff1a; conda create -n my_env python 3.8 这样会创建一个名为 my_env 的环境&#xff0c;并在Anaconda环境目录下生成一个相应的文件夹&#xff0c;包含该虚拟环境所需的所有…

STM32-ADC+DMA

本内容基于江协科技STM32视频学习之后整理而得。 文章目录 1. ADC模拟-数字转换器1.1 ADC模拟-数字转换器1.2 逐次逼近型ADC1.3 ADC框图1.4 ADC基本结构1.5 输入通道1.6 规则组的转换模式1.6.1 单次转换&#xff0c;非扫描模式1.6.2 连续转换&#xff0c;非扫描模式1.6.3 单次…

时间、查找、打包、行过滤与指令的运行——linux指令学习(二)

前言&#xff1a;本节内容标题虽然为指令&#xff0c;但是并不只是讲指令&#xff0c; 更多的是和指令相关的一些原理性的东西。 如果友友只想要查一查某个指令的用法&#xff0c; 很抱歉&#xff0c; 本节不是那种带有字典性质的文章。但是如果友友是想要来学习的&#xff0c;…

如何确保 PostgreSQL 在高并发写操作场景下的数据完整性?

文章目录 一、理解数据完整性二、高并发写操作带来的挑战三、解决方案&#xff08;一&#xff09;使用合适的事务隔离级别&#xff08;二&#xff09;使用合适的锁机制&#xff08;三&#xff09;处理死锁&#xff08;四&#xff09;使用索引和约束&#xff08;五&#xff09;批…

系统学习ElastricSearch(一)

不知道大家在项目中是否使用过ElastricSearch&#xff1f;大家对它的了解又有多少呢&#xff1f;官网的定义&#xff1a;Elasticsearch是一个分布式、可扩展、近实时的搜索与数据分析引擎。今天我们就来揭开一下它的神秘面纱&#xff08;以下简称ES&#xff09;。 ES 是使用 J…