FreeRTOS 延时函数和软件定时器 详解

news2024/11/18 0:17:20

目录

什么是延时函数?

1.延时函数分类

2.vTaskDelay 与 HAL_Delay 的区别

什么是定时器?

1.软件定时器优缺点

2.软件定时器原理

3.软件定时器相关配置

4.单次定时器和周期定时器

软件定时器相关 API 函数

1. 创建软件定时器

2. 开启软件定时器

3. 停止软件定时器

4. 复位软件定时器

5. 更改软件定时器定时时间

延时函数和软件定时器实操


什么是延时函数?

延时函数是一种编程语言中常用的函数类型,用于暂停一段时间后再执行后续的操作。在延时函数执行期间,程序会暂停执行,直到指定的时间结束后才会继续执行后续代码。常见的延时函数参数是毫秒或微秒,可以控制真实时间和计算机时间的关系。延时函数常用于需要等待或暂停执行的场景,如控制程序运行速度、动画效果等。

不过,过度使用延时函数可能会影响程序的性能和响应速度。

1.延时函数分类

相对延时:vTaskDelay

绝对延时:vTaskDelayUntil

2.vTaskDelay 与 HAL_Delay 的区别

vTaskDelay 作用是让任务阻塞,任务阻塞后,RTOS系统调用其它处于就绪状态的优先级最高的任 务来执行。

HAL_Delay 一直不停的调用获取系统时间的函数,直到指定的时间流逝然后退出,故其占用了全 部CPU时间。

什么是定时器?

简单可以理解为闹钟,到达指定一段时间后,就会响铃。

STM32 芯片自带硬件定时器,精度较高,达到定时时间后会触发中断,也可以生成 PWM 、输入 捕获、输出比较,等等,功能强大,但是由于硬件的限制,个数有限。

软件定时器也可以实现定时功能,达到定时时间后可调用回调函数,可以在回调函数里处理信 息。

1.软件定时器优缺点

优点:

1. 简单、成本低;

2. 只要内存足够,可创建多个;

缺点:

精度较低,容易受中断影响。在大多数情况下够用,但对于精度要求比较高的场合不建议使用。

2.软件定时器原理

定时器是一个可选的、不属于 FreeRTOS 内核的功能,它是由定时器服务任务来提供的。

在调用函数 vTaskStartScheduler() 开启任务调度器的时候,会创建一个用于管理软件定时器的任 务,这个任务就叫做软件定时器服务任务。

1. 负责软件定时器超时的逻辑判断

2. 调用超时软件定时器的超时回调函数

3. 处理软件定时器命令队列

FreeRTOS提供了很多定时器有关的API函数,这些API函数大多都使用FreeRTOS的队列发送命令给 定时器服务任务。这个队列叫做定时器命令队列。定时器命令队列是提供给FreeRTOS的软件定时 器使用的,用户不能直接访问!

3.软件定时器相关配置

软件定时器有一个定时器服务任务和定时器命令队列,这两个东西肯定是要配置的,相关的配置 也是放到文件FreeRTOSConfig.h中的,涉及到的配置如下:

1、configUSE_TIMERS

如果要使用软件定时器的话宏configUSE_TIMERS一定要设置为1,当设置为1的话定时器服务任务 就会在启动FreeRTOS调度器的时候自动创建。

2、configTIMER_TASK_PRIORITY

设置软件定时器服务任务的任务优先级,可以为0~(configMAX_PRIORITIES-1)。优先级一定要根 据实际的应用要求来设置。如果定时器服务任务的优先级设置的高的话,定时器命令队列中的命 令和定时器回调函数就会及时的得到处理。

3、configTIMER_QUEUE_LENGTH

此宏用来设置定时器命令队列的队列长度。

4、configTIMER_TASK_STACK_DEPTH

此宏用来设置定时器服务任务的任务堆栈大小。

4.单次定时器和周期定时器

单次定时器: 只超时一次,调用一次回调函数。可手动再开启定时器;

周期定时器: 多次超时,多次调用回调函数。

软件定时器相关 API 函数

                                函数                                描述
xTimerCreate()动态方式创建软件定时器
xTimerCreateStatic()静态方式创建软件定时器
xTimerStart()开启软件定时器定时
xTimerStop()停止软件定时器定时
xTimerReset()复位软件定时器定时
xTimerChangePeriod()更改软件定时器的定时超时时间
xTimerStartFromISR()在中断中开启软件定时器定时
xTimerStopFromISR()在中断中停止软件定时器定时
xTimerResetFromISR()在中断中复位软件定时器定时
xTimerChangePeriodFromISR()在中断中更改定时超时时间

1. 创建软件定时器

TimerHandle_t xTimerCreate
            (   const char * const pcTimerName,
                const TickType_t xTimerPeriod,
                const UBaseType_t uxAutoReload,
                void * const pvTimerID,
                TimerCallbackFunction_t pxCallbackFunction );

