FreeRTOS中osDelay和HAL_Delay的区别

news2024/11/28 10:51:32

aa8a4f13710fd1618d5eec3d61b2594b.png

问题场景

在FreeRTOS中创建了线程A、线程B,其中线程A优先级大于线程B。线程A、B任务代码如下:

void A(void *argument)
{
  while (1)
  {
    printf("A\r\n");
    HAL_Delay(1000);
  }
}

void B(void *argument)
{
  while (1)
  {
    printf("B\r\n");
    HAL_Delay(1000);
  }
}

烧录程序后查看串口数据发现只打印了A而不打印B,说明只执行了A线程没有执行B线程。

问题原因

HAL_Delay是由ST提供的STM32 Cube HAL库中的一个函数,通常用于在STM32微控制器上实现简单的延时。HAL_Delay函数使用系统时钟来进行延时,并且在延时期间会阻塞整个处理器,也就是说,它会使处理器暂时停止执行其他任务和代码。

在开始运行线程之前,线程A、B处于就绪态,由于线程A优先级比线程B高,FreeRTOS任务控制器优先选择线程A运行,此时线程A进入运行态。随后线程A打印A,然后被HAL_Delay函数"阻塞",注意此时的"阻塞"并不意味着程序进入了阻塞态,由于HAL_Delay阻塞的是整个处理器,因此FreeRTOS无法进行其他线程的调度,也就是说,HAL_Delay同时阻塞了线程B。当HAL_Delay函数运行结束后,线程A重回就绪态,由于线程A优先级比线程B高,FreeRTOS任务控制器优先选择线程A运行,循环往复,线程B不被执行。


解决办法

osDelay是FreeRTOS(Real-Time Operating System)中的一个函数,用于实现任务的延时。FreeRTOS是一个开源的实时操作系统,专门用于嵌入式系统。osDelay函数允许任务挂起一段时间,然后由操作系统调度器在指定的时间后重新运行该任务。在等待期间,任务会被放入挂起状态,让其他任务有机会运行。

也就是说,当调用osDelay时,线程A进入阻塞态,此时任务控制器选择进入就绪态的线程B执行,循环往复,线程A、B同时被执行。我们可以将任务A和B进行如下改动,即可看到既打印A又打印B。

void A(void *argument)
{
  while (1)
  {
    printf("A\r\n");
    osDelay(1000);
  }
}

void B(void *argument)
{
  while (1)
  {
    printf("B\r\n");
    osDelay(1000);
  }
}


使用osDelay可能带来的问题

观察一下HAL_Delay和osDelay的函数原型:

/**
  * @brief This function provides minimum delay (in milliseconds) based
  */
__weak void HAL_Delay(uint32_t Delay);

/*
  Wait for Timeout (Time Delay).
*/
osStatus_t osDelay (uint32_t ticks);

可以看到HAL_Delay函数的目的是提供毫秒级别的延时,意味着当你输入HAL_Delay(500),硬件会尽量延时精确到500ms的时间。

与之不同的是,osDelay函数的输入是ticks。ticks是一个计时单位,表示任务将被挂起的时间长度。每个tick的时间取决于FreeRTOS配置的时钟节拍(tick)周期。例如,如果tick周期为1毫秒,那么传递参数ticks为10就会使任务挂起10毫秒。由此可见,osDelay函数延时的时间和一个ticks记时时间长度有很大关系。

那么如何确定ticks具体代表多长时间呢?首先我们应该找到用于配置的头文件,通常这个头文件名字叫做FreeRTOSConfig.h。其中,configTICK_RATE_HZ配置选项的值表示每秒钟系统时钟节拍(tick)的数量。configTICK_RATE_HZ的值一般默认被设置为1000,表示系统时钟每秒产生1000个tick,即每个tick的时间间隔为1毫秒,此时osDelay对单个任务延时的时间长度和HAL_Delay近似。

==========

往期回顾:

STM32中断,看着一篇就够了

STM32CubeMX介绍

【蓝桥杯单片机】第二章 软件安装

【蓝桥杯单片机】第一章 大赛概述

