【STM32项目】在FreeRtos背景下的实战项目的实现过程(一)

news2024/11/15 19:48:46

在这里插入图片描述
个人主页~

这篇文章是我亲身经历的,在做完一个项目之后总结的经验,虽然我没有将整个项目给放出来,因为这项目确实也是花了米让导师指导的,但是这个过程对于STM32的实战项目开发都是非常好用的,可以说按照这个过程,在你熟悉各种外设的前提下,你可以不用受别人指导地进行一个项目,甚至完成自己的一个作品


实战项目的实现过程

  • 一、FreeRtos
    • 1、简介
    • 2、功能
      • (1)裸机开发
      • (2)基于Rtos的开发
    • 3、格式
      • (1)定义任务
      • (2)定义空闲任务
      • (3)main函数
      • (4)开始任务函数

一、FreeRtos

1、简介

Rtos就是实时操作系统,os的意思就像是我们常用的iOS、HamonyOS是一个意思,就是操作系统的意思,而FreeRtos就是免费的实时操作系统,在嵌入式系统中非常常用

它的底层代码是用C语言写成的,可移植性特别好,且简单易用,核心代码有9000多行

2、功能

(1)裸机开发

像STM32在开始学习的时候,我们的程序是一个main函数,里面的代码一行接着一行执行,非常单一,只要写好程序,程序就会按照既定的顺序执行,不会出现某一段代码先于前面几行的代码的情况,也就是实时性差,这叫做裸机开发也就是不带操作系统的开发,它常用于不需要高实时性的场景的产品开发

在delay函数下的等待只能等待,没有占用CPU的情况,浪费资源

(2)基于Rtos的开发

Rtos有很多种,除了FreeRtos以外,我们可以在浏览器上搜索其他的Rtos,但在所有嵌入式系统中,FreeRtos是应用最多的

添加了Rtos的嵌入式系统实时性会提高,我们可以将某些程序分为多个任务,给予它们优先级,优先级高的优先获得CPU使用权,也就是一个优先级低的任务执行过程中,优先级高的任务一旦出现需要执行的情况,优先级低的任务立刻发生中断,先让优先级高的任务完成,然后再回到原来的位置继续执行,而且这个过程是可以嵌套的,在优先级1的任务过程中,优先级2的任务可以中断优先级1的任务,然后优先级3的任务又可以中断优先级2的任务

多个任务可以同一优先级,创建的实时任务数量没有软件限制,也就是说,在理想条件下,创建的实时任务可以有无数个

在不断中断的过程中,嵌入式系统捕捉外界变化的能力变得十分灵敏,实时性有所提高

在delay函数下按照优先级的顺序使用CPU,确保CPU能在每个时间段都有事情可做,节省资源

3、格式

FreeRtos的配置过程可以直接看正点原子的视频教程,这里其实只要懂得基本原理即可,直接找一个现成的文件用就可以,实在想要自己做就跟着视频教程一步一步来搭建一个Rtos系统
在这里插入图片描述
我们这里就不讲怎么配置了,文本解释不清还占用篇幅

(1)定义任务

//任务优先级
#define START_TASK_PRIO		1
//任务堆栈大小
#define START_STK_SIZE 		128  
//任务堆栈
StackType_t StartTaskStack[START_STK_SIZE];
//任务控制块
StaticTask_t StartTaskTCB;
//任务句柄
TaskHandle_t StartTask_Handler;
//任务函数
void start_task(void *pvParameters);


//任务优先级
#define TASK1_TASK_PRIO		2
//任务堆栈大小
#define TASK1_STK_SIZE 		128  
//任务堆栈
StackType_t Task1TaskStack[TASK1_STK_SIZE];
//任务控制块
StaticTask_t Task1TaskTCB;
//任务句柄
TaskHandle_t Task1Task_Handler;
//任务函数
void task1_task(void *pvParameters);

