FreeRTOS 时间管理和定时器

FreeRTOS 是一个开源的实时操作系统,提供了丰富的时间管理和定时器功能,用于实现任务调度、延时等操作。在本文中,我们将深入探讨 FreeRTOS 的时间管理和定时器相关的内容。

时间管理

FreeRTOS 提供了以下几种与时间相关的管理功能:

1. vTaskDelay函数

vTaskDelay 函数用于使任务进入阻塞状态,以实现延时功能。延时的时间以 FreeRTOS 的时钟节拍(tick)为单位。

#include "FreeRTOS.h"
#include "task.h"void vTaskFunction(void *pvParameters)
{// 任务执行的代码vTaskDelay(pdMS_TO_TICKS(1000));  // 延时 1000 毫秒
}

2. vTaskDelayUntil 函数

vTaskDelayUntil 函数用于设置任务的周期性执行,它在指定的绝对时间执行任务,而不是相对于当前时间的相对延时。

#include "FreeRTOS.h"
#include "task.h"void vTaskFunction(void *pvParameters)
{TickType_t xLastWakeTime = xTaskGetTickCount();for (;;){// 任务执行的代码// 等待下一个周期vTaskDelayUntil(&xLastWakeTime, pdMS_TO_TICKS(1000));}
}

3. 获取系统时间

xTaskGetTickCount 函数用于获取系统自启动以来的时钟节拍数,以及 xTaskGetTickCountFromISR 用于中断服务例程中获取时钟节拍数。

#include "FreeRTOS.h"
#include "task.h"void vTaskFunction(void *pvParameters)
{TickType_t currentTickCount = xTaskGetTickCount();// 执行任务代码
}

xTaskGetTickCountFromISR 是 FreeRTOS 提供的一个用于在中断服务例程(ISR,Interrupt Service Routine)中获取系统时钟节拍数的函数。由于在中断上下文中,一些 FreeRTOS API 是不允许使用的,因此需要使用特定的 ISR 版本的函数来执行相应的操作。

函数原型:

TickType_t xTaskGetTickCountFromISR(void);
  • 返回值: 当前的系统时钟节拍数(以 TickType_t 类型表示)。

示例代码

下面是一个简单的示例,演示了如何在中断服务例程中使用 xTaskGetTickCountFromISR 函数:

#include "FreeRTOS.h"
#include "task.h"
#include "stdio.h"// 模拟一个中断服务例程
void vISRFunction(void)
{BaseType_t xHigherPriorityTaskWoken = pdFALSE;// 获取当前的系统时钟节拍数TickType_t currentTickCount = xTaskGetTickCountFromISR();// 执行中断服务例程的操作// 通知等待的任务发生了事件vTaskNotifyGiveFromISR(/*任务句柄*/, &xHigherPriorityTaskWoken);// 如果有任务的优先级高于当前运行的任务,需进行任务切换portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}void vTaskFunction(void *pvParameters)
{for (;;){// 等待中断服务例程通知ulTaskNotifyTake(pdTRUE, portMAX_DELAY);// 任务执行的代码printf("Task is running. Current tick count: %lu\n", xTaskGetTickCount());}
}int main(void)
{// 创建任务xTaskCreate(vTaskFunction, "Task", 1000, NULL, 1, NULL);// 模拟中断服务例程定期触发for (;;){vISRFunction();// 模拟中断的周期vTaskDelay(pdMS_TO_TICKS(1000));}return 0;
}

在上述示例中,vISRFunction 模拟一个中断服务例程,其中使用了 xTaskGetTickCountFromISR 函数来获取当前系统时钟节拍数。随后,通过 vTaskNotifyGiveFromISR 函数通知等待的任务发生了事件,并通过 portYIELD_FROM_ISR 判断是否需要进行任务切换。

请注意,在实际中断服务例程中,应该谨慎使用 FreeRTOS API,并根据实际情况选择是否需要任务切换。在某些情况下,可能需要在中断服务例程中延迟任务的执行,以避免破坏实时性。

定时器

FreeRTOS 提供了定时器作为一种更灵活的时间管理工具,可以用于周期性执行任务或在一段时间后触发事件。

1. 创建定时器

使用 xTimerCreate 函数创建定时器,并指定回调函数。

#include "FreeRTOS.h"
#include "timers.h"void vTimerCallback(TimerHandle_t xTimer)
{// 定时器回调函数,执行相应操作
}void vTaskFunction(void *pvParameters)
{TimerHandle_t xTimer = xTimerCreate("MyTimer",               // 定时器名称pdMS_TO_TICKS(1000),     // 周期为 1000 毫秒pdTRUE,                  // 自动重载NULL,                    // 定时器IDvTimerCallback);         // 回调函数if (xTimer != NULL){// 启动定时器xTimerStart(xTimer, 0);}// 任务执行的代码
}

2. 定时器示例

下面是一个完整的示例,演示了如何使用 FreeRTOS 定时器。

#include "FreeRTOS.h"
#include "timers.h"
#include "task.h"void vTimerCallback(TimerHandle_t xTimer)
{// 定时器回调函数,执行相应操作printf("Timer expired!\n");
}void vTaskFunction(void *pvParameters)
{TimerHandle_t xTimer = xTimerCreate("MyTimer",               // 定时器名称pdMS_TO_TICKS(1000),     // 周期为 1000 毫秒pdTRUE,                  // 自动重载NULL,                    // 定时器IDvTimerCallback);         // 回调函数if (xTimer != NULL){// 启动定时器xTimerStart(xTimer, 0);for (;;){// 任务执行的代码}}
}int main(void)
{xTaskCreate(vTaskFunction, "Task", 1000, NULL, 1, NULL);vTaskStartScheduler();return 0;
}

在这个示例中,创建了一个名为 “MyTimer” 的定时器,每隔 1000 毫秒触发一次回调函数 vTimerCallback。回调函数中输出 “Timer expired!”。任务函数中启动了定时器,并进入一个无限循环的任务执行代码。

以上是 FreeRTOS 的时间管理和定时器相关内容的简要介绍。通过使用这些功能,可以更加灵活地管理任务的执行时间和周期性任务的触发。在实际项目中,合理利用时间管理和定时器功能将对系统的稳定性和实时性产生积极影响。

项目实例

假设我们正在开发一个嵌入式系统,这个系统负责控制智能家居中的温度和湿度监控。我们需要定期采集传感器数据,更新显示,以及根据设定的温度阈值触发相应的控制操作。在这个项目中,时钟和定时器将起到关键作用。

1. 系统初始化

首先,在系统初始化阶段,我们需要初始化 FreeRTOS 时钟节拍和创建定时器。

#include "FreeRTOS.h"
#include "task.h"
#include "timers.h"// 定义任务和定时器句柄
TaskHandle_t xTaskHandle;
TimerHandle_t xTimerHandle;// 任务函数
void vTemperatureTask(void *pvParameters);// 定时器回调函数
void vTimerCallback(TimerHandle_t xTimer);int main(void)
{// 创建任务xTaskCreate(vTemperatureTask, "TemperatureTask", 1000, NULL, 1, &xTaskHandle);// 创建定时器,每隔1秒触发一次回调函数xTimerHandle = xTimerCreate("SensorTimer", pdMS_TO_TICKS(1000), pdTRUE, (void *)0, vTimerCallback);// 启动定时器if (xTimerHandle != NULL){xTimerStart(xTimerHandle, 0);}// 启动任务调度器vTaskStartScheduler();return 0;
}

2. 温度任务

温度任务周期性地采集传感器数据,并更新显示。

#include "FreeRTOS.h"
#include "task.h"void vTemperatureTask(void *pvParameters)
{for (;;){// 采集传感器数据float temperature = readTemperatureSensor();// 更新显示updateDisplay(temperature);// 等待下一个周期vTaskDelay(pdMS_TO_TICKS(5000)); // 5秒周期}
}

3. 定时器回调函数

定时器回调函数用于检查温度是否超过设定的阈值,并触发相应的控制操作。

#include "FreeRTOS.h"
#include "timers.h"void vTimerCallback(TimerHandle_t xTimer)
{// 读取当前温度float currentTemperature = readTemperatureSensor();// 检查是否超过设定的阈值if (currentTemperature > TEMPERATURE_THRESHOLD){// 执行控制操作,例如打开风扇或空调controlTemperature(currentTemperature);}
}

通过这个示例,我们展示了在一个智能家居温控系统中如何利用 FreeRTOS 的时钟和定时器功能。温度任务定期采集传感器数据,而定时器回调函数则用于实时监测温度并触发相应的控制操作。这种基于时钟和定时器的任务调度方式可以确保系统按照预定的周期执行任务,提高系统的实时性和可靠性。

公众号 | FunIO
微信搜一搜 “funio”,发现更多精彩内容。
个人博客 | blog.boringhex.top

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

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

相关文章

【C++高阶(八)】单例模式特殊类的设计

💓博主CSDN主页:杭电码农-NEO💓   ⏩专栏分类:C从入门到精通⏪   🚚代码仓库:NEO的学习日记🚚   🌹关注我🫵带你学习C   🔝🔝 单例模式 1. 前言2. 设计一个不能被拷贝/继承的…

SVN搭建指导

环境 centos 7.9 SVN安装方式一:yum 1.1 http服务 至今还没有搞定网页版,网页版需要搭建apache http服务。遇到如下问题: centos - svn: Could not open the requested SVN filesystem - Stack Overflow 在试了加777权限,加a…

c语言:指针作为参数传递

探究实参与形参它们相互独立 由于主调函数的变量a,b与被调函数的形参x,y它们相互独立。函数 swap 可以修改变量x,y,但是却无法影响到主调函数中的a,b。 现在利用取地址运算符,分别打印它们的首地址&#x…

生物识别规划人脸识别方案的概述

方案概述 人脸识别方案采用高性能AI芯片,支持RGB和IR摄像头, 支持LCD显示屏。方案特点 • 普通RGB摄像头和IR摄像头同时参与3D成像RGB摄像头 支持屏幕回显 • 双目摄像头得到特征点视差计算人脸相 对3D深度信息, 同时利用可见光和红外 光谱信…

Axure RP 8 for Mac/win中文版:打造完美交互式原型设计体验

Axure RP 8,一款引领潮流的交互式原型设计工具,为设计师提供了无限的可能性,让他们能够创造出逼真的原型,从而更好地展示和测试他们的设计。 Axure RP 8拥有丰富的功能和工具,让设计师可以轻松地创建出复杂的交互式原…

SQLite数据库的增删改查

一、前言 这篇文章主要针对Android自带的轻量级数据库SQLite 实现增删改查。该数据库常用于本地数据的储存喝管理。例如,可以将用户信息,日志数据等重要信息存储在SQLite数据库中。 二、代码实现 1.创建MySqliteOpenHelp作为工具类 /*** MySqliteOpen…

GSCoolink GSV1201E Type C/DP1.2转HDM1.4

DisplayPort 1.2 to HDMI 1.4 Converter with Embedded MCU 功能特征 1、GSV1201E是一款高性能、低功耗、USB Type-C Alternate Mode DisplayPort 1.2 to HDMI 1.4转换器。 2、显示接口接收器支持21.6Gbps(HBR2,4-lane)。 3、HDMI发射器支持9Gbps(TMDS3G3Lane)。…

Swagger2接口测试文档

目录 一、Swagger简介 1.1 Swagger是什么? 1.2 为什么要用Swagger 1.3 Swagger注解 二、Spring集成Swagger 三、测试环境配置 一、Swagger简介 1.1 Swagger是什么? Swagger是一款RESTFUL接口的文档在线自动生成功能测试功能软件。Swagger是一个规…

git如何修改提交代码时的名字和邮箱?

在Git中修改提交时使用的用户名和电子邮件地址,你可以通过配置全局或本地的Git配置文件来实现。全局配置适用于你系统上的所有Git仓库,而本地配置只适用于当前仓库。 修改全局用户名和邮箱 如果你想要更改全局的用户名和邮箱,你可以使用下面…

Linux之进程(五)(进程控制)

目录 一、进程创建 1、fork函数创建进程 2、fork函数的返回值 3、fork常规用法 4、fork调用失败的原因 二、进程终止 1、进程终止的方式 2、进程退出码 3、进程的退出方法 三、进程等待 1、进程等待的必要性 2、wait函数 3、waitpid函数 四、进程程序替换 1、概念…

armv8-a 介绍

ARMv8-A 是针对应用配置文件的最新一代 ARM 架构。现在包括32位执行状态和64位执行状态。ARMv8 引入了使用 64 位宽寄存器执行执行的能力,但提供了向后兼容机制以使现有 ARMv7 软件能够执行。 AArch64是用于描述 ARMv8 架构的 64 位执行状态的名称。AArch32描述了ARMv8架构的…

Android studio中导入opencv库

具体opencv库的导入流程参考链接:Android Studio开发之路 (五)导入OpenCV以及报错解决 一、出现的错误:NullPointerException: Cannot invoke “java.io.File.toPath()” because “this.mySdkLocation” is null 解决办法&#…

北斗卫星导航系统介绍

1.北斗卫星导航系统 1.1概述 北斗卫星导航系统(BeiDou(COMPASS)Navigation Satellite System)是中国正在实施的自主发展、独立运行的全球卫星导航系统。系统建设目标是:建成独立自主、开放兼容、技术先进、稳定可靠的…

java获取当前线程的上下文类加载器(context ClassLoader)

当前线程的上下文类加载器初始设置等于加载该应用的类加载器。 代码示例: package com.thb;public class Demo4 {public static void main(String[] args) {System.out.println(Thread.currentThread().getContextClassLoader());} }运行输出:

客户需求分析常用的ChatGPT通用提示词模板

客户需求调研:如何进行客户需求调研,获取准确的需求信息? 客户画像建立:如何建立客户画像,深入了解客户特征和需求? 痛点识别与解决:如何识别客户的痛点,并制定相应的解决方案&…

k8s 中部署Jenkins

创建namespace apiVersion: v1 kind: Namespace metadata:name: jenkins创建pv以及pvc kind: PersistentVolume apiVersion: v1 metadata:name: jenkins-pv-volumenamespace: jenkinslabels:type: localapp: jenkins spec:#storageClassName: manualcapacity:storage: 5Giacc…

提高Spring Boot技能的9种方法

以下是提高 Spring Boot 技能的 9 种方法: 1. 外部化您的配置: 充分利用 Spring Boot 潜力的另一种方法是尽可能地尝试外部化您的配置,而不是对其进行硬编码。外部化您的配置将使您的应用程序更加灵活且更易于管理。 外部化配置的另一个优点…

地质灾害监测预警解决方案

目录 1.前言 2.滑坡监测站建设方案 2.1建站方案 2.2监测指标体系 2.3监测设备配置 3.地面沉降监测建设方案 3.1建设方案 3.2监测指标体系 3.3监测设备配置 4.泥石流监测站建设方案 4.1建设方案 4.2监测指标体系 4.3监测设备配置 5.岩溶塌陷监测站方案 5.1建站方案…

利用openssl进行rsa加解密的例子

OpenSSL介绍 OpenSSL安装 https://blog.csdn.net/zhizhengguan/article/details/112846817 OpenSSL实例 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <openssl/rsa.h> #include <openssl/pem.h> #include <ope…

深入理解网络 I/O:FileOutputStream、BufferFileOutputStream、ByteBuffer

&#x1f52d; 嗨&#xff0c;您好 &#x1f44b; 我是 vnjohn&#xff0c;在互联网企业担任 Java 开发&#xff0c;CSDN 优质创作者 &#x1f4d6; 推荐专栏&#xff1a;Spring、MySQL、Nacos、Java&#xff0c;后续其他专栏会持续优化更新迭代 &#x1f332;文章所在专栏&…