当前位置: 首页 > news >正文

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&#xff1a;至少等待指定个数的Tick Interrupt才能变为就绪态xTaskDelayUtil&#xff1a;等待到指定的绝对时刻&#xff0c;才能变为就绪态个人感觉这两个延时函数就是&#xff0c;比如一个我等3个小时&#xff0c;一个是我等到下午3点的…...

HCIA-HarmonyOS Application Developer——题目集1

题目1 1、一位开发人员在设计应用程序时&#xff0c;添加了一个Text组件和Button组件&#xff0c;开发样图如下所示。该开发者不能选择哪种布局方式来放置组件? A、StackLayout B、DependentLayout C、DirectionalLayout D、TableLayout 解析&#xff1a;&#xff08;A&#…...

高性能 Message ToJavaBean 工具 【easy.server.mapper】

easy.server.mapper 介绍 后端开发中&#xff0c;消息转换常见问题 Map 中的数据 转换成实体Bean数组 中的数据 转换成实体BeanServet 中的 param 转换成实体Bean 以上的三个问题是最常见的消息转换困扰。 以Map 举例 常见做法是 手动转换 Map<String,Object> da…...

Web前端学习:三 - 练习

三六&#xff1a;风筝效果 <!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 采用了什么设计模式?

答案是采用了原型模式。原型模式的好处在于方便地拷贝某个实例的属性进行使用、又不会对原实例造成影响&#xff0c;其逻辑在于对 Cloneable 接口的实现。 话不多说看下 Intent 的关键源码&#xff1a; // frameworks/base/core/java/android/content/Intent.java public cla…...

Java数据类型与变量

个人主页&#xff1a;平行线也会相交 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 平行线也会相交 原创 收录于专栏【JavaSE_primary】 文章目录字面常量数据类型变量整型变量字节型变量浮点数变量双精度浮点数单精度浮点数字符型变量布尔型变量空常量nu…...

Python为CANoe工程添加/删除DBC文件

前面文章我们对于通过COM来实现打开CANoe、导入CANoe配置工程、导入执行文件、启动CANoe软件和执行脚本;但是这只能完成最基本的功能调用,在实际得到使用过程中,特别是各家在推的CI/CD以及平台化,仅仅是实现这些功能是完全不够用的;比如dbc的添加和删除,这是我们非常必要…...

不同的产品经理特征和需要的能力

产品经理是一个管家&#xff0c;需要和各方沟通推动产品各个决策进展。 每天早上看看线上用户数据、看下今天要安排任务&#xff0c;接着就是和各方开会讨论推动产品实现。每天穿插于与 UI、用户以及完成自己的 todolist 中循环。如果公司体制完善&#xff0c;还要和运营、数据…...

webpack之处理样式资源

处理样式资源 本章节我们学习使用 Webpack 如何处理 Css、Less、Sass、Scss、Styl 样式资源 #介绍 Webpack 本身是不能识别样式资源的&#xff0c;所以我们需要借助 Loader 来帮助 Webpack 解析样式资源 我们找 Loader 都应该去官方文档中找到对应的 Loader&#xff0c;然后…...

Golang 接口笔记

基本介绍接口是一个数据类型&#xff0c;可以定义一组方法&#xff0c;但都不需要实现。并且interface中不能包含任何变量。到某个自定义类型要使用的时候&#xff0c;再根据具体情况把这些方法实现出来语法type 接口名 interface {method1(参数列表) 返回值列表method2(参数列…...

[计算机网络(第八版)]第二章 物理层(章节测试/章节作业)

章节作业 带答案版 选择题 (单选题)双绞线是用两根绝缘导线绞合而成的&#xff0c;绞合的目的是&#xff08; &#xff09;。 A. 减少干扰 B. 提高传输速度 C. 增大传输距离 D. 增大抗拉强度(单选题)在电缆中采用屏蔽技术可以带来的好处主要是&#xff08; &#xff09;。 A…...

[iOS 理解] Swift Runtime (1) 类

Warm up 先看一段代码&#xff1a; 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参数&#xff1a; 型号&#xff1a;20N06 漏极-源极电压&#xff08;VDS&#xff09;&#xff1a;60V 栅源电压&#xff08;VGS&#xff09;&#xff1a;20V 漏极电流&#xff08;ID&#xff09;&#xff1a;20A 功耗&#xff08;PD&#xff0…...

常见前端基础面试题(HTML,CSS,JS)(四)

