FreeRTOS的Delay函数
两个Delay函数
有两个延时函数
vTaskDelay:至少等待指定个数的Tick Interrupt才能变为就绪态
xTaskDelayUtil:等待到指定的绝对时刻,才能变为就绪态
个人感觉这两个延时函数就是,比如一个我等3个小时,一个是我等到下午3点的区别。
两个函数的原型如下:
vTaskDelay:
void vTaskDelay( const TickType_t xTicksToDelay ){BaseType_t xAlreadyYielded = pdFALSE;/* A delay time of zero just forces a reschedule. */if( xTicksToDelay > ( TickType_t ) 0U ){configASSERT( uxSchedulerSuspended == 0 );vTaskSuspendAll();{traceTASK_DELAY();/* A task that is removed from the event list while the* scheduler is suspended will not get placed in the ready* list or removed from the blocked list until the scheduler* is resumed.** This task cannot be in an event list as it is the currently* executing task. */prvAddCurrentTaskToDelayedList( xTicksToDelay, pdFALSE );}xAlreadyYielded = xTaskResumeAll();}else{mtCOVERAGE_TEST_MARKER();}/* Force a reschedule if xTaskResumeAll has not already done so, we may* have put ourselves to sleep. */if( xAlreadyYielded == pdFALSE ){portYIELD_WITHIN_API();}else{mtCOVERAGE_TEST_MARKER();}}
xTaskDelayUtil
BaseType_t xTaskDelayUntil( TickType_t * const pxPreviousWakeTime,const TickType_t xTimeIncrement ){TickType_t xTimeToWake;BaseType_t xAlreadyYielded, xShouldDelay = pdFALSE;configASSERT( pxPreviousWakeTime );configASSERT( ( xTimeIncrement > 0U ) );configASSERT( uxSchedulerSuspended == 0 );vTaskSuspendAll();{/* Minor optimisation. The tick count cannot change in this* block. */const TickType_t xConstTickCount = xTickCount;/* Generate the tick time at which the task wants to wake. */xTimeToWake = *pxPreviousWakeTime + xTimeIncrement;if( xConstTickCount < *pxPreviousWakeTime ){/* The tick count has overflowed since this function was* lasted called. In this case the only time we should ever* actually delay is if the wake time has also overflowed,* and the wake time is greater than the tick time. When this* is the case it is as if neither time had overflowed. */if( ( xTimeToWake < *pxPreviousWakeTime ) && ( xTimeToWake > xConstTickCount ) ){xShouldDelay = pdTRUE;}else{mtCOVERAGE_TEST_MARKER();}}else{/* The tick time has not overflowed. In this case we will* delay if either the wake time has overflowed, and/or the* tick time is less than the wake time. */if( ( xTimeToWake < *pxPreviousWakeTime ) || ( xTimeToWake > xConstTickCount ) ){xShouldDelay = pdTRUE;}else{mtCOVERAGE_TEST_MARKER();}}/* Update the wake time ready for the next call. */*pxPreviousWakeTime = xTimeToWake;if( xShouldDelay != pdFALSE ){traceTASK_DELAY_UNTIL( xTimeToWake );/* prvAddCurrentTaskToDelayedList() needs the block time, not* the time to wake, so subtract the current tick count. */prvAddCurrentTaskToDelayedList( xTimeToWake - xConstTickCount, pdFALSE );}else{mtCOVERAGE_TEST_MARKER();}}xAlreadyYielded = xTaskResumeAll();/* Force a reschedule if xTaskResumeAll has not already done so, we may* have put ourselves to sleep. */if( xAlreadyYielded == pdFALSE ){portYIELD_WITHIN_API();}else{mtCOVERAGE_TEST_MARKER();}return xShouldDelay;}
下面是图示:
使用vTaskDelay(n)时,进入,退出vTaskDelay的时间间隔至少是n个Tick中断
使用xTaskDelayUtil(&Pre,n)时,前后两次退出xTaskDelayUntil的时间至少是n个Tick中断
退出xTaskDelayUntil时任务就进入就绪态,一般都能得到执行机会
所以可以使用xTaskDelayUntil来让任务周期性的运行