//任务优先级
#define TASK2_TASK_PRIO		3
//任务堆栈大小
#define TASK2_STK_SIZE 		128  
//任务堆栈
StackType_t Task2TaskStack[TASK2_STK_SIZE];
//任务控制块
StaticTask_t Task2TaskTCB;
//任务句柄
TaskHandle_t Task2Task_Handler;
//任务函数
void task2_task(void *pvParameters);

开始任务start_task是必须要有的,然后按照一样的格式将任务1234等创建好,确定堆栈以及堆栈大小,控制块、句柄以及任务函数的声明

(2)定义空闲任务

//空闲任务堆栈
static StackType_t Idle_Task_Stack[configMINIMAL_STACK_SIZE];
//定时器任务堆栈
static StackType_t Timer_Task_Stack[configTIMER_TASK_STACK_DEPTH];

//空闲任务控制块
static StaticTask_t Idle_Task_TCB;	
//定时器任务控制块
static StaticTask_t Timer_Task_TCB;


//获取空闲任务的任务堆栈和任务控制块内存,因为本例程使用的是静态内存
//因此空闲任务的任务堆栈由用户来提供,接口函数就是下面这个函数

//ppxIdleTaskTCBBuffer:任务控制块内存
//ppxIdleTaskStackBuffer:任务堆栈内存
//pulIdleTaskStackSize:任务堆栈大小
void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer, 
								   StackType_t **ppxIdleTaskStackBuffer, 
								   uint32_t *pulIdleTaskStackSize)
{
	*ppxIdleTaskTCBBuffer=&Idle_Task_TCB;
	*ppxIdleTaskStackBuffer=Idle_Task_Stack;
	*pulIdleTaskStackSize=configMINIMAL_STACK_SIZE;
}

//获取定时器任务的任务堆栈和任务控制块内存
//ppxTimerTaskTCBBuffer:任务控制块内存
//ppxTimerTaskStackBuffer:任务堆栈内存
//pulTimerTaskStackSize:任务堆栈大小

void vApplicationGetTimerTaskMemory(StaticTask_t **ppxTimerTaskTCBBuffer, 
									StackType_t**ppxTimerTaskStackBuffer, 
									uint32_t *pulTimerTaskStackSize)
{
	*ppxTimerTaskTCBBuffer=&Timer_Task_TCB;
	*ppxTimerTaskStackBuffer=Timer_Task_Stack;
	*pulTimerTaskStackSize=configTIMER_TASK_STACK_DEPTH;
}

在这里插入图片描述

(3)main函数

int main()
{
	//在前面这里放所使用模块的初始化,将所有用到的外设驱动起来
	//下面就是开始任务函数的定义
	StartTask_Handler=xTaskCreateStatic((TaskFunction_t	)start_task,
													//任务函数		
										(const char* 	)"start_task",
													//任务名称		
										(uint32_t 		)START_STK_SIZE,	
													//任务堆栈大小
										(void* 		  	)NULL,		
													//传递给任务函数的参数		
										(UBaseType_t 	)START_TASK_PRIO, 
													//任务优先级	
										(StackType_t*   )StartTaskStack,	
													//任务堆栈
										(StaticTask_t*  )&StartTaskTCB);	         
													//任务控制块
    vTaskStartScheduler();//开启任务调度
}

在这里插入图片描述

(4)开始任务函数

在FreeRtos进入临界段代码的时候需要关闭中断,当处理完临界段代码以后再打开中断
一般我们都会使用这个临界区,进入和退出是配套使用的,我们在使用的时候要尽量保持临时段耗时短