参数:

  • pcTimerName:软件定时器名称
  • xTimerPeriodInTicks:定时超时时间,单位:系统时钟节拍。宏 pdMS_TO_TICKS() 可用于将以毫秒为单位指定的时间转换为以 tick 为单位指定的时间。
  • uxAutoReload:定时器模式, pdTRUE:周期定时器, pdFALSE:单次定时器
  • pvTimerID:软件 定时器 ID,用于多个软件定时器公用一个超时回调函数
  • pxCallbackFunction:软件定时器超时回调函数

返回值:

  • 成功:定时器句柄
  • 失败:NULL

2. 开启软件定时器

BaseType_t xTimerStart( TimerHandle_t xTimer,
                        TickType_t xBlockTime );

参数:

  • xTimer:待开启的软件定时器的句柄
  • xTickToWait:发送命令到软件定时器命令队列的最大等待时间

返回值:

  • pdPASS:开启成功
  • pdFAIL:开启失败

3. 停止软件定时器

BaseType_t xTimerStop( TimerHandle_t xTimer,
                        TickType_t xBlockTime );

参数与返回值同上。

4. 复位软件定时器

BaseType_t xTimerReset( TimerHandle_t xTimer,
                        TickType_t xBlockTime );

参数与返回值同上。

该功能将使软件定时器的重新开启定时,复位后的软件定时器以复位时的时刻作为开启时刻重新 定时。

5. 更改软件定时器定时时间

BaseType_t xTimerChangePeriod( TimerHandle_t xTimer,
                                TickType_t xNewPeriod,
                                TickType_t xBlockTime );

xNewPeriod:新的定时超时时间,单位:系统时钟节拍。

其余参数与返回值同上。

延时函数和软件定时器实操

创建两个定时器:

定时器1,周期定时器,每1秒打印一次 zglnb

定时器2,单次定时器,启动后 2 秒打印一次 ljx666

打开CubeMX

1.将FreeRTOS移植到STM32F103C8T6,具体看我之前写过的文章

将FreeRTOS移植到STM32F103C8T6

2.使能定时器

3.创建两个定时器

4.代码示例:

void StartDefaultTask(void const * argument)
{
    // xTimerChangePeriod(myTimer01Handle, pdMS_TO_TICKS(1000), 0); // 官方函数
    osTimerStart(myTimer01Handle, 1000);
    osTimerStart(myTimer02Handle, 2000);
  for(;;)
  {

    osDelay(1);
  }
}

void Callback01(void const * argument)
{
	printf("周期定时器:zglnb\r\n");
}

void Callback02(void const * argument)
{
	printf("单次定时器:ljx666\r\n");
}

5.打开串口助手,查看结果

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

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

相关文章

C++STL----list的使用

文章目录 list简介list的使用默认成员函数的使用list容器元素的修改front和backpush_front和pop_frontpush_back和pop_backinserterase list迭代器begin和endrbegin和rend list大小控制resizeclear list操作函数sortspliceremoveremove_ifuniquemergereverseassign CSTL----lis…

CloudFlare系列--使用第三方来自定义CDN的IP(笨牛详细版)

原文网址:CloudFlare系列--使用第三方来自定义CDN的IP(笨牛详细版)_IT利刃出鞘的博客-CSDN博客 简介 本文介绍如何使用自定义节点来提高CloudFlare的CDN节点的访问速度。 CloudFlare的CDN很强大,可以防DDos等攻击,也可以提高国外服务器的访…

假如我有一台服务器,我会让它提供三种服务

一、提供照片上传、存储和下载服务 随着移动互联网时代的持续快速发展,PC互联网日益势微,各大互联网门户网站的博客、空间也跟着凋零, 作为博客、空间的标配功能的相册也随之被关闭。 2019年3月6日网易相册发布停运公告并于当年5月8日正式停…

网络安全—小白自学

1.网络安全是什么 网络安全可以基于攻击和防御视角来分类,我们经常听到的 “红队”、“渗透测试” 等就是研究攻击技术,而“蓝队”、“安全运营”、“安全运维”则研究防御技术。 2.网络安全市场 一、是市场需求量高; 二、则是发展相对成熟…

yo!这里是进程间通信

目录 前言 进程间通信简介 目的 分类 匿名通道 介绍 举例(进程池) 命名管道 介绍 举例 共享内存 介绍 共享内存函数 1.shmget 2.shmat 3.shmdt 4.shmctl 举例 1.框架 2.通信逻辑 消息队列 信号量 同步与互斥 理解信号量 后记…

漫谈广告机制设计 | 混排:广告与自然结果的交锋博弈(2)

话说前文,在彼此不同的利益面前,自然侧和广告侧在混排战场展开了一番较量,一个浑水摸鱼,一个暗渡陈仓。最终双方不得不坐下来,为了平台整体的利益,一起谈谈各自的诉求,商讨一下解决方案。 第三…

安装虚拟机(VMware)保姆级教程及配置虚拟网络编辑器和安装WindowsServer以及宿主机访问虚拟机和配置服务器环境

