STM32(F103ZET6)第十九课:FreeRtos的移植和使用

目录

  • 需求
  • 一、FreeRtos简介
  • 二、移植FreeRtos
    • 1.复制代码
    • 2.内存空间分配和内核相关接口
    • 3.FreeRtosConfig
    • 4.添加到工程中
    • 三、任务块操作
    • 1.任务四种状态
    • 2.创建任务过程

需求

1.将FreeRtos(嵌入式实时操作系统)移植到STM32中。
2.在该系统中实现任务的创建、挂起、恢复和删除。
3.将板子上写的传感器模块的数据获取,移植到FreeRtos(嵌入式实时操作系统)环境下。
在这里插入图片描述

一、FreeRtos简介

裸机执行流程:前后台系统
在这里插入图片描述
操作系统执行流程:
在这里插入图片描述
加入操作系统的作用:用户想要实现多个任务并行的效果,但是单片机只有一个核心,同时只能处理一件事,通过加入操作系统,可以实现任务快速的切换,给人一种多个任务同时在执行的错觉。
FreeRtos的概念:
在这里插入图片描述在这里插入图片描述

二、移植FreeRtos

移植之前,找一个工程mian.c清空,然后移植FreeRTOS。因为加上操作系统之后,编程方式就变了,之前的while(1)就不在使用了。

1.复制代码

从官网下载的FreeRTOS 包含 Demo 例程和内核源码(比较重要,我们就需要提取该目录下的大部分文件)。 FreeRTOS 文件夹下的 Source 文件夹里面包含的是 FreeRTOS 内核的源代码,
我们移植 FreeRTOS 的时候就需要这部分源代码; FreeRTOS 文件夹下的 Demo 文件夹里
面包含了 FreeRTOS 官方为各个单片机移植好的工程代码, FreeRTOS 为了推广自己,会
给各种半导体厂商的评估板写好完整的工程程序,这些程序就放在 Demo 这个目录下,这
部分 Demo 非常有参考价值。我们把 FreeRTOS 到 STM32 的时候,FreeRTOSConfig.h 这
个头文件就是从这里拷贝过来的。
在这里插入图片描述
将源码直接复制到想要移植的工程文件下,改名为FreeRtos:
在这里插入图片描述
这里我们再重点分析下 FreeRTOS/ Source 文件夹下的文件,具体见图 13-6。“include”
文件夹和“portable”文件夹包含的是 FreeRTOS 的通用的头文件和 C 文件,这两部分的文
件试用于各种编译器和 include 处理器, 是通用的。需要移植的头文件和 C 文件放在编号
portblle 这个文件夹。
在这里插入图片描述
我们打开 portable 这个文件夹,可以看到里面很多与编译器相关的文件夹, 在不同的
编译器中使用不同的支持文件。文件夹“Keil”就是我们就是我们使用的编译器,当打开 “Keil”
文件夹的时候,你会看到一句话“See-also-the-RVDS-directory.txt”,其实 “Keil” 里面的内容
跟 RVDS 里面的内容一样,所以我们只需要 RVDS 文件夹里面的内容即可。而 MemMang
文件夹下存放的是跟内存管理相关的,我们的重点是RVDS文件夹
在这里插入图片描述
打开 RVDS 文件夹, 下面包含了各种处理器相关的文件夹,从文件夹的名字我们就非
常熟悉了,有 M0、 M3、 M4 等各种系列, FreeRTOS 是一个软件,单片机是一个硬件,
FreeRTOS 要想运行在一个单片机上面,它们就必须关联在一起,那么怎么关联?还是得通
过写代码来关联,这部分关联的文件叫接口文件,通常由汇编和 C 联合编写。这些接口文
件都是跟硬件密切相关的,不同的硬件接口文件是不一样的,但都大同小异。编写这些接口
文件的过程我们就叫移植,移植的过程通常由 FreeRTOS 和 MCU 原厂的人来负责,移植
好的这些接口文件就放在 RVDS 这个文件夹的目录下。
在这里插入图片描述

2.内存空间分配和内核相关接口

