初识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ÿ…...
[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解
突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 安全措施依赖问题 GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...

安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件
在选煤厂、化工厂、钢铁厂等过程生产型企业,其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进,需提前预防假检、错检、漏检,推动智慧生产运维系统数据的流动和现场赋能应用。同时,…...

理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端
🌟 什么是 MCP? 模型控制协议 (MCP) 是一种创新的协议,旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议,它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...
React Native在HarmonyOS 5.0阅读类应用开发中的实践
一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强,React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 (1)使用React Native…...

现代密码学 | 椭圆曲线密码学—附py代码
Elliptic Curve Cryptography 椭圆曲线密码学(ECC)是一种基于有限域上椭圆曲线数学特性的公钥加密技术。其核心原理涉及椭圆曲线的代数性质、离散对数问题以及有限域上的运算。 椭圆曲线密码学是多种数字签名算法的基础,例如椭圆曲线数字签…...

蓝桥杯3498 01串的熵
问题描述 对于一个长度为 23333333的 01 串, 如果其信息熵为 11625907.5798, 且 0 出现次数比 1 少, 那么这个 01 串中 0 出现了多少次? #include<iostream> #include<cmath> using namespace std;int n 23333333;int main() {//枚举 0 出现的次数//因…...

AI病理诊断七剑下天山,医疗未来触手可及
一、病理诊断困局:刀尖上的医学艺术 1.1 金标准背后的隐痛 病理诊断被誉为"诊断的诊断",医生需通过显微镜观察组织切片,在细胞迷宫中捕捉癌变信号。某省病理质控报告显示,基层医院误诊率达12%-15%,专家会诊…...

Linux 内存管理实战精讲:核心原理与面试常考点全解析
Linux 内存管理实战精讲:核心原理与面试常考点全解析 Linux 内核内存管理是系统设计中最复杂但也最核心的模块之一。它不仅支撑着虚拟内存机制、物理内存分配、进程隔离与资源复用,还直接决定系统运行的性能与稳定性。无论你是嵌入式开发者、内核调试工…...

宇树科技,改名了!
提到国内具身智能和机器人领域的代表企业,那宇树科技(Unitree)必须名列其榜。 最近,宇树科技的一项新变动消息在业界引发了不少关注和讨论,即: 宇树向其合作伙伴发布了一封公司名称变更函称,因…...
LangChain 中的文档加载器(Loader)与文本切分器(Splitter)详解《二》
🧠 LangChain 中 TextSplitter 的使用详解:从基础到进阶(附代码) 一、前言 在处理大规模文本数据时,特别是在构建知识库或进行大模型训练与推理时,文本切分(Text Splitting) 是一个…...