【蓝桥杯嵌入式】第九章 PWM

==========

3fac1cbcfcc3d5a0751ce52cc8ff14bf.png

aa182fa3ec2d89ca9e5483a18090b6ca.png

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

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

相关文章

基于springboot实现校园疫情防控系统项目【项目源码+论文说明】计算机毕业设计

基于springboot实现校园疫情防控系统演示 摘要 随着信息技术和网络技术的飞速发展,人类已进入全新信息化时代,传统管理技术已无法高效,便捷地管理信息。为了迎合时代需求,优化管理效率,各种各样的管理系统应运而生&am…

回溯法(1)--装载问题和0-1背包

一、回溯法 回溯法采用DFS+剪枝的方式,通过剪枝删掉不满足条件的树,提高本身作为穷举搜索的效率。 回溯法一般有子集树和排列树两种方式,下面的装载问题和01背包问题属于子集树的范畴。 解空间类型: 子集树&#xff1…

【C++项目】高并发内存池第七讲性能分析

目录 1.测试代码2.代码介绍3.运行结结果 1.测试代码 #include"ConcurrentAlloc.h" #include"ObjectPool.h" #include"Common.h" void BenchmarkMalloc(size_t ntimes, size_t nworks, size_t rounds) {std::vector<std::thread> vthread(…

超强Redis基础学习 优化 使用 常见问题

问题大纲 为什么Redis可以这么快&#xff1f; 它是纯内存操作&#xff0c;内存本身就很快 其次&#xff0c;它是单线程的&#xff0c;Redis服务器核心是基于非阻塞的IO多路复用机制&#xff0c;单线程避免了多线程的频繁上下文切换问题 Redis的持久化机制 Redis提供了持久化…

会声会影2024输出文件太大什么原因 会声会影输出文件处于保护状态什么原因

会声会影2024是一款专业的视频编辑软件&#xff0c;它由于简单易学的操作被众人所喜爱。在会声会影中编辑好的视频一般以渲染的形式导出保存&#xff0c;但是有时会出现输出文件太大的情况&#xff0c;这到底是什么原因呢&#xff1f;下面由我带大家一起来了解会声会影输出文件…

git本地搭建服务器[Vmware虚拟机访问window的git服务器]

先按照https://zhuanlan.zhihu.com/p/494988089说明下载好Gitblit然后复制到tomcat的webapps目录下,如下: 双击"startup.bat"启动tomcat: 然后访问"http://127.0.0.1:8080/gitblit/"即可看到git的界面: 说明git服务器已经能够成功运行了! Vmware虚拟机…

机器学习(五)如何理解机器学习三要素

1.8如何理解机器学习三要素 统计学习模型策略算法 模型&#xff1a;规律yaxb 策略&#xff1a;什么样的模型是好的模型&#xff1f;损失函数 算法&#xff1a;如何高效找到最优参数&#xff0c;模型中的参数a和b 1.8.1模型 机器学习中&#xff0c;首先要考虑学习什么样的…

5G 3GPP全球频谱介绍

所谓 “频谱”&#xff0c;是指特定类型的无线通信所在的射频范围。不同的无线技术使用不同的频谱&#xff0c;因此互不干扰。由于一项技术的频谱是有限的&#xff0c;因此频谱空间存在大量竞争&#xff0c;并且人们也在不断开发和增强全新的、高效率的频谱使用方式。 介绍5G …

ConcurrentHashMap 的 size()方法是线程安全的吗?为什么

ConcurrentHashMap 的 size()方法是非线程安全的。也就是说&#xff0c;当有线程调用 put 方法在添加元素的时候&#xff0c;其他线程在调用 size()方法获取的元素个数和实际存储元素个数是不一致的。原因是 size()方法是一个非同步方法&#xff0c;put()方法和 size()方法并没…

获取某个抖音用户的视频列表信息

思路 确定url确定并获取相关参数构造header发送请求解析数据输出数据 运行结果 代码 import requests # 获取某个用户的的视频信息&#xff0c;截至20231028&#xff0c;程序可以正常运行。 # 构造请求头header headers {User-Agent:..........................,Cookie:...…