MemMang 文件夹下存放的是跟内存管理相关的,总共有五个 heap 文件以及一
个 readme 说明文件,这五个 heap 文件在移植的时候必须使用一个,因为 FreeRTOS 在
创建内核对象的时候使用的是动态分配内存,而这些动态内存分配的函数则在这几个文件里
面实现,不同的分配算法会导致不同的效率与结果,后面在内存管理中我们会讲解每个文件
的区别,由于现在是初学,所以我们选用 heap4.c 即可。
在这里插入图片描述
FreeRTOS 为我们提供了 cortex-m0、m3、m4 和 m7 等内核的单片机的接口文件,
只要是使用了这些内核的 MCU 都可以使用里面的接口文件。我们这里以 ARM_CM3 这个
文件夹为例,看看里面的文件,里面只有“port.c”与“portmacro.h”两个文件, port.c 文件里
面的内容是由 FreeRTOS 官方的技术人员为 Cortex-M3 内核的处理器写的接口文件,里面
核心的上下文切换代码是由汇编语言编写而成;portmacro.h 则是 port.c 文件对应的头文
件,主要是一些数据类型和宏定义。
在这里插入图片描述
首先在我们的 STM32 裸机工程模板根目录下新建一个文件夹,命名为“FreeRTOS”,
并且在 FreeRTOS 文件夹下新建两个空文件夹,分别命名为“src”与“port”,src 文件夹用于
保存 FreeRTOS 中的核心源文件,也就是我们常说的‘.c 文件’, port 文件夹用于保存内存
管理以及处理器架构相关代码,这些代码 FreeRTOS 官方已经提供给我们的,直接使用即可,
在前面已经说了, FreeRTOS 是软件,我们的开发版是硬件,软硬件必须有桥梁来连接,这
些 与 处 理 器 架 构 相 关 的 代 码 , 可 以 称 之 为 RTOS 硬 件 接 口 层 , 它 们 位 于
FreeRTOS/Source/Portable 文件夹下。
在这里插入图片描述
打开 FreeRTOS 源码,在“FreeRTOSvX.X.X\FreeRTOS\Source”目录下找到所有的‘.c 文
件’,将它们拷贝到我们新建的 src 文件夹中。
在这里插入图片描述
打开 FreeRTOS VX.X.X 源码,在“FreeRTOS VX.X.X \FreeRTOS\Source\portable”目录
下找到“ MemMang”文件夹与“ RVDS”文件夹,将它们拷贝到我们新建的 port 文件夹中。
在这里插入图片描述
打开 FreeRTOS VX.X.X 源码,在“FreeRTOS VX.X.X \FreeRTOS\Source” 目录下找到
“include”文件夹,它是我们需要用到 FreeRTOS 的一些头文件,将它直接拷贝到我们新建的
FreeRTOS 文件夹中,完成这一步之后就可以看到我们新建的 FreeRTOS 文件夹已经有 3
个文件夹,这 3 个文件夹就包含 FreeRTOS 的核心文件,至此,FreeRTOS 的源码就提取
完成
在这里插入图片描述

3.FreeRtosConfig

拷贝 FreeRTOSConfig.h 文件到 user 文件夹
FreeRTOSConfig.h 文件是 FreeRTOS 的工程配置文件,因为 FreeRTOS 是可以裁剪的
实时操作内核,应用于不同的处理器平台,用户可以通过修改这个 FreeRTOS 内核的配置头
文件来裁剪 FreeRTOS 的功能,所以我们把它拷贝一份放在 user 这个文件夹下面
在这里插入图片描述
其中,FreeRTOSConfig.h 是直接从 demo 文件夹下面拷贝过来的,该头文件对裁剪整个FreeRTOS 所需的功能的宏均做了定义,有些宏定义被使能,有些宏定义被失能,一开始我们只需要配置最简单的功能即可。要想随心所欲的配置 FreeRTOS 的功能,必须对这些宏定义的功能有所掌握。
比较重要的宏文件:
#define configUSE_TIME_SLICING 1 //使能时间片调度(默认式使能的)
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 //硬件计算前导零指令,如果所使用的, MCU 没有这些硬件指令的话此宏应该设置为 0
#define configUSE_TICKLESS_IDLE 0 //置 1:使能低功耗 tickless 模式;置 0:保持系统节拍(tick)中断一直运行
#define configUSE_QUEUE_SETS 1 //启用队列
#define configUSE_TASK_NOTIFICATIONS 1 //开启任务通知功能,默认开启
#define configUSE_MUTEXES 1 //使用互斥信号量
#define configUSE_RECURSIVE_MUTEXES 1 //使用递归互斥信号量
#define configUSE_COUNTING_SEMAPHORES 1 //为 1 时使用计数信号量
#define configQUEUE_REGISTRY_SIZE 10 //设置可以注册的信号量和消息队列个数
#define configUSE_APPLICATION_TASK_TAG 0
#define configSUPPORT_DYNAMIC_ALLOCATION 1 //支持动态内存申请
#define configUSE_MALLOC_FAILED_HOOK 0 //使用内存申请失败钩子函数
#define configCHECK_FOR_STACK_OVERFLOW 1// 大于 0 时启用堆栈溢出检测功能,如果使用此功能用户必须提供一个栈溢出钩子函数如果使用的话此值可以为 1 或者 2,因为有两种栈溢出检测方法
#define configGENERATE_RUN_TIME_STATS 0 //启用运行时间统计功能
#define configUSE_STATS_FORMATTING_FUNCTIONS 1
#define configUSE_TIMERS 1 //启用软件定时器
#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-1) //软件定时器优先级
#define configTIMER_QUEUE_LENGTH 10 //软件定时器队列长度
#define configTIMER_TASK_STACK_DEPTH (configMINIMAL_STACK_SIZE*2) //软件定时器任务堆栈大小
//可选函数配置选项
#define INCLUDE_xTaskGetSchedulerState 1
#define INCLUDE_eTaskGetState 1
#define INCLUDE_xTimerPendFunctionCall 1
//中断服务函数 也可以修改起始文件
#define vPortSVCHandler SVC_Handler
#define xPortPendSVHandler PendSV_Handler
#define xPortSysTickHandler SysTick_Handler

