FreeRTOS入门基础
RTOS是为了更好地在嵌入式系统上实现多任务处理和时间敏感任务而设计的系统。它能确保任务在指定或预期的时间内得到处理。FreeRTOS是一款免费开源的RTOS,它广泛用于需要小型、预测性强、灵活系统的嵌入式设备。
创建第一个任务
- 任务函数:任务是通过函数来定义的。函数通常看起来像这样的无限循环
void vTaskFunction( void * pvParameters ){for( ;; ){// 任务代码}} - 创建任务:使用
xTaskCreate()函数来创建一个任务。xTaskCreate(vTaskFunction, // 任务函数"TaskName", // 任务名称STACK_SIZE, // 堆栈大小NULL, // 参数TASK_PRIORITY, // 任务优先级NULL ); // 用来传回创建的任务的句柄 - 启动调度器:创建任务后,需要启动调度器,这样RTOS就能开始管理这些任务了。
vTaskStartScheduler();
freertos基本组件
FreeRTOS作为一个实时操作系统(RTOS),提供了多种基础组件来组织代码并有效地管理任务。以下是一些FreeRTOS的基本组件:
-
任务 (Tasks):
- 任务是FreeRTOS中的基本执行单位,相当于一个独立的线程。每个任务都有自己的优先级,调度器根据这些优先级来决定运行哪个任务。
-
队列 (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。
- 队列用于在任务之间发送和接收数据。它们可以帮助实现任务同步,并提供一种安全传递消息的方法,如事件、内存块等。
-
信号量 (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) 操作。
- 信号量是一种同步机制,可以用来控制对共享资源的访问,或者在任务之间同步操作。在FreeRTOS中有两种主要类型的信号量:二进制信号量和计数信号量。
-
互斥量 (Mutexes):
- 互斥量是特殊类型的信号量,专门用于管理资源访问。与二元信号量不同,互斥量具有所有权的概念,使其在处理优先级反转问题时更加有效。
-
定时器 (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()函数来启动定时器,此后定时器将按照设定的周期运行。在资源有限的嵌入式系统里,软件定时器是一种资源节约的实现定时功能的方式,因为你可以在一个定时服务中管理多个定时器,而无需为每个定时任务创建单独的线程。 - 第四个参数是指针,它会被传递给定时器回调函数,可以用作计数器或存储状态信息。
- 第五个参数是定时器到期时调用的回调函数。
- 定时器可以在一个定义好的时间之后运行一个函数。FreeRTOS支持一次性定时器和周期性定时器。
-
事件组 (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:等待事件组中的一个或多个特定事件标志变为设置状态。- 事件组是处理多个任务和中断共享状态或事件同步时的一个非常有用的工具,能够以线程安全的方式进行复杂的事件标志操作。
- 事件组是一种可以等待或设置一组事件标志的机制。这允许任务在多种事件中等待任意组合的事件。
-
任务通知 (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 很熟悉ÿ…...
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模型的特点是它在多种不同的音频条件下(如不同的背景噪声水…...
C#与Unity的协作协议:从语法表层到引擎契约的深度解析
1. 这不是“学编程”,而是重新建立你和机器对话的语法系统很多人点开这个标题,心里想的是:“Unity游戏开发?那我得先学会C#,再学Unity编辑器,最后做个小飞机打砖块……”——这个思路本身就把门关死了。我带…...
AI技术解析的底线:只拆解真实可验证的项目
我不能按照该标题生成相关内容。原因如下:标题中“TAI #200”指向的是“Technical AI Newsletter”(技术型AI通讯)第200期,属于特定小众专业社群的内部简报编号,非公开项目、非可复现技术实践、非通用技能型内容&#…...
索尼360 Reality Audio发展受阻,苹果携手杜比让空间音频成主流
索尼的行动与失察索尼在市场创新方面思路正确,利用个人音频业务融入技术,争取平台采用,吸引音乐家录制专辑,授权音频制造商。但没料到自己不会成为沉浸式音频未来的关键参与者,失误只因不是苹果。空间音频如何定义2010…...
微信小程序逆向工程深度解析:wxappUnpacker实用指南
微信小程序逆向工程深度解析:wxappUnpacker实用指南 【免费下载链接】wxappUnpacker forked from https://github.com/qwerty472123/wxappUnpacker 项目地址: https://gitcode.com/gh_mirrors/wxappu/wxappUnpacker 微信小程序逆向工程是移动应用安全研究的重…...
Java 零基础全套教程,数据结构与集合源码,笔记 168-174
Java 零基础全套教程,数据结构与集合源码,笔记 168-174 一、参考资料 【Java视频教程,java入门神器(附300道Java面试题剖析)】 https://www.bilibili.com/video/BV1PY411e7J6/?p168&share_sourcecopy_web&vd_…...
05-系统技术架构师必备——软件工程方法与UML建模体系
关键词:UML建模、Scrum、敏捷开发、软件测试、白盒测试、McCabe复杂度、瀑布模型、RUPUML 软件工程 敏捷开发 软件测试 Scrum RUP 系统架构 建模系统技术架构师必备——软件工程方法与UML建模体系 摘要 UML建模和软件工程方法是系统技术架构师与开发团队沟通的"…...
【Android】针灸大师-穴位解剖精准经络系统-医学生必备-会员版
【Android】针灸大师-穴位解剖精准经络系统-医学生必备-会员版 链接:https://pan.xunlei.com/s/VOtJd241jF6B-cTY3Gs64aacA1?pwdeynm# 针灸大师(Acupuncture master)将经络穴位与人体精细解剖相结合,是交互式学习十二经脉,奇经八脉,经络系统…...
Lindy流程冷启动死亡陷阱(97%新手踩中的第3个环节):实时检测+自动回滚机制详解
更多请点击: https://kaifayun.com 第一章:Lindy流程冷启动死亡陷阱的底层认知 Lindy效应在软件工程中并非仅适用于“越老越可靠”的技术寿命预测,它更深层地揭示了一种反直觉的系统演化规律:一个尚未被时间验证的流程࿰…...
戴森球计划蓝图架构范式:从模块化设计到星际规模工程的技术演进
戴森球计划蓝图架构范式:从模块化设计到星际规模工程的技术演进 【免费下载链接】FactoryBluePrints 游戏戴森球计划的**工厂**蓝图仓库 项目地址: https://gitcode.com/GitHub_Trending/fa/FactoryBluePrints 在戴森球计划的工厂建设中,蓝图设计…...
Postman登录接口响应为空?HTTP响应体未刷出的三层根因分析
1. 这不是Postman的问题,是接口通信链路上某个环节“失语”了你用Postman调后端登录接口,请求发出去了,状态码也回来了(比如200),但响应体里空空如也——没有JSON数据、没有token字段、甚至Response标签页里…...
