FreeRTOS 中delay、xtestdelay、xtestdelayUntil的区别

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

FreeRTOS 延迟函数概述

vTaskDelay

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

语法
void vTaskDelay(const TickType_t xTicksToDelay);
  • xTicksToDelay:延迟的时间长度,以系统时钟节拍 (ticks) 为单位。
示例代码
void vTaskA(void *pvParameters)
{for( ;; ){// 执行任务操作// ...// 延迟 1000 个 ticksvTaskDelay(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 个 ticksxtestdelay(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 个 ticksvTaskDelay(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 个 ticksxtestdelay(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.mzph.cn/bicheng/42130.shtml

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

相关文章

python爬虫入门(一)之HTTP请求和响应

一、爬虫的三个步骤&#xff08;要学习的内容&#xff09; 1、获取网页内容 &#xff08;HTTP请求、Requests库&#xff09; 2、解析网页内容 &#xff08;HTML网页结构、Beautiful Soup库&#xff09; 3、存储或分析数据 b站学习链接&#xff1a; 【【Python爬虫】爆肝两…

基于大象机器人UltraArm P340机械臂和传送带,实现教育场景中的自动化分拣系统!

引言 今天我们将展示一个高度自动化的模拟场景&#xff0c;展示多个机械臂与传送带协同工作的高效分拣系统。在这个场景中&#xff0c;机械臂通过视觉识别技术对物体进行分类&#xff0c;并通过精确的机械操作将它们放置在指定的位置。这一系统不仅提高了分拣的速度和准确性&am…

CH12_函数和事件

第12章&#xff1a;Javascript的函数和事件 本章目标 函数的概念掌握常用的系统函数掌握类型转换掌握Javascript的常用事件 课程回顾 Javascript中的循环有那些&#xff1f;Javascript中的各个循环特点是什么&#xff1f;Javascript中的各个循环语法分别是什么&#xff1f;…

java面试-java基础(中)

文章目录 一、面向对象OOP和面向过程OPP区别&#xff1f;二、面向对象有哪些特性&#xff1f;三、重载和重写区别&#xff1f;四、private&#xff0c;default&#xff0c;protected&#xff0c;public访问控制符范围五、抽象类和接口有什么区别&#xff1f;如何选用&#xff1…

什么是医学影像数据?

医学影像数据是指通过各种影像技术获取的人体内部结构和功能的可视化数据。这些影像技术包括但不限于X射线、计算机断层扫描&#xff08;CT&#xff09;、磁共振成像&#xff08;MRI&#xff09;、超声波&#xff08;US&#xff09;和正电子发射断层扫描&#xff08;PET&#x…

【ue5】虚幻5同时开多个项目

正常开ue5项目我是直接在桌面点击快捷方式进入 只会打开一个项目 如果再想打开一个项目需要进入epic 再点击启动就可以再开一个项目了

Hadoop-16-Hive HiveServer2 HS2 允许客户端远程执行HiveHQL HCatalog 集群规划 实机配置运行

章节内容 上一节我们完成了&#xff1a; Metastore的基础概念配置模式&#xff1a;内嵌模式、本地模式、远程模式实机配置远程模式 并测试 背景介绍 这里是三台公网云服务器&#xff0c;每台 2C4G&#xff0c;搭建一个Hadoop的学习环境&#xff0c;供我学习。 之前已经在 V…

昇思25天学习打卡营第13天|K近邻算法实现红酒聚类

K近邻算法&#xff08;K-Nearest-Neighbor, KNN&#xff09;是一种用于分类和回归的非参数统计方法&#xff0c;是机器学习最基础的算法之一。它正是基于以上思想&#xff1a;要确定一个样本的类别&#xff0c;可以计算它与所有训练样本的距离&#xff0c;然后找出和该样本最接…

牛客链表题:BM1 反转链表(取头放尾法)

描述 给定一个单链表的头结点pHead(该头节点是有值的&#xff0c;比如在下图&#xff0c;它的val是1)&#xff0c;长度为n&#xff0c;反转该链表后&#xff0c;返回新链表的表头。 数据范围&#xff1a; 0≤&#x1d45b;≤10000≤n≤1000 要求&#xff1a;空间复杂度 &…

TA都可以使用哪些存储接口?分别都存放在了哪里?

思考: 如何开发一个TA? sdk又是什么?开发一个TA的流程是怎样的?How to do?有关TA的签名介绍TEE开发Secure driver介绍RPMB的简介以及开发流程共享内存的最大限制是什么?TA的栈内存/堆内存又有哪些限制TA都支持哪些密码学算法?TA都可以使用哪些存储接口?分别都存放在了哪…

数据埋点从入门到了解

想讲讲为什么有埋点&#xff0c;举个例子 目录 什么是埋点&#xff1f;用途小红书上 埋点的主要类型代码示例1. 代码埋点前端埋点后端埋点 (Node.js 示例) 2. 全埋点示例3. 可视化埋点示例 解释常见问题埋点管理系统结论 王五是一名数据分析师&#xff0c;负责分析公司产品的用…

C++语言相关的常见面试题目(三)

1. List底层实现原理 省流&#xff1a; list底层实现了一个双向循环链表。 每个元素&#xff08;或节点&#xff09;包含三个部分&#xff1a;数据域(_M_Storage)、前驱指针(_M_prev)、后继指针(_M_next)。 数据域&#xff1a;存储实际数据。 前驱指针&#xff1a;指向链表中…

Mysql 数据库主从复制-CSDN

查询两台虚拟机的IP 主虚拟机IP 从虚拟机IP服务 修改对应的配置文件 查询对应配置文件的命令 find / -name my.cnf编辑对应的配置文件 主 my.cnf &#xff08;部分配置&#xff09; [mysqld] ########basic settings######## server_id 1 log_bin /var/log/mysql/mysql-…

gnome 建议安装的扩展

安装 扩展管理器&#xff1a; sudo apt install gnome-shell-extension-manager在 扩展管理器 里搜索并添加 扩展 推荐 Applications Menu&#xff1a;自带。左上角显示 应用程序 按钮&#xff0c;以下拉菜单分类显示应用RunCat&#xff1a;状态栏里显示一只猫和 cpu 利用率…

[激光原理与应用-98]:南京科耐激光-激光焊接-焊中检测-智能制程监测系统IPM介绍 - 2 - 什么是激光器焊接? 常见的激光焊接技术详解

目录 一、什么是激光焊接 1.1 概述 1.2 激光焊接的优点 二、激光焊接的应用 2.1 哪些场合必须使用激光焊接 1. 汽车制造业 2. 航空航天领域 3. 电子行业&#xff1a;消费类电子3C 4. 医疗器械制造 5. 新能源锂电池行业 6. 其他领域 三、激光焊接的分类 3.1 按焊接…

【ONLYOFFICE8.1】ONLYOFFICE8.1版本桌面编辑器测评

有宝子说office太贵&#xff0c;不适合个人和学生&#xff0c;而WPS不仅贵广告还多&#xff0c;那么有没有一款软件可以替代office和WPS呢&#xff1f;...当然有喽。当当当当&#xff01;它就是众望所归、备受好评的ONLYOFFICE。下面就和小编一起来探索和测评一下ONLYOFFICE8.1…

深入解析怀庄之醉酱酒的独特魅力

在众多美酒中&#xff0c;酱酒以其独有的风格和丰富的文化内涵&#xff0c;赢得了无数鉴赏家的青睐。本文旨在从专业角度深入探讨酱酒的空杯留香现象、典型色泽特性及品鉴技巧&#xff0c;揭示其背后的科学原理与艺术魅力&#xff0c;助您更全面地理解与欣赏这一中华传统佳酿。…

C++报错无法访问Private

严重性 代码 说明 项目 文件 行 禁止显示状态 错误 C2248 “main::Person::~Person”: 无法访问 private 成员(在“main::Person”类中声明) #include<iostream> #include<ctime> int main() {using namespace std;class Person{//Per…

响应式设计的双璧:WebKit 支持 CSS Flexbox 和 Grid 布局深度解析

响应式设计的双璧&#xff1a;WebKit 支持 CSS Flexbox 和 Grid 布局深度解析 在现代网页设计中&#xff0c;响应式布局是实现跨设备兼容性的关键。CSS Flexbox 和 Grid 作为 CSS 布局的两大支柱&#xff0c;提供了强大的工具来构建灵活和复杂的用户界面。WebKit&#xff0c;作…

JS的块级作用域是什么

在JavaScript中&#xff0c;块级作用域&#xff08;Block Scope&#xff09;是指变量或函数在代码块&#xff08;如{}内的代码区域&#xff09;中声明后&#xff0c;其作用域被限制在这个块级结构内部。这意味着&#xff0c;块外部的代码无法访问块内部声明的变量或函数&#x…