4.添加到工程中

添加 FreeRTOS 源码到工程组文件夹
在这里插入图片描述
配置 FreeRTOS 头文件路径
在这里插入图片描述

三、任务块操作

1.任务四种状态

在这里插入图片描述
四种形态:
运行态
当任务实际执行时,它被称为处于运行状态。 任务当前正在使用处理器。 如果运行 RTOS 的处理器只有一个内核, 那么在任何给定时间内都只能有一个任务处于运行状态。
就绪态
准备就绪任务指那些能够执行(它们不处于阻塞或挂起状态), 但目前没有执行的任务, 因为同等或更高优先级的不同任务已经处于运行状态。
阻塞态
如果任务当前正在等待时间或外部事件,则该任务被认为处于阻塞状态。 例如,如果一个任务调用vTaskDelay(),它将被阻塞(被置于阻塞状态), 直到延迟结束-一个时间事件。 任务也可以通过阻塞来等待队列、信号量、事件组、通知或信号量 事件。 处于阻塞状态的任务通常有一个"超时"期, 超时后任务将被超时,并被解除阻塞, 即使该任务所等待的事件没有发生。
“阻塞”状态下的任务不使用任何处理时间,不能 被选择进入运行状态。
挂起态
与“阻塞”状态下的任务一样, “挂起”状态下的任务不能 被选择进入运行状态,但处于挂起状态的任务 没有超时。 相反,任务只有在分别通过 vTaskSuspend() 和 xTaskResume() API 调用明确命令时 才会进入或退出挂起状态。
调度机制
和裸机操作不同,操作系统中执行的是一个一个任务块,通过任务调度器(使用相关的调度算法)来决定当前时刻要执行哪个任务。
调度方式主要有两种:
1.抢占式调度:任务优先级不同时使用。每个任务都有自己的优先级,高优先级的任务会抢占低优先级的任务。
2.时间片调度:任务优先级相同时使用。当多个任务优先级相同时,任务调度器会在每一次系统节拍到的时候切换任务。
其实说白了就是:STM32执行的是线性代码,只有中断能打断。而FreeRtos执行的是不同等级的任务块,等级越高任务块就越先执行,相同等级的任务块执行时系统会来回切换。
优先级不能设置为0,因为FreeRtos的空闲任务优先级为0,一般情况下我们不去抢。

2.创建任务过程

1、首先要添加FreeRTOS相关头文件。这是必须的!
在这里插入图片描述
2、创建一个句柄,TaskHandle_t 类型
在这里插入图片描述在这里插入图片描述
3、创建任务