作用域和作用域链的理解 作用域 &#xff08;1&#xff09;全局作用域 最外层函数和最外层函数外面定义的变量拥有全局作用域所有未定义直接赋值的变量自动声明为全局作用域所有window对象的属性拥有全局作用域全局作用域有很大的弊端&#xff0c;过多的全局作用域变量会污染…...

RabbitMQ发布确认模式

目录 一、发布确认原理 二、发布确认的策略 &#xff08;一&#xff09;开启发布确认的方法 &#xff08;二&#xff09;单个确认模式 &#xff08;三&#xff09;批量确认模式 &#xff08;四&#xff09;异步确认模式 &#xff08;五&#xff09;如何处理异步未确认消…...

零基础的人如何入门 Python ?看完这篇文章你就懂了

第一部分&#xff1a;编程环境准备 零基础入门Python的话我不建议用IDE&#xff0c;IDE叫集成开发环境&#xff0c;这东西一般是专业程序员用来实战开发用的&#xff0c;好处很多&#xff0c;比如&#xff1a;调试、语法高亮、项目管理、代码跳转、智能提示、自动完成、单元测…...

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接口自动化中&#xff0c;我们常常需要依赖多个接口&#xff0c;A接口依赖B&#xff0c;C&#xff0c;D接口的响应作为请求参数&#xff1b;或者URL中的参数是从其他接口中提取返回值作获取参数这是必不可少的。那么怎么实现呢&#xff1f;下面就来介绍多业务依赖…...

JUC 之 CompletableFuture

——CompletableFuture Future Future 接口&#xff08;FutureTask 实现类&#xff09; 定义了操作异步任务执行的一些方法&#xff0c;如获取异步的执行结果、取消任务的执行、判断任务是否被取消、判断任务执行是否完毕例如&#xff1a; 主线程让一个子线程去执行任务&…...

Opencv中的addweighted函数

一.addweighted函数作用 addweighted&#xff08;&#xff09;是OpenCV库中用于图像处理的函数&#xff0c;主要功能是将两个输入图像&#xff08;尺寸和类型相同&#xff09;按照指定的权重进行加权叠加&#xff08;图像融合&#xff09;&#xff0c;并添加一个标量值&#x…...

深入理解JavaScript设计模式之单例模式

目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式&#xff08;Singleton Pattern&#…...

cf2117E

原题链接&#xff1a;https://codeforces.com/contest/2117/problem/E 题目背景&#xff1a; 给定两个数组a,b&#xff0c;可以执行多次以下操作&#xff1a;选择 i (1 < i < n - 1)&#xff0c;并设置 或&#xff0c;也可以在执行上述操作前执行一次删除任意 和 。求…...

三体问题详解

从物理学角度&#xff0c;三体问题之所以不稳定&#xff0c;是因为三个天体在万有引力作用下相互作用&#xff0c;形成一个非线性耦合系统。我们可以从牛顿经典力学出发&#xff0c;列出具体的运动方程&#xff0c;并说明为何这个系统本质上是混沌的&#xff0c;无法得到一般解…...

微信小程序云开发平台MySQL的连接方式

注&#xff1a;微信小程序云开发平台指的是腾讯云开发 先给结论&#xff1a;微信小程序云开发平台的MySQL&#xff0c;无法通过获取数据库连接信息的方式进行连接&#xff0c;连接只能通过云开发的SDK连接&#xff0c;具体要参考官方文档&#xff1a; 为什么&#xff1f; 因为…...

汇编常见指令

汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX&#xff08;不访问内存&#xff09;XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用

1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...

Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)

参考官方文档&#xff1a;https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java&#xff08;供 Kotlin 使用&#xff09; 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...

稳定币的深度剖析与展望

一、引言 在当今数字化浪潮席卷全球的时代&#xff0c;加密货币作为一种新兴的金融现象&#xff0c;正以前所未有的速度改变着我们对传统货币和金融体系的认知。然而&#xff0c;加密货币市场的高度波动性却成为了其广泛应用和普及的一大障碍。在这样的背景下&#xff0c;稳定…...

如何在网页里填写 PDF 表格?

有时候&#xff0c;你可能希望用户能在你的网站上填写 PDF 表单。然而&#xff0c;这件事并不简单&#xff0c;因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件&#xff0c;但原生并不支持编辑或填写它们。更糟的是&#xff0c;如果你想收集表单数据&#xff…...