实验证明
程序创建2个任务
Task1:
高优先级
设置变量flag为1,然后调用vTaskDelay(xDelay50ms)或vTaskDelayUntil(&xLastWakeTime,xDelay50ms)
Task2:
低优先级
设置变量flag=0
main函数代码如下:
int main(void)
{prvSetupHardware();/*Task1的优先级更高,Task1先执行*/xTaskCreate(vTask1,"Task1",1000,NULL,2,NULL);xTaskCreate(vTask2,"Task2",1000,NULL,1,NULL);/*启动调度器*/vTaskStartScheduler();/*如果程序运行到这里,就表示出错了,一般是内存不足*/return 0;}Task1的代码中使用条件开关来选择Delay函数,把#if 1 改为 #if 0 就可以使用vTaskDelayUntil,代码如下:
void vTask1(void *pvParameters)
{const TickType_t xDelay50ms = pdMS_TO_TICKS(50UL);TickType_t xLastWakeTime;int i;/*获得当前的Tick Count*/xLastWakeTime = xTaskGetTickCount();for(;;){flag =1;/*故意加入多个循环,让程序运行时间长一点*/for(i=0;i<5;i++)printf("Task1 is running\r\n");
#if 1vTaskDelay(xDelay50ms);
#else vTaskDelayUntil(&PreWakeTime,xDelay50ms);}
}使用MDK的逻辑分析仪,可以观察flag变量的bit波形,如下:
flag为1时表示,Task1正在运行,flag为0时表示Task2正在运行,也就是Task1处于阻塞状态
vTaskDelay:指定的是阻塞时间
vTaskDelayUntil:指定的是任务执行的间隔,周期

相关文章:
FreeRTOS的Delay函数
两个Delay函数有两个延时函数vTaskDelay:至少等待指定个数的Tick Interrupt才能变为就绪态xTaskDelayUtil:等待到指定的绝对时刻,才能变为就绪态个人感觉这两个延时函数就是,比如一个我等3个小时,一个是我等到下午3点的…...
HCIA-HarmonyOS Application Developer——题目集1
题目1 1、一位开发人员在设计应用程序时,添加了一个Text组件和Button组件,开发样图如下所示。该开发者不能选择哪种布局方式来放置组件? A、StackLayout B、DependentLayout C、DirectionalLayout D、TableLayout 解析:(A&#…...
高性能 Message ToJavaBean 工具 【easy.server.mapper】
easy.server.mapper 介绍 后端开发中,消息转换常见问题 Map 中的数据 转换成实体Bean数组 中的数据 转换成实体BeanServet 中的 param 转换成实体Bean 以上的三个问题是最常见的消息转换困扰。 以Map 举例 常见做法是 手动转换 Map<String,Object> da…...
Web前端学习:三 - 练习
三六:风筝效果 <!DOCTYPE html> <html><head><meta charset"utf-8"><title></title><style type"text/css">*{margin: 0;padding: 0;}.d1{width: 200px;height: 200px;background: yellow;position…...
面试题:Android 中 Intent 采用了什么设计模式?
答案是采用了原型模式。原型模式的好处在于方便地拷贝某个实例的属性进行使用、又不会对原实例造成影响,其逻辑在于对 Cloneable 接口的实现。 话不多说看下 Intent 的关键源码: // frameworks/base/core/java/android/content/Intent.java public cla…...
Java数据类型与变量
个人主页:平行线也会相交 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 平行线也会相交 原创 收录于专栏【JavaSE_primary】 文章目录字面常量数据类型变量整型变量字节型变量浮点数变量双精度浮点数单精度浮点数字符型变量布尔型变量空常量nu…...
Python为CANoe工程添加/删除DBC文件
前面文章我们对于通过COM来实现打开CANoe、导入CANoe配置工程、导入执行文件、启动CANoe软件和执行脚本;但是这只能完成最基本的功能调用,在实际得到使用过程中,特别是各家在推的CI/CD以及平台化,仅仅是实现这些功能是完全不够用的;比如dbc的添加和删除,这是我们非常必要…...
不同的产品经理特征和需要的能力
产品经理是一个管家,需要和各方沟通推动产品各个决策进展。 每天早上看看线上用户数据、看下今天要安排任务,接着就是和各方开会讨论推动产品实现。每天穿插于与 UI、用户以及完成自己的 todolist 中循环。如果公司体制完善,还要和运营、数据…...
webpack之处理样式资源
处理样式资源 本章节我们学习使用 Webpack 如何处理 Css、Less、Sass、Scss、Styl 样式资源 #介绍 Webpack 本身是不能识别样式资源的,所以我们需要借助 Loader 来帮助 Webpack 解析样式资源 我们找 Loader 都应该去官方文档中找到对应的 Loader,然后…...
Golang 接口笔记
基本介绍接口是一个数据类型,可以定义一组方法,但都不需要实现。并且interface中不能包含任何变量。到某个自定义类型要使用的时候,再根据具体情况把这些方法实现出来语法type 接口名 interface {method1(参数列表) 返回值列表method2(参数列…...
[计算机网络(第八版)]第二章 物理层(章节测试/章节作业)
章节作业 带答案版 选择题 (单选题)双绞线是用两根绝缘导线绞合而成的,绞合的目的是( )。 A. 减少干扰 B. 提高传输速度 C. 增大传输距离 D. 增大抗拉强度(单选题)在电缆中采用屏蔽技术可以带来的好处主要是( )。 A…...
[iOS 理解] Swift Runtime (1) 类
Warm up 先看一段代码: import ObjectiveCclass Obj {var x: Double 0 }let v: NSObjectProtocol Obj() as! NSObjectProtocol let result v.isKind(of: Obj.self) let size class_getInstanceSize(Obj.self)我们有一个没有继承 NSObject、没有遵循 NSObjectP…...
ASEMI低压MOS管20N06参数,20N06体积,20N06大小
编辑-Z ASEMI低压MOS管20N06参数: 型号:20N06 漏极-源极电压(VDS):60V 栅源电压(VGS):20V 漏极电流(ID):20A 功耗(PD࿰…...
常见前端基础面试题(HTML,CSS,JS)(四)
作用域和作用域链的理解 作用域 (1)全局作用域 最外层函数和最外层函数外面定义的变量拥有全局作用域所有未定义直接赋值的变量自动声明为全局作用域所有window对象的属性拥有全局作用域全局作用域有很大的弊端,过多的全局作用域变量会污染…...
RabbitMQ发布确认模式
目录 一、发布确认原理 二、发布确认的策略 (一)开启发布确认的方法 (二)单个确认模式 (三)批量确认模式 (四)异步确认模式 (五)如何处理异步未确认消…...
零基础的人如何入门 Python ?看完这篇文章你就懂了
第一部分:编程环境准备 零基础入门Python的话我不建议用IDE,IDE叫集成开发环境,这东西一般是专业程序员用来实战开发用的,好处很多,比如:调试、语法高亮、项目管理、代码跳转、智能提示、自动完成、单元测…...
Atcoder abc257 E
E - Addition and Multiplication 2 题意: 给你一个数字n表示你现在拥有的金额 然后给你1~9每个经营额所需要的成本, 设总经营额为x, 当前使用的经营额为y, 则每一次使用经营额时都有x10*xy 问, 如何在使用不大于成本数量的金额下, 使得经营额最高 例如: 5 5 4 3 8 1 6 7 …...
模拟退火算法改进
import numpy as np import matplotlib.pyplot as plt import math import random from scipy.stats import norm from mpl_toolkits.mplot3d import Axes3D # 目标函数 def Function(x, y): return -20 * np.exp(-0.2*np.sqrt(0.5*(x*xy*y)))\ -np.exp(0.5*(n…...
SpringBoot+HttpClient+JsonPath提取A接口返回值作为参数调用B接口
前言 在做java接口自动化中,我们常常需要依赖多个接口,A接口依赖B,C,D接口的响应作为请求参数;或者URL中的参数是从其他接口中提取返回值作获取参数这是必不可少的。那么怎么实现呢?下面就来介绍多业务依赖…...
JUC 之 CompletableFuture
——CompletableFuture Future Future 接口(FutureTask 实现类) 定义了操作异步任务执行的一些方法,如获取异步的执行结果、取消任务的执行、判断任务是否被取消、判断任务执行是否完毕例如: 主线程让一个子线程去执行任务&…...
阿里云ACP云计算备考笔记 (5)——弹性伸缩
目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...
YSYX学习记录(八)
C语言,练习0: 先创建一个文件夹,我用的是物理机: 安装build-essential 练习1: 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件,随机修改或删除一部分,之后…...
Golang dig框架与GraphQL的完美结合
将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用,可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器,能够帮助开发者更好地管理复杂的依赖关系,而 GraphQL 则是一种用于 API 的查询语言,能够提…...
【2025年】解决Burpsuite抓不到https包的问题
环境:windows11 burpsuite:2025.5 在抓取https网站时,burpsuite抓取不到https数据包,只显示: 解决该问题只需如下三个步骤: 1、浏览器中访问 http://burp 2、下载 CA certificate 证书 3、在设置--隐私与安全--…...
【单片机期末】单片机系统设计
主要内容:系统状态机,系统时基,系统需求分析,系统构建,系统状态流图 一、题目要求 二、绘制系统状态流图 题目:根据上述描述绘制系统状态流图,注明状态转移条件及方向。 三、利用定时器产生时…...
网络编程(UDP编程)
思维导图 UDP基础编程(单播) 1.流程图 服务器:短信的接收方 创建套接字 (socket)-----------------------------------------》有手机指定网络信息-----------------------------------------------》有号码绑定套接字 (bind)--------------…...
力扣热题100 k个一组反转链表题解
题目: 代码: func reverseKGroup(head *ListNode, k int) *ListNode {cur : headfor i : 0; i < k; i {if cur nil {return head}cur cur.Next}newHead : reverse(head, cur)head.Next reverseKGroup(cur, k)return newHead }func reverse(start, end *ListNode) *ListN…...
论文阅读笔记——Muffin: Testing Deep Learning Libraries via Neural Architecture Fuzzing
Muffin 论文 现有方法 CRADLE 和 LEMON,依赖模型推理阶段输出进行差分测试,但在训练阶段是不可行的,因为训练阶段直到最后才有固定输出,中间过程是不断变化的。API 库覆盖低,因为各个 API 都是在各种具体场景下使用。…...
消防一体化安全管控平台:构建消防“一张图”和APP统一管理
在城市的某个角落,一场突如其来的火灾打破了平静。熊熊烈火迅速蔓延,滚滚浓烟弥漫开来,周围群众的生命财产安全受到严重威胁。就在这千钧一发之际,消防救援队伍迅速行动,而豪越科技消防一体化安全管控平台构建的消防“…...
全面解析数据库:从基础概念到前沿应用
在数字化时代,数据已成为企业和社会发展的核心资产,而数据库作为存储、管理和处理数据的关键工具,在各个领域发挥着举足轻重的作用。从电商平台的商品信息管理,到社交网络的用户数据存储,再到金融行业的交易记录处理&a…...