Ret = xTaskCreate(LED_Task, //创建任务的任务函数名"LED1_Toggle",//任务名字50,//任务栈深度。32位单片机*4NULL,//创建任务时传递参数,没有就给NULL1,//任务优先级&LED_TaskHandle);//任务的句柄,用于后边删除,挂起任务if(Ret == pdPASS){printf("LED_Task创建完成\r\n");}Ret = xTaskCreate(KEY_Task, //创建任务的任务函数名"KEY_Task",//任务名字100,//任务栈深度。32位单片机*4NULL,//创建任务时传递参数,没有就给NULL2,//任务优先级&KEY_TaskHandle);//任务的句柄,用于后边删除,挂起任务if(Ret == pdPASS){printf("KEY_Task创建完成\r\n");}printf("开启FreeRTOS调度器\r\n");//调度器启动完成之后,FreeRTOS会获取CPU控制权,会按照任务优先级执行创建的任务vTaskStartScheduler();printf("开启FreeRTOS调度器成功\r\n");

创建完成后一定要打开调度器。
4、写与句柄对应的任务函数,通常要加while(1)每个任务都是1个无限循环程序,内容根据需求来定。
在这里插入图片描述在这里插入图片描述
接下来重点了解一下创建函数:

在这里插入图片描述
在这里插入图片描述
简单来说:
参数1:实现任务的函数名
参数2:自己起一个任务名
参数3:分配空间,栈深度(32位单片机*4)
参数4:任务函数传参时使用
参数5:任务优先级(越高优先级越高)
参数6:该任务的句柄

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

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

相关文章

git 更改分支名称

1. 本地分支重命名(还未推送到远程) 1、修改当前分支名称 git branch -m 新分支名称2、修改其他分支名称 git branch -m 旧分支名称 新分支名称2. 远程分支重命名(已推送远程) 1)重新命名远程分支对应的本地分支 …

86、pod部署策略

一、集群的调度 集群的调度: 怎么把pod部署到节点的方法。 1.1、调度的过程: scheduler是集群的调度器,主要任务就是把pod部署到节点上。 1.2、自动调度: 1、公平,保证每个可用的节点都可以部署pod 2、资源的高…

【生日视频制作】黑板写文字美女跳舞2版AE模板修改文字软件生成器教程特效素材【AE模板】

生日视频制作教程黑板写文字美女跳舞2版AE模板修改文字特效广软件告生成神器素材祝福玩法AE模板替换工程 怎么如何做的【生日视频制作】黑板写文字美女跳舞2版AE模板修改文字软件生成器教程特效素材【AE模板】 生日视频制作步骤: 安装AE软件 下载AE模板 把AE模板导…

有向无环图的关联矩阵及其矩阵乘积的含义

有向无环图的关联矩阵及其矩阵乘积的含义 引言关联矩阵的定义矩阵乘积 B B T BB^T BBT的含义伪代码示例C代码示例结论引言 在计算机科学和数学中,有向无环图(Directed Acyclic Graph, DAG)是一种常见的数据结构,广泛应用于各种算法中,如拓扑排序、动态规划等。在有向无环…

10、Django Admin修改标题

admin from django.contrib import admin from .models import Category, Origin, Hero, Villain # 添加以下代码 admin.site.site_header "系统管理" admin.site.site_title "管理员界面" admin.site.index_title "欢迎来到这里&#xff…

网络模型及协议介绍

一.OSI七层模型 OSI Open System Interconnect 开放系统互连模型 以前不同厂家所生产的网络设备的标准是不同的,所以为了统一生产规范就制定了OSI这个生产模型。 作用:降低网络进行数据通信复杂度 这个模型的作用第一降低数据通信的复杂度&#xff…

QT cmake vscode 构建流程

采用基于QT creater方式实现: 1. Qt Creator——创建项目——Qt Widgets Application——CMake——Desktop Qt 6.8.0 MSVC2022 64bit——接下来全默认 关键点是选择CMake和构建套件这里用windows的MSVC。 2. 用vscode打开,即可。 可以配置一个调试任务…

【html】编辑器、基础、属性、标题、段落、格式化、 连接、头部、CSS、图像

目录 2.HTML编辑器 3.HTML基础 3.1 HTML标题 3.2 段落 4.HTML元素 4.1 元素语法 4.2 嵌套元素 4.3 HTML空元素 4.4 HTML提示,使用小写标签 5.HTML属性 5.1 属性实例 5.2 HTML 属性常用引用属性值 5.3 使用小写属性 5.4 HTML属性参考手册 6.HTML标题 6.1 HTML水…

JAKA学习2:博途组态配置PROFINET和MODBUS

