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

FreeRTOS入门基础

RTOS是为了更好地在嵌入式系统上实现多任务处理和时间敏感任务而设计的系统。它能确保任务在指定或预期的时间内得到处理。FreeRTOS是一款免费开源的RTOS,它广泛用于需要小型、预测性强、灵活系统的嵌入式设备。

创建第一个任务

  1. 任务函数:任务是通过函数来定义的。函数通常看起来像这样的无限循环
       void vTaskFunction( void * pvParameters ){for( ;; ){// 任务代码}}

  2. 创建任务:使用xTaskCreate()函数来创建一个任务。
       xTaskCreate(vTaskFunction,       // 任务函数"TaskName",          // 任务名称STACK_SIZE,          // 堆栈大小NULL,                // 参数TASK_PRIORITY,       // 任务优先级NULL );              // 用来传回创建的任务的句柄

  3. 启动调度器:创建任务后,需要启动调度器,这样RTOS就能开始管理这些任务了。
       vTaskStartScheduler();

freertos基本组件

FreeRTOS作为一个实时操作系统(RTOS),提供了多种基础组件来组织代码并有效地管理任务。以下是一些FreeRTOS的基本组件:

  1. 任务 (Tasks):

    • 任务是FreeRTOS中的基本执行单位,相当于一个独立的线程。每个任务都有自己的优先级,调度器根据这些优先级来决定运行哪个任务。
  2. 队列 (Queues):

    • 队列用于在任务之间发送和接收数据。它们可以帮助实现任务同步,并提供一种安全传递消息的方法,如事件、内存块等。
      #include "FreeRTOS.h"
      #include "queue.h"// 队列句柄,用于后续的队列操作如发送和接收
      QueueHandle_t xQueue;// main() 或者任何初始化函数中
      void main() {// 创建一个可以存储10个元素的队列,每个元素大小为sizeof( BaseType_t )xQueue = xQueueCreate(10, sizeof(BaseType_t));if (xQueue == NULL) {// 队列创建失败,可能是由于内存不足// 错误处理代码} else {// 队列成功创建// 可以继续使用队列}// ... 其余初始化代码 ...// 启动任务,开始调度器vTaskStartScheduler();// ... 其余代码 ...
      }

      在这个例子中:

    • xQueueCreate 函数的第一个参数(10)指定了队列能够存储的元素的数量。
    • 第二个参数(sizeof(BaseType_t))指定了队列中每个元素的大小。
    • 注意,在使用 xQueueCreate() 创建队列之前,必须确保已经调用了 vTaskStartScheduler(),因为队列的使用依赖于FreeRTOS的内存管理函数,它们在调度器启动时初始化。此外,创建队列通常在系统的初始化阶段进行,然后各个任务可以通过队列句柄进行数据的发送和接收。

       

      创建队列后,可以使用 xQueueSend()xQueueReceive() 等函数来在任务之间传递数据。如果队列创建成功,xQueueCreate() 将返回一个非NULL的 QueueHandle_t 句柄,用于后续的队列操作。如果内存不足或者有其他原因导致队列创建失败,则返回NULL。

  3. 信号量 (Semaphores):

    • 信号量是一种同步机制,可以用来控制对共享资源的访问,或者在任务之间同步操作。在FreeRTOS中有两种主要类型的信号量:二进制信号量和计数信号量。
      #include "FreeRTOS.h"
      #include "semphr.h"SemaphoreHandle_t xSemaphore = NULL;void main_demo( void )
      {// 二进制信号量创建xSemaphore = xSemaphoreCreateBinary();if (xSemaphore != NULL){// 信号量创建成功,可以被使用}else{// 信号量创建失败,处理错误情况}// ...// 后续代码,如启动调度器和任务等// ...
      }
      #include "FreeRTOS.h"
      #include "semphr.h"SemaphoreHandle_t xCountingSemaphore;void main_demo( void )
      {// 计数信号量创建,最大计数和初始计数xCountingSemaphore = xSemaphoreCreateCounting(maxCount, initialCount);if (xCountingSemaphore != NULL){// 信号量创建成功}else{// 信号量创建失败,处理错误情况}// ...// 后续代码,如启动调度器和任务等// ...
      }

      在计数信号量的创建中, maxCount 表示信号量能够达到的最大计数值,而 initialCount 是信号量的初始计数值。

       

      信号量通常用于同步任务或中断服务程序 (ISR),例如,保护共享资源,协调任务的执行,任务通知等。创建后的信号量句柄可以通过任务和中断服务程序进行给出 (Give) 和取得 (Take) 操作。

  4. 互斥量 (Mutexes):

    • 互斥量是特殊类型的信号量,专门用于管理资源访问。与二元信号量不同,互斥量具有所有权的概念,使其在处理优先级反转问题时更加有效。
  5. 定时器 (Timers):

    • 定时器可以在一个定义好的时间之后运行一个函数。FreeRTOS支持一次性定时器和周期性定时器。
      #include "FreeRTOS.h"
      #include "timers.h"TimerHandle_t xTimer;void vTimerCallback(TimerHandle_t xTimer)
      {// 这里处理定时器到期时的逻辑
      }void main_demo( void )
      {const TickType_t xTimerPeriod = pdMS_TO_TICKS( 1000 ); // 定时周期1000毫秒// 创建软件定时器xTimer = xTimerCreate("Timer",                // 定时器的文本名称,用于调试xTimerPeriod,           // 定时器的周期,以tick计数pdTRUE,                 // pdFALSE为单次定时器,pdTRUE为周期性定时器( void * ) 0,           // 可用于传递给回调函数的标识符,通常是NULLvTimerCallback          // 定时器到期时调用的回调函数);if (xTimer == NULL){// 定时器创建失败,可能是由于内存不足}else{// 定时器创建成功,可以启动定时器if (xTimerStart(xTimer, 0) != pdPASS){// 定时器启动失败}}// ...// 后续代码,如启动调度器和任务等// ...
      }

      在这个例子中:

    • 第一个参数("Timer")是定时器名称。
    • 第二个参数(xTimerPeriod)设置定时器周期,通过pdMS_TO_TICKS宏转换了毫秒到tick。
    • 第三个参数指定了定时器是单次的 (pdFALSE) 还是自动重载的周期性定时器 (pdTRUE)。
    •  

      定时器创建后,你需要调用xTimerStart()函数来启动定时器,此后定时器将按照设定的周期运行。在资源有限的嵌入式系统里,软件定时器是一种资源节约的实现定时功能的方式,因为你可以在一个定时服务中管理多个定时器,而无需为每个定时任务创建单独的线程。

    • 第四个参数是指针,它会被传递给定时器回调函数,可以用作计数器或存储状态信息。
    • 第五个参数是定时器到期时调用的回调函数。
  6. 事件组 (Event Groups):

    • 事件组是一种可以等待或设置一组事件标志的机制。这允许任务在多种事件中等待任意组合的事件。
      #include "FreeRTOS.h"
      #include "event_groups.h"EventGroupHandle_t xEventGroup;void main_demo( void )
      {// 创建事件组xEventGroup = xEventGroupCreate();if(xEventGroup == NULL){// 事件组创建失败,通常是因为内核没有足够的可用堆空间// 错误处理代码}else{// 事件组成功创建,可以使用xEventGroup来设置、清除和等待事件标志}// ...// 启动任务和调度器等// ...
      }

      在这个例子中,xEventGroupCreate 用于创建一个新的事件组,并返回一个 EventGroupHandle_t 类型的句柄,以供后续的事件组操作使用。如果事件组创建失败,则返回 NULL,通常是由于内存不足。

       

      成功创建事件组后,可以使用如下函数操作事件标志:

    • xEventGroupSetBits:设置事件组中的一个或多个事件标志。
    • xEventGroupClearBits:清除事件组中的一个或多个事件标志。
    • xEventGroupWaitBits:等待事件组中的一个或多个特定事件标志变为设置状态。
    • 事件组是处理多个任务和中断共享状态或事件同步时的一个非常有用的工具,能够以线程安全的方式进行复杂的事件标志操作。
  7. 任务通知 (Task Notifications):

    • 任务通知是一种轻量级的信号量替代方式,可以快速地向任务发送信号。
    • 发送任务通知

      // 取得需要通知的任务的句柄,可以在任务创建时获取
      TaskHandle_t xTaskToNotify = ...;// 发送通知给任务,'ulValue' 是通知值
      uint32_t ulValue = 10;
      BaseType_t xHigherPriorityTaskWoken = pdFALSE; // 仅在中断服务程序中使用// 任务级代码
      xTaskNotify(xTaskToNotify, ulValue, eSetValueWithOverwrite);// 或者在 ISR 中
      xTaskNotifyFromISR(xTaskToNotify, ulValue, eSetValueWithOverwrite, &xHigherPriorityTaskWoken);
      portYIELD_FROM_ISR( xHigherPriorityTaskWoken );

      在上面的代码中,xTaskToNotify 是要接收通知的任务的句柄。ulValue 是要发送的通知值。eSetValueWithOverwrite 指示即使之前的通知未被任务接收,也将覆盖通知值。

    • 等待任务通知

      // 该变量将接收通知值
      uint32_t ulNotificationValue;
      BaseType_t xResult;// 等待通知
      xResult = xTaskNotifyWait(0x00,          // 在进入等待时不清除任何位ULONG_MAX,     // 在退出等待时将清除所有位&ulNotificationValue,  // 存储接收到的通知值portMAX_DELAY); // 一直等待直到接收到通知if(xResult == pdPASS)
      {// 任务接收到通知,`ulNotificationValue` 包含收到的值
      }

      在上面的等待通知代码中,xTaskNotifyWait 第一个参数为零表示调用任务进入等待通知状态时,不清除任务的任何通知状态位。第二个参数 ULONG_MAX 表示调用任务在接收到通知时将清除任务的所有通知状态位。第四个参数是阻塞时间,这个例子中使用 portMAX_DELAY,任务会无限期地等待直到收到通知。

       

      通过 xTaskNotifyGive 和 ulTaskNotifyTake 的组合,任务通知机制也可以模仿二进制信号量的行为。任务通知作为一种轻量级的同步机制,在许多场合可以替代信号量和事件组,以节省系统资源。

资源地址

FreeRTOS - Market leading RTOS (Real Time Operating System) for embedded systems with Internet of Things extensions

 Free RTOS Book and Reference Manual

相关文章:

FreeRTOS入门基础

RTOS是为了更好地在嵌入式系统上实现多任务处理和时间敏感任务而设计的系统。它能确保任务在指定或预期的时间内得到处理。FreeRTOS是一款免费开源的RTOS,它广泛用于需要小型、预测性强、灵活系统的嵌入式设备。 创建第一个任务 任务函数:任务是通过函数…...

蓝桥杯-24点-搜索

题目 思路 --暴力递归全组合的方法。只有4个数,4种计算方式,共有4 * 3 * 2 * 1 * 4种不同的情况,可以写递归来实现。 --每次计算都是两个数之间的运算,因此4个数需要3次计算,第一次计算前有4个数,第二次有…...

【附下载】3Ds Max从安装、配置到入门提高和高级用法

#3Ds Max 一、安装 1.1 安装说明 地址:链接:https://pan.baidu.com/s/1lwKMbgbE32wCL6PpMv706A?pwddll8 提取码:dll8 –来自百度网盘超级会员V2的分享 安装说明:文件夹里有安装说明 安装解压即可 关键就是将crack文件放到自己…...

开源堡垒机Jumpserver

开源堡垒机Jumpserver 文章目录 开源堡垒机Jumpserver1 Jumpserver介绍2 Jumpserver部署用户管理资产创建账号管理模板添加 用户组管理权限管理远程连接免密连接 1 Jumpserver介绍 Jumpserver 是全球首款完全开源的堡垒机,使用 GNU GPL v2.0 开源协议,是…...

PyTorch学习笔记之基础函数篇(十五)

文章目录 数值比较运算8.1 torch.equal()函数8.2 torch.ge()函数8.3 torch.gt()函数8.4 torch.le()函数8.5 torch.lt()函数8.6 torch.ne()函数8.7 torch.sort()函数8.8 torch.topk()函数 数值比较运算 8.1 torch.equal()函数 torch.equal(tensor1, tensor2) -> bool这个函…...

Latex插入pdf图片,去除空白部分

目录 参考链接: 流程: 参考链接: ​科研锦囊之Latex-如何插入图片、表格、参考文献 http://t.csdnimg.cn/vpSJ3 流程: Latex的图片插入支持PDF文件,这里笔者建议都使用PDF文件进行图片的插入,因为PDF作…...

微服务:高并发带来的问题的容错方案

1.相关脚本(陈天狼) 启动nacos客户端: startup.cmd -m standalone 启动sentinel控制台: # 直接使⽤jar命令启动项⽬(控制台本身是⼀个SpringBoot项⽬) java -Dserver.port8080 -Dcsp.sentinel.dashboard.serverlocalhost:808…...

sqllab第35-45关通关笔记

35关知识点: 宽字节注入数值型注入错误注入 payload:id1andextractvalue(1,concat(0x7e,database(),0x7e))0--联合注入 payload:id0unionselect1,database(),version()-- 36关知识点: 字符型注入宽字节注入错误注入 payload:id1%df%27andextractvalue(…...

Jenkins流水线将制品发布到Nexus存储库

1、安装jenkins(建议别用docker安装,坑太多) docker run -d -p 8089:8080 -p 10241:50000 -v /var/jenkins_workspace:/var/jenkins_home -v /etc/localtime:/etc/localtime --name my_jenkins --userroot jenkins/jenkins:2.449 坑1 打开x…...

信息学奥赛一本通之MAC端VSCode C++环境配置

前提 安装 Visual Studio CodeVSCode 中安装 C/C扩展确保 Clang 已经安装(在终端中输入命令:clang --version 来确认是否安装)未安装,在命令行执行xcode-select --install 命令,会自行安装,安装文件有点大…...

MPIKGC:大语言模型改进知识图谱补全

MPIKGC:大语言模型改进知识图谱补全 提出背景MPIKGC框架 论文:https://arxiv.org/pdf/2403.01972.pdf 代码:https://github.com/quqxui/MPIKGC 提出背景 知识图谱就像一个大数据库,里面有很多关于不同事物的信息,这…...

Flutter-自定义图片3D画廊

效果 需求 3D画廊效果 设计内容 StackGestureDetectorTransformPositioned数学三角函数 代码实现 具体代码大概300行 import dart:math;import package:flutter/material.dart; import package:flutter_xy/widgets/xy_app_bar.dart;import ../../r.dart;class ImageSwitc…...

python中如何解析Html

在最近需要的需求中,需要 python 获取网页内容,并从html中获取到想要的内容。这里记录一下两个比较常用的python库对html的解析。 1. BeautifulSoup 它是一个非常流行的python脚本库,用于解析HTML和XML文档。如果你对 java 很熟悉&#xff…...

Hystrix的原理及应用:构建微服务容错体系的利器(一)

本系列文章简介: 本系列文章旨在深入剖析Hystrix的原理及应用,帮助大家理解其如何在微服务容错体系中发挥关键作用。我们将从Hystrix的核心原理出发,探讨其隔离、熔断、降级等机制的实现原理;接着,我们将结合实际应用场…...

win10企业版LTSC可以识别鼠标,无法识别移动硬盘问题

1. USB控制器重置:在设备管理器中,展开"通用串行总线控制器"。右键点击每个USB控制器,选择"卸载设备"。完成后,重新启动计算机。操作系统将自动重新安装USB控制器驱动程序。这可能有助于解决与USB控制器相关的…...

[经验分享]OpenCV显示上一次调用的图片的处理方法

最近在研究OpenCV时发现,重复调用cv::imshow("frame", frame)时,会显示出上一次的图片。 网上搜索了方法,有以下3种因素可能导致: 1. 图像变量未正确更新:可能在更新 frame 变量之前就已经调用了 imshow。…...

NFS性能优化参考 —— 筑梦之路

CentOS 7 NFS服务优化的配置参考—— 筑梦之路_nfs 读取优化-CSDN博客 核心原则是减少客户端与服务端的交互次数,因此我们在访问文件的时候应该尽量保持文件的打开状态,避免重复打开关闭文件,这样NFS全路径的逐级检查。这种方法对NFSv4以后的…...

Vue3学习日记 Day4 —— pnpm,Eslint

注:此课程需要有Git的基础才能学习 一、pnpm包管理工具 1、使用原因 1.1、速度快,远胜过yarn和npm 1.2、节省磁盘空间 2、使用方式 2.1、安装方式 npm install -g pnpm 2.2、创建项目 pnpm create vue 二、Eslint配置代码风格 1、环境同步 1、禁用Pret…...

二叉树遍历(牛客网)

描述 编一个程序,读入用户输入的一串先序遍历字符串,根据此字符串建立一个二叉树(以指针方式存储)。 例如如下的先序遍历字符串: ABC##DE#G##F### 其中“#”表示的是空格,空格字符代表空树。建立起此二叉树…...

语音识别:whisper部署服务器(远程访问,语音实时识别文字)

Whisper是OpenAI于2022年发布的一个开源深度学习模型,专门用于语音识别任务。它能够将音频转换成文字,支持多种语言的识别,包括但不限于英语、中文、西班牙语等。Whisper模型的特点是它在多种不同的音频条件下(如不同的背景噪声水…...

Docker 运行 Kafka 带 SASL 认证教程

Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明:server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...

JVM垃圾回收机制全解析

Java虚拟机(JVM)中的垃圾收集器(Garbage Collector,简称GC)是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象,从而释放内存空间,避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...

Module Federation 和 Native Federation 的比较

前言 Module Federation 是 Webpack 5 引入的微前端架构方案,允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一)

宇树机器人多姿态起立控制强化学习框架论文解析 论文解读:交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一) 论文解读:交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化…...

【JavaSE】绘图与事件入门学习笔记

-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角,以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向,距离坐标原点x个像素;第二个是y坐标,表示当前位置为垂直方向,距离坐标原点y个像素。 坐标体系-像素 …...

全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比

目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...

.Net Framework 4/C# 关键字(非常用,持续更新...)

一、is 关键字 is 关键字用于检查对象是否于给定类型兼容,如果兼容将返回 true,如果不兼容则返回 false,在进行类型转换前,可以先使用 is 关键字判断对象是否与指定类型兼容,如果兼容才进行转换,这样的转换是安全的。 例如有:首先创建一个字符串对象,然后将字符串对象隐…...

C++课设:简易日历程序(支持传统节假日 + 二十四节气 + 个人纪念日管理)

名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 专栏介绍:《编程项目实战》 目录 一、为什么要开发一个日历程序?1. 深入理解时间算法2. 练习面向对象设计3. 学习数据结构应用二、核心算法深度解析…...

给网站添加live2d看板娘

给网站添加live2d看板娘 参考文献: stevenjoezhang/live2d-widget: 把萌萌哒的看板娘抱回家 (ノ≧∇≦)ノ | Live2D widget for web platformEikanya/Live2d-model: Live2d model collectionzenghongtu/live2d-model-assets 前言 网站环境如下,文章也主…...

【Elasticsearch】Elasticsearch 在大数据生态圈的地位 实践经验

Elasticsearch 在大数据生态圈的地位 & 实践经验 1.Elasticsearch 的优势1.1 Elasticsearch 解决的核心问题1.1.1 传统方案的短板1.1.2 Elasticsearch 的解决方案 1.2 与大数据组件的对比优势1.3 关键优势技术支撑1.4 Elasticsearch 的竞品1.4.1 全文搜索领域1.4.2 日志分析…...