//开始任务函数
void start_task(void *pvParameters)
{
    taskENTER_CRITICAL();         //进入临界区
    //创建task1任务
	Task1Task_Handler=xTaskCreateStatic((TaskFunction_t	)task1_task,		
										(const char* 	)"task1_task",		
										(uint32_t 		)TASK1_STK_SIZE,	
										(void* 		  	)NULL,				
										(UBaseType_t 	)TASK1_TASK_PRIO, 	
										(StackType_t*   )Task1TaskStack,	
										(StaticTask_t*  )&Task1TaskTCB);	
    //创建task2任务
	Task2Task_Handler=xTaskCreateStatic((TaskFunction_t	)task2_task,		
										(const char* 	)"task2_task",		
										(uint32_t 		)TASK2_STK_SIZE,	
										(void* 		  	)NULL,				
										(UBaseType_t 	)TASK2_TASK_PRIO, 	
										(StackType_t*   )Task2TaskStack,	
										(StaticTask_t*  )&Task2TaskTCB);
																			
    vTaskDelete(StartTask_Handler); //删除开始任务
    taskEXIT_CRITICAL();            //退出临界区
}

在这里插入图片描述
这里只是简单地使用FreeRtos,掌握Rtos下的多任务多优先级的实现方式,掌握FreeRtos的基本用法,打造一个实时性系统


今日分享就到这里~

在这里插入图片描述

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

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

相关文章

Layout 布局组件快速搭建

文章目录 设置主题样式变量封装公共布局组件封装 Logo 组件封装 Menu 菜单组件封装 Breadcrumb 面包屑组件封装 TabBar 标签栏组件封装 Main 内容区组件封装 Footer 底部组件封装 Theme 主题组件 经典布局水平布局响应式布局搭建 Layout 布局组件添加 Layout 路由配置启动项目 …

关于Idea中的debug模式只能执行一次的问题

希望文章能给到你启发和灵感~ 如果觉得文章对你有帮助的话,点赞 关注 收藏 支持一下博主吧~ 阅读指南 开篇说明一、基础环境说明1.1 硬件环境1.2 软件环境 二、为什么debug模式只有生效一次三、补充说明其他调试功能四、最后 开篇说明 记录一…

设计模式学习优质网站分享:refactoring.guru

地址 英文版地址:https://refactoring.guru/design-patterns 中文版地址:https://refactoringguru.cn/design-patterns 介绍 这个网站是专门学习 设计模式 和 软件重构 的网站 整体来说并不花哨,但我觉得他最大的优点就是: 概…

PyTorch 基础学习(2)- 张量 Tensors