目录 一、GSD文件安装与设备组态1.1、GSD安装1.2、PROFINET设备组态二、远程启动顺序2.1、启动步骤2.2、安全点配置三、JAKA配置3.1、输入输出点配置一、GSD文件安装与设备组态 1.1、GSD安装 1.2、PROFINET设备组态 二、远程启动顺序 2.1、启动步骤 1、 要保证DO9已开机状态…

驾驭Python与MySQL的桥梁:pymysql的神秘面纱

文章目录 **驾驭Python与MySQL的桥梁:pymysql的神秘面纱**背景:为何选择pymysql?库的简介安装指南简单的库函数使用方法场景应用常见问题与解决方案总结 驾驭Python与MySQL的桥梁:pymysql的神秘面纱 背景:为何选择pym…

赛码网牛客在acm模式下利用node.js处理多行输入方法

赛码网在JS Node的语言下,acm模式的默认标准输入输出代码是这样的: const readline require(readline);const rl readline.createInterface({input: process.stdin,output: process.stdout }); rl.on(line, function (line) {const tokens line.spli…

java重点学习-redis

一.redis 穿透无中生有key,布隆过滤nul隔离 锁与非期解难题。缓存击穿过期key, 雪崩大量过期key,过期时间要随机。 面试必考三兄弟,可用限流来保底。 1.1 Redis的使用场景 根据自己简历上的业务进行回答 缓存穿透、击穿、雪崩、双…

实验报告: lookie-lookie 项目测试与分析

目录 一、实验目的 二、实验环境 三、实验步骤 1. 下载与准备项目 1.1 从 GitHub 获取项目 1.2 查看项目文件结构 2. 运行项目 2.1 启动项目 2.2 浏览器设置 3. 项目体验 3.1 功能测试 3.2 运行截图 4. 文件结构分析 4.1 总体结构 4.2 主要文件和目录说明 5. 数…

重头开始嵌入式第三十二天(TCP多客户端模型)

1.多路IO 1.select #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <sys/types.h> /* See NOTES */ #include <sys/socket.h> #include <netinet/in.h> #include <netine…

基于人体关节夹角的人体动作识别算法(代码+数据集)

为此本文提出了一个基于人体关节夹角的人体动作识别算法&#xff0c;主要做了以下工作&#xff1a; &#xff08;1&#xff09;提出了一个可解释性强&#xff0c;耗费算力较少且鲁棒性较高的基于人体关节夹角的人体动作序列的特征抽取方法。 &#xff08;2&#xff09;本文所使…

PCL 移动立方体三维重建——RBF算法【2024最新版】

目录 一、算法原理1、算法概述2、参考文献二、代码实现三、结果展示四、相关链接本文由CSDN点云侠原创,原文链接,首发于:2024年9月1日。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的爬虫与GPT。 一、算法原理 1、算法概述 该算法实现的是Reconstruction a…

单片机配置导入导出功能设计(一种思路)

背景&#xff1a; 为了方便部分不开放到屏幕的配置进行修改&#xff0c;兼容离线机器&#xff0c;也支持产线大批量配置导入&#xff0c;提高生产效率&#xff0c;特此研发配置导入导出功能。 原理&#xff1a; 上电监测到U盘和文件系统正常后&#xff0c;监测是否存在配置文件…

贸易术语你都不懂,你还做什么外贸

外贸小伙伴们&#xff0c;连贸易术语都不懂&#xff0c;还做啥外贸&#xff1f;别担心&#xff0c;今天我给大家整理了常见的外贸贸易术语&#xff0c;让你轻松入门&#xff0c;快速上手&#xff01; 1、FOB: Free On Board 船上交货价。按离岸价进行的交易&#xff0c;买方…

Java并发线程 共享模型之管程 5

1. 生产者消费者 package cn.itcast.testcopy;import cn.itcast.n2copy.util.Sleeper; import lombok.extern.slf4j.Slf4j;import java.util.LinkedList;/*** ClassName: Test21* Package: cn.itcast.testcopy* Description: 生产者消费者** Author: 1043* Create: 2024/9/4 - …

软件测试之压力测试知识总结

&#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 压力测试 压力测试是一种软件测试&#xff0c;用于验证软件应用程序的稳定性和可靠性。压力测试的目标是在极其沉重的负载条件下测量软件的健壮性和错误处理能力&…