目录 一、操作系统 1.1.什么是操作系统 1.2.常见操作系统 1.3.个人版本和服务器版本的区别 1.4.Linux的各个版本 二、VMware Wworkstation Pro虚拟机的安装 1.下载与安装 注意:VMWare虚拟网卡 2.配置虚拟网络编辑器 三、安装配置 WindowsServer 1.创建虚拟…

讲述为什么要学习Adobe XD以及 Adobe XD下载安装

首先 我们要了解 Adobe XD 是个什么东西 XD是Adobe公司专门开发出来面向交互、界面设计的矢量绘图工具。 然后是 他可以做什么? 最基本的 可以做UI界面设置 所有 手机 平板 电脑等设备的UI界面 我们都可以通过XD完成 还有就是原型设置 我们可以做各种界面图 还有…

寄存器、CPU缓存、内存。以及他们之间的关系

寄存器 CPU寄存器是CPU内部的高速存储区域,用于临时存储数据和指令。寄存器是CPU的重要组成部分,用于提高程序的执行效率。它们比主存储器更快,可以使得CPU更有效地处理数据和执行指令。 寄存器可以分为不同类型,下面列出部分AR…

用baostock库获取上证50成分股

最近知道了baostock库,免费,开源(www.baostock.com) 用来试试看。获取上证50成分股: import baostock as bs import pandas as pd# 登陆系统 lg bs.login() # 显示登陆返回信息 print(login respond error_code:lg.…

Docker 镜像读写层核心概念:rootfs、Union mount、image以及layser原理详解

Docker 镜像读写层核心概念:rootfs、Union mount、image以及layser原理详解 文章目录 Docker 镜像读写层核心概念:rootfs、Union mount、image以及layser原理详解rootfsUnion mount为什么镜像层都是只读的去掉读写层的话会有什么问题 Docker镜像imageDoc…

LVS-keepalived实现高可用

概念: 本章核心: Keepalived为LVS应运而生的高可用服务。LVS的调度无法做高可用,预算keepalived这个软件,实现了调度器的高可用。 但是:Keeplived不是专门为LVS集群服务的,也可以做其他服务器的高可用 LVS…

Vue进阶(幺陆玖)项目部署后IE报 SCRIPT1002:语法错误 解决方案探讨

文章目录 一、前言二、组件懒加载2.1 什么是懒加载2.2 如何实现懒加载 三、延伸阅读 软件程序唤醒3.1 protocolCheck 实现3.2 自定义实现 四、拓展阅读 一、前言 Vue项目改造升级后,原本本地热部署后IE可正常打开的项目出现页面白屏且控制台给出SCRIPT1002:语法错误…

电动两轮车智能化浪潮崛起,移远通信以全场景解决方案引领户外出行新变革

凭借受众广泛、使用方便等优势,电动两轮出行越来越走俏,成为通勤、校园、景区等场景的不二之选。而随着物联网新技术的采用,智能化两轮车能为骑行者带来更多样化、更舒适的驾驶和交互体验,也成为“Z世代”的扮靓利器和出游好伙伴。…

【LeetCode每日一题合集】2023.10.16-2023.10.22(只出现一次的数字Ⅲ)

文章目录 260. 只出现一次的数字 III⭐(异或)🐂2652. 倍数求和解法1——枚举模拟解法2—— O ( 1 ) O(1) O(1)容斥原理相似题目——1201. 丑数 III(二分查找容斥原理) 2530. 执行 K 次操作后的最大分数解法1——贪心优…

机器学习——代价敏感错误率与代价曲线

文章目录 代价敏感错误率实现代价曲线例子 代价敏感错误率 指在分类问题中,不同类别的错误分类所造成的代价不同。在某些应用场景下,不同类别的错误分类可能会产生不同的代价。例如,在医学诊断中,将疾病患者错误地分类为健康人可…

区块链技术的未来:去中心化应用和NFT的崛起

区块链技术正在以前所未有的速度改变着金融和数字资产领域。它的演进为去中心化应用和非替代性代币(NFT)的崛起提供了坚实的基础。在本文中,我们将深入探讨这一数字革命的关键方面,从区块链的基本原理到它如何改变金融领域&#x…

修改svc的LoadBalancer的IP引发的惨案

文章目录 背景修改externalIPs的操作api-server报错日志挽救教训 背景 k8s集群没有接外部负载均衡,部署istio的时候ingressgateway一直pending。 于是手动修改了这个lb svc的externalIP,于是k8s就崩了,如何崩的,且听我还道来。 …

Redis(03)| 数据结构-链表

大家最熟悉的数据结构除了数组之外,我相信就是链表了。 Redis 的 List 对象的底层实现之一就是链表。C 语言本身没有链表这个数据结构的,所以 Redis 自己设计了一个链表数据结构。 链表节点结构设计 先来看看「链表节点」结构的样子: type…

ReentrantLock 的实现原理

ReentrantLock ReentrantLock 是一种可重入的排它锁,主要用来解决多线程对共享资源竞争的问题。它的核心特性有几个: 它支持可重入,也就是获得锁的线程在释放锁之前再次去竞争同一把锁的时候,不需要加锁就可以直接访问。它支持公…