PyTorch张量简介 张量是数学和计算机科学中的一个基本概念,用于表示多维数据,是AI世界中一切事物的表示和抽象。可以将张量视为一个扩展了标量、向量和矩阵的通用数据结构。以下是对张量的详细解释: 张量的定义 标量(0阶张量&am…

Assembly(七)实验环境搭建

本篇文章将讲解在win11环境下的王爽老师的汇编语言的环境搭建 首先凑齐这些文件: 随后安装好Dosbox,去官网下载就好 打开箭头所指文件 找到文件最后部分 [autoexec] # Lines in this section will be run at startup. # You can put your MOUNT lines here. MOUNT C D:\Debug …

快速搭建Vue_cli以及ElementUI简单项目学生管理系统雏形

为了帮助大家快速搭建Vue_cli脚手架还有ElementUI的简单项目,今天我给大家提供方法. 因为这个搭建这个项目步骤繁多,容易忘记,所以给大家提供这个资料希望可以帮助到你们. 废话不多说开始搭建项目: 搭建Vue_cli项目 首先点开HBuilder左上角的文件点击新建,点击项目,选择vue项…

2024年人工智能固态硬盘采购容量预计超过45 EB

根据TrendForce发布的最新市场报告,人工智能(AI)服务器客户在过去两个季度显著增加了对企业级固态硬盘(SSD)的订单。为了满足AI应用中不断增长的SSD需求,上游供应商正在加速工艺升级,并计划在20…

智慧交通物联网应用,5G路由器赋能高速道路监控数据传输

高速道路为了保障交通的高速、安全运行,沿线部署了控制设施、监视设施、情报设施、传输设施、显示设施及控制中心等。在传统的高速管理中,这些设施的传输设施多采用光纤线缆进行数据传输,但高速道路覆盖范围广、距离远,布线与施工…

韩顺平 集合

集合 一、体系结构图二、Collection2.1 Collection 接口和常用方法2.2 集合遍历2.2.1 迭代器2.2.2 增强for循环 三、List接口及其常用方法3.1 三种遍历方式3.2 ArrayList3.3 LinkedList 四 MAP4.1 hashmap 一、体系结构图 集合主要是两组 单列和双列集合 Collection接口有两个重…

第十五章:高级调度

本章内容包括: 使用节点污点和pod容忍度组织pod调度到特定节点将节点亲和性规则作为节点选择器的一种替代使用节点亲和性进行多个pod的共同调度使用节点非亲和性来分离多个pod Kubernetes允许你去影响pod被调度到哪个节点。起初,只能通过在pod规范⾥指定…

Linux安装Nginx后,无法解析Windows主机Hosts文件

问题展示: 配置好Linux的Nginx配置后,Windows同样配置好host,而通过浏览器只能用IP地址成功访问,而域名则不行 解决方法: 点击Windows图标,搜索记事本,选择以管理员身份运行,编辑…

php-xlswriter实现数据导出excel单元格合并,内容从指定行开始写

最终效果图: 代码: public function export_data() {$list $this->get_list_organ();$content [];$content[] []; // 第2行不设置内容,设置为空foreach ($list as $key > $value) {$content[] [$value[organ_name], $value[clas…

防火墙技术与地址转换

文章目录 前言一、四种区域二、实验拓扑图基础配置防火墙配置测试结果 前言 防火墙是计算机网络中的一种安全设备或软件功能,旨在监控和控制进出网络的网络流量。其核心目的是保护内部网络免受外部攻击或不必要的访问。防火墙通过设定一系列安全规则,允…

【iOS】UITableViewCell的重用问题解决方法

我自己在实验中对cell的重用总结如下: 非自定义Cell和非自定义cell的复用情况一样: 第一次加载创建tableView的时候,是屏幕上最多也显示几行cell就先创建几个cell,此时复用池里什么都没有开始下滑tableView,刚开始滑…

可视化编程-七巧低代码入门02

1.1.什么是可视化编程 非可视化编程是一种直接在集成开发环境中(IDE)编写代码的编程方式,这种编程方式要求开发人员具备深入的编程知识,开发效率相对较低,代码维护难度较大,容易出现错误,也需要…

最新的APS高级计划排程系统推动的MRP供应链计划是什么?

在当下“内卷”的市场环境下,制造业的订单需求从过去大批量标准品生产已经演变成小批量、多订单的非标订单生产,这对制造业的供应链提出了更高的要求。为了应对市场实现产销平衡,中大型的企业都开始重视供应链的建设工作,以应对企…

数字签名和CA数字证书的核心原理和作用

B站讲解视频,讲述HTTPS CA认证的整个行程过程与原理 https://www.bilibili.com/video/BV1mj421d7VE

[Qt][Qt 文件]详细讲解

目录 1.输入输出设备类2.文件读写类3.文件和目录信息类 1.输入输出设备类 在Qt中,⽂件读写的类为QFile,其⽗类为QFileDevice QFileDevice提供了⽂件交互操作的底层功能QFileDevice的⽗类是QIODevice,其⽗类为QObject QIODevice是Qt中所有I/O…

【数学建模备赛】Ep05:斯皮尔曼spearman相关系数

文章目录 一、前言🚀🚀🚀二、斯皮尔曼spearman相关系数:☀️☀️☀️1. 回顾皮尔逊相关系数2. 斯皮尔曼spearman相关系数3. 斯皮尔曼相关系数公式4. 另外一种斯皮尔曼相关系数定义5. matlab的用法5. matlab的用法 三、对斯皮尔曼相…

立仪光谱共焦传感器行业应用|透明胶水高度测量

01|检测需求:透明胶水高度测量 02|检测方式 根据客户要求及观察我们使用立仪科技D40A26XL镜头搭配E系列控制器进行测量 03|光谱共焦测量结果 经过测量可以得出胶水的高度为1076.406μm 04|光谱共焦侧头 D40A26XL侧头…