初识FreeRTOS入门,对FreeRTOS简介、任务调度、内存管理、通信机制以及IO操作,控制两个led不同频率闪烁
当代嵌入式系统的开发越来越复杂,实时性要求也越来越高。为了满足这些需求,开发者需要使用实时操作系统(RTOS),其中一个流行的选择是FreeRTOS(Free Real-Time Operating System)。本篇博客将详细介绍FreeRTOS的特性、任务调度、内存管理、通信机制以及一些示例代码。
文章目录
- 1. FreeRTOS简介
- 2. 任务调度
- 3. 内存管理
- 4. 通信机制
- 5. IO操作
- 总结
1. FreeRTOS简介
FreeRTOS是一个开源的实时操作系统,专门设计用于嵌入式系统。它提供了一套任务调度、内存管理、中断处理和通信机制,使开发者能够更方便地开发实时应用程序。FreeRTOS具有以下特点:
- 开源免费:FreeRTOS遵循GNU通用公共许可证(GPL)的开源协议,可以免费使用和修改。
- 简单轻量:FreeRTOS的内核非常小巧,适用于资源有限的嵌入式系统。
- 可移植性:FreeRTOS提供了可移植的API接口,可以在不同的处理器和开发环境中使用。
- 可裁剪性:FreeRTOS的内核和组件可以根据需求进行裁剪,以减少内存占用和代码大小。
2. 任务调度
FreeRTOS的核心是任务调度器(Task Scheduler),它负责按照一定的调度策略将任务分配给处理器执行。每个任务都是一个独立的函数,可以有不同的优先级和堆栈大小。任务调度器根据任务的优先级和调度策略决定哪个任务被执行。
下面是一个简单的示例代码,展示了如何在FreeRTOS中创建和调度任务:
#include "FreeRTOS.h"
#include "task.h"// 任务1的函数
void vTask1(void *pvParameters)
{while (1){// 任务1的代码}
}// 任务2的函数
void vTask2(void *pvParameters)
{while (1){// 任务2的代码}
}int main()
{// 创建任务1xTaskCreate(vTask1, "Task 1", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 1, NULL);// 创建任务2xTaskCreate(vTask2, "Task 2", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 1, NULL);// 启动任务调度器vTaskStartScheduler();return 0;
}
以上代码中,通过调用xTaskCreate
函数创建了两个任务vTask1
和vTask2
。任务函数中的代码会被不断执行,不需要显式地进行任务调度。在main
函数中,通过调用vTaskStartScheduler
函数启动了任务调度器,使得任务可以被调度执行。
3. 内存管理
FreeRTOS提供了一套内存管理机制,用于动态分配和释放任务堆栈和其他资源。开发者可以使用FreeRTOS提供的内存分配函数,如pvPortMalloc
和vPortFree
,来管理内存。
下面是一个示例代码,展示了如何使用FreeRTOS的内存管理函数:
#include "FreeRTOS.h"
#include "task.h"// 任务的堆栈大小
#define TASK_STACK_SIZE 128// 任务的优先级
#define TASK_PRIORITY 1int main()
{// 创建任务的堆栈StackType_t *taskStack = (StackType_t *)pvPortMalloc(TASK_STACK_SIZE * sizeof(StackType_t));// 创建任务xTaskCreate(vTask, "Task", TASK_STACK_SIZE, NULL, TASK_PRIORITY, NULL);// 启动任务调度器vTaskStartScheduler();// 释放任务的堆栈vPortFree(taskStack);return 0;
}
以上代码中,通过调用pvPortMalloc
函数动态分配了任务的堆栈空间,然后通过调用vTaskCreate
函数创建了任务。在任务执行完毕后,通过调用vPortFree
函数释放任务的堆栈空间。
4. 通信机制
FreeRTOS提供了多种通信机制,如信号量、消息队列和事件组,用于实现任务间的通信和同步。
下面是一个示例代码,展示了如何使用FreeRTOS的信号量来实现任务间的同步:
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"// 信号量
SemaphoreHandle_t xSemaphore;// 任务1的函数
void vTask1(void *pvParameters)
{while (1){// 等待信号量xSemaphoreTake(xSemaphore, portMAX_DELAY);// 任务1的代码// 发送信号量xSemaphoreGive(xSemaphore);}
}// 任务2的函数
void vTask2(void *pvParameters)
{while (1){// 等待信号量xSemaphoreTake(xSemaphore, portMAX_DELAY);// 任务2的代码// 发送信号量xSemaphoreGive(xSemaphore);}
}int main()
{// 创建信号量xSemaphore = xSemaphoreCreateBinary();// 创建任务1xTaskCreate(vTask1, "Task 1", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 1, NULL);// 创建任务2xTaskCreate(vTask2, "Task 2", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 1, NULL);// 启动任务调度器vTaskStartScheduler();// 删除信号量vSemaphoreDelete(xSemaphore);return 0;
}
以上代码中,通过调用xSemaphoreCreateBinary
函数创建了一个二值信号量。任务1和任务2在执行前都会等待信号量,当某个任务执行完毕后,通过调用xSemaphoreGive
函数发送信号量,使得另一个任务可以执行。
5. IO操作
任务:使用freertos进行基于stm32的两个任务控制,一个任务是pa0口控制一个led灯每500ms闪烁一次,另一个任务是pa1口控制一个led灯每1s闪烁一次
#include "stm32f4xx.h"
#include "FreeRTOS.h"
#include "task.h"// 定义任务句柄
TaskHandle_t task1Handle, task2Handle;// 定义任务1的函数
void Task1(void *pvParameters)
{while(1){// 控制PA0口的LED灯每500ms闪烁一次GPIO_ToggleBits(GPIOA, GPIO_Pin_0);vTaskDelay(pdMS_TO_TICKS(500));}
}// 定义任务2的函数
void Task2(void *pvParameters)
{while(1){// 控制PA1口的LED灯每1s闪烁一次GPIO_ToggleBits(GPIOA, GPIO_Pin_1);vTaskDelay(pdMS_TO_TICKS(1000));}
}int main()
{// 初始化GPIOA的时钟RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; // 输出模式GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; // 推挽输出GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; // 无上下拉GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 速度50MHz// 初始化GPIOA的PA0和PA1口GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;GPIO_Init(GPIOA, &GPIO_InitStructure);// 创建任务1xTaskCreate(Task1, "Task1", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 1, &task1Handle);// 创建任务2xTaskCreate(Task2, "Task2", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 1, &task2Handle);// 启动任务调度器vTaskStartScheduler();while(1){// 如果任务调度器启动失败,可以在此处处理异常情况}return 0;
}
以上示例代码中,首先使用STM32的库函数RCC_AHB1PeriphClockCmd
和GPIO_InitTypeDef
初始化GPIO
引脚PA0
和PA1
的设置。然后,在任务1和任务2函数中分别控制PA0口和PA1口的LED灯闪烁,通过调用vTaskDelay
函数来实现延时。
在main函数中,使用xTaskCreate
函数创建任务1和任务2,并分别传入相应的函数指针、任务名称、堆栈大小和优先级。然后通过调用vTaskStartScheduler
函数启动任务调度器。
总结
本篇博客详细介绍了FreeRTOS的特性、任务调度、内存管理、通信机制和举例对STM32的IO口进行操作。
FreeRTOS的源代码和文档可以在官方网站(https://www.freertos.org/)上找到。
相关文章:
初识FreeRTOS入门,对FreeRTOS简介、任务调度、内存管理、通信机制以及IO操作,控制两个led不同频率闪烁
当代嵌入式系统的开发越来越复杂,实时性要求也越来越高。为了满足这些需求,开发者需要使用实时操作系统(RTOS),其中一个流行的选择是FreeRTOS(Free Real-Time Operating System)。本篇博客将详细…...

STM32CUBUMX配置FLASH(W25Q128)--保姆级教程
———————————————————————————————————— ⏩ 大家好哇!我是小光,嵌入式爱好者,一个想要成为系统架构师的大三学生。 ⏩最近在开发一个STM32H723ZGT6的板子,使用STM32CUBEMX做了很多驱动&#x…...

【Golang 接口自动化04】 解析接口返回JSON串
目录 前言 解析到结构体 json数据与struct字段是如何相匹配的呢? 解析到interface Go类型和JSON类型 实例代码 simpleJson 总结 资料获取方法 前言 上一次我们一起学习了如何解析接口返回的XML数据,这一次我们一起来学习JSON的解析方法。 JSO…...
EPPlus与Microsoft.Office.Interop.Excel的使用区别
文章目录 代码的使用区别EPPlus的工作原理Microsoft.Office.Interop.Excel的使用原理代码的使用区别 static void ExportToExcel(List<(string, double, double)> list, string outputFilePath){//Microsoft.Office.Interop.Excel的使用 /* Excel.Application excelAp…...
ncrack工具使用说明
介绍 网络认证破解工具。 Ncrack是用于网络身份验证破解的开源工具。 它设计为使用可适应不同网络情况的动态引擎进行高速并行破解。 Ncrack还可以针对特殊情况进行广泛的微调,尽管默认参数的通用性足以覆盖几乎所有情况。 它建立在模块化架构上,可以轻松扩展以支持其他协议…...
第二章:进程管理(处理机/CPU管理)
文章目录 2.1 进程与线程1.进程(1)进程的概念、进程的组成、进程的组织(2)进程控制块PCB(3)进程的状态与转换:五状态模型(4)进程控制(5)进程间的通信①共享存储②消息传递③管道通信(6)父进程与子进程(7)进程的内存空间2.线程 Thread(1)线程的概念(2)线程的实现方式:用户级线…...

MySQL中锁的简介——表级锁-元数据锁、意向锁
1.元数据锁 查看元数据锁 select object_type,object_scheme,object_name,lock_type,lock_duration from perfomance_scheme.metadata_locks;2.意向锁 线程A开启事务后在执行update更新语句时候,会给数据加上行锁,加上行锁以后,会对整张表加…...
React几种避免子组件无效刷新的方案
您好,如果喜欢我的文章,可以关注我的公众号「量子前端」,将不定期关注推送前端好文~ 前言 一个很常见的场景,React中父组件和子组件在一起,子组件不依赖于父组件任何数据,但是会一起发生变化。 在探究原…...

分享亿款好用的PDF编辑工具
所周知,PDF文件是不能够像word/excel/ppt等文件一样,可以被随意编辑的,PDF文件往往只能够被查看,我们无法对它进行编辑,或者对上面的文字进行复制,也不能任意删除上面的页面。但是很多时候,我们…...

AI生成式视频技术来临:Runway Gen-2文本生成视频
Runway Gen-2的官方网站提供了一种文本生成视频的工具。以下是对该工具的介绍: 文本生成视频:Runway Gen-2是一个创新的在线工具,可以将文本转化为视频。用户只需输入文本描述或句子,Runway Gen-2就能自动生成相应的视频内容。这…...
react钩子函数
React组件的生命周期包括多个阶段和方法,用于在组件不同的生命周期时执行特定的操作。以下是React类组件中常见的生命周期方法: 挂载阶段(Mounting Phase): constructor:组件实例化时调用,用于初…...

RISC-V公测平台发布 · 如何在SG2042上玩转k3s
前言 Kubernetes是一个开源的容器管理平台,通过Kubernetes的跨集群管理功能,用户可以方便地进行应用程序的复制、迁移和跨云平台的部署。 而k3s作为Kubernetes的轻量级发行版,相比传统的Kubernetes具有更小的二进制文件大小和更低的资源消耗…...

Linux系统常见小问题
1、新系统在输入命令时,不会自动提示,按上箭头(↑)和下向下箭头(↓)不会匹配之前的输入 以CentOS 为例,可以通过配置 ~/.bashrc 文件来实现按向上箭头显示最相近的命令。以下是具体的实现步骤 …...

WEB:mfw
背景知识 Git泄露 Githack使用 命令执行漏洞 题目 这里页面里有Git,猜测是Git泄露 先用dirsearch扫一下 确实存在.git目录,可以尝试访问一下 使用Githack来下载并恢复.git文件 这里记得使用的时候关闭杀毒软件 结果会自动保存 点进去先看一下flag这个…...

2.4 传统经验光照模型详解
一、光照模型 光照模型(illumination model),也称为明暗模型,用于计算物体某点处的光强(颜色值)。从算法理论基础而言,光照模型分为两类:一种是基于物理理论的,另一种是…...

基于高通QCC5171的对讲机音频数据传输系统设计
一 研发资料准备 二 设计方法 蓝牙连接与配对:使用QCC5171的蓝牙功能,实现设备之间的蓝牙连接和配对。确保设备能够相互识别并建立起稳定的蓝牙连接。 音频采集与处理:将麦克风采集到的音频数据通过QCC5171的ADC(模数转换器&…...
【题解】判断链表中是否有环、链表中环的入口结点
文章目录 判断链表中是否有环链表中环的入口结点 判断链表中是否有环 题目链接:判断链表中是否有环 解题思路1:快慢指针 代码如下: bool hasCycle(ListNode *head) {if(head nullptr) return false;ListNode* fast head;ListNode* slow …...

Pytorch 最全入门介绍,Pytorch入门看这一篇就够了
本文通过详细且实践性的方式介绍了 PyTorch 的使用,包括环境安装、基础知识、张量操作、自动求导机制、神经网络创建、数据处理、模型训练、测试以及模型的保存和加载。 1. Pytorch简介 在这一部分,我们将会对Pytorch做一个简单的介绍,包括它…...
Lambda 表达式的作用域
在Lambda表达式中访问外层作用域和旧版本的匿名对象中的方式类似。你可以直接访问标记了final的外层局部变量,或者实例的字段以及静态变量。 Lambda表达式不会从超类(supertype)中继承任何变量名,也不会引入一个新的作用域。Lambd…...

【portswigger】第二专题-XSS(二)
portswigger 靶场(第二章节)XSS 视频同步更新至bilibili bibi地址 【【portswigger】第二专题-XSS(一前置知识)】 https://www.bilibili.com/video/BV1mp4y157xA/?share_sourcecopy_web 【【portswigger】第二专题-XSSÿ…...

VB.net复制Ntag213卡写入UID
本示例使用的发卡器:https://item.taobao.com/item.htm?ftt&id615391857885 一、读取旧Ntag卡的UID和数据 Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click轻松读卡技术支持:网站:Dim i, j As IntegerDim cardidhex, …...

Zustand 状态管理库:极简而强大的解决方案
Zustand 是一个轻量级、快速和可扩展的状态管理库,特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...

【力扣数据库知识手册笔记】索引
索引 索引的优缺点 优点1. 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度(创建索引的主要原因)。3. 可以加速表和表之间的连接,实现数据的参考完整性。4. 可以在查询过程中,…...

【机器视觉】单目测距——运动结构恢复
ps:图是随便找的,为了凑个封面 前言 在前面对光流法进行进一步改进,希望将2D光流推广至3D场景流时,发现2D转3D过程中存在尺度歧义问题,需要补全摄像头拍摄图像中缺失的深度信息,否则解空间不收敛…...

剑指offer20_链表中环的入口节点
链表中环的入口节点 给定一个链表,若其中包含环,则输出环的入口节点。 若其中不包含环,则输出null。 数据范围 节点 val 值取值范围 [ 1 , 1000 ] [1,1000] [1,1000]。 节点 val 值各不相同。 链表长度 [ 0 , 500 ] [0,500] [0,500]。 …...

Psychopy音频的使用
Psychopy音频的使用 本文主要解决以下问题: 指定音频引擎与设备;播放音频文件 本文所使用的环境: Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...
什么是EULA和DPA
文章目录 EULA(End User License Agreement)DPA(Data Protection Agreement)一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA(End User License Agreement) 定义: EULA即…...

自然语言处理——循环神经网络
自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元(GRU)长短期记忆神经网络(LSTM)…...

Java面试专项一-准备篇
一、企业简历筛选规则 一般企业的简历筛选流程:首先由HR先筛选一部分简历后,在将简历给到对应的项目负责人后再进行下一步的操作。 HR如何筛选简历 例如:Boss直聘(招聘方平台) 直接按照条件进行筛选 例如:…...
《C++ 模板》
目录 函数模板 类模板 非类型模板参数 模板特化 函数模板特化 类模板的特化 模板,就像一个模具,里面可以将不同类型的材料做成一个形状,其分为函数模板和类模板。 函数模板 函数模板可以简化函数重载的代码。格式:templa…...