10分钟了解JWT令牌 (JSON Web)

10分钟了解JSON Web令牌&#xff08;JWT&#xff09; JSON Web Token&#xff08;JWT&#xff09;是目前最流行的跨域身份验证解决方案。今天给大家介绍JWT的原理和用法。 1.跨域身份验证 Internet服务无法与用户身份验证分开。一般过程如下。 1.用户向服务器发送用户名和密码。…

IOC课程整理-12 Spring 国际化

1. Spring 国际化使用场景 2. Spring 国际化接口 3. 层次性 MessageSource 4. Java 国际化标准实现 5. Java 文本格式化 6. MessageSource 开箱即用实现 7. MessageSource 內建依赖 8. 课外资料 9. 面试题精选 Spring 国际化接口有哪些&#xff1f; • 核心接口 - MessageSour…

Linux操作系统 - 从概念上认识进程

目录 前置知识 冯诺依曼和现代计算机结构 操作系统的理解 进程的概念 进程和PCB 查看进程信息的指令 - ps 进程的一些特性 进程标识符 - PID 进程状态 进程状态的概念 Linux下的进程状态 父子进程 子进程的创建 - fork 僵尸进程 孤儿进程 进程切换 CPU上下文切…

PLC案例集合

这里写自定义目录标题 按时断电一次性按钮震荡电路上升沿和下降沿红绿灯案例抢答器未完待续 下载程序时&#xff0c;必须将PLC处于停机状态&#xff08;STOP&#xff09; 重新下载程序后&#xff0c;M会保持上一次程序中的状态。 所以&#xff0c;程序开始前要对中继进行复位 …

Windows查看核心与线程数

文章目录 前言一、可视化界面1、任务管理器2、设备管理器3、CPU-Z 二、命令或程序1、cmd命令2、Java程序 前言 查询电脑硬件CPU信息命令的学习&#xff0c;予以记录&#xff01; 参考博客&#xff1a;https://blog.csdn.net/huazicomeon/article/details/53540852 一、可视化界…

【计算机网络笔记】Web缓存/代理服务器技术

系列文章目录 什么是计算机网络&#xff1f; 什么是网络协议&#xff1f; 计算机网络的结构 数据交换之电路交换 数据交换之报文交换和分组交换 分组交换 vs 电路交换 计算机网络性能&#xff08;1&#xff09;——速率、带宽、延迟 计算机网络性能&#xff08;2&#xff09;…

echarts 按需加载处理

下载内容 npm install echarts --save按需封装组件 // 引入 echarts 核心模块&#xff0c;核心模块提供了 echarts 使用必须要的接口。 import * as echarts from echarts/core; import echarts/lib/component/legend// 引入柱状图图表&#xff0c;图表后缀都为 Chart // 引入…

HarmonyOS鸿蒙原生应用开发设计- 图标库

HarmonyOS设计文档中&#xff0c;为大家提供了独特的图标库&#xff0c;开发者可以根据需要直接引用。 图标库可以分为双色图标、填充图标、线性图标。具体分为 键盘、箭头、连接状态、媒体、人、设备、索引、通信、文件、物体与工具等。 整体分类 开发者直接使用官方提供的图标…

杂牌行车记录仪mp4恢复案例

行车记录仪是一种常见的视频采集设备&#xff0c;随着国内汽车市场的疯涨而普及&#xff0c;基本上每个车上都有&#xff0c;这一类记录仪有的是主机厂自带的&#xff08;如特斯拉&#xff09;&#xff0c;但更多的是第三方厂商生产的独立的记录仪。下面我们看一个小厂商的记录…

测开 (性能测试)

目录 前言 1、性能测试和功能测试的区别 2、性能好与不好的表现 3、性能测试衡量指标 && 名称解释 指标一&#xff1a;并发用户数 指标二&#xff1a;响应时间 / 平均响应时间 指标三&#xff1a;事务 指标四&#xff1a;点击率&#xff08;Hit Per Second&…