STM32F407单片机编程入门(十二) FreeRTOS实时操作系统详解及实战含源码

news2024/9/22 1:56:22

文章目录

    • 一.概要
    • 二.什么是实时操作系统
    • 三.FreeRTOS的特性
    • 四.FreeRTOS的任务详解
      • 1.任务函数定义
      • 2.任务的创建
      • 3.任务的调度原理
    • 五.CubeMX配置一个FreeRTOS例程
      • 1.硬件准备
      • 2.创建工程
      • 3.调试FreeRTOS任务调度
    • 六.CubeMX工程源代码下载
    • 七.小结

一.概要

FreeRTOS是一个迷你的实时操作系统内核。作为一个轻量级的操作系统,功能包括:任务管理、时间管理、信号量、消息队列、内存管理、记录功能、软件定时器、协程等,可基本满足较小系统的需要。
由于RTOS需占用一定的系统资源(尤其是RAM资源),只有μC/OS-II、embOS、salvo、FreeRTOS等少数实时操作系统能在小RAM单片机上运行。相对μC/OS-II、embOS等商业操作系统,FreeRTOS操作系统是完全免费的操作系统,具有源码公开、可移植、可裁减、调度策略灵活的特点,可以方便地移植到各种单片机上运行。

二.什么是实时操作系统

操作系统是一个控制程序,作为硬件和应用程序之间的桥梁,主要是和硬件打交道,负责协调分配计算资源和内存资源给不同的应用程序使用,并防止系统出现故障。面对来自不同应用程序的大量且互相竞争的资源请求,操作系统通过一个调度算法和内存管理算法尽可能把资源公平且有效率地分配给不同的程序。应用程序则通过调用操作系统提供的API接口获得相应资源完成指定的任务。

实时操作系统(RTOS-Real Time Operating System)中实时(Real Time)指的是任务(Task)或者说实现一个功能的线程(Thread)必须在给定的时间(Deadline)内完成。

三.FreeRTOS的特性

具有抢占式或者合作式的实时操作系统内核
功能可裁剪,最小占用10kB左右rom空间,0.5kB ram空间
灵活的任务优先级分配
具有低功耗模式
有互斥锁、信号量、消息队列等功能
运行过程可追踪
支持中断嵌套

四.FreeRTOS的任务详解

FreeRTOS的核心是任务调度器(Task Scheduler),它负责按照一定的调度策略将任务分配给处理器执行。每个任务都是一个独立的函数,可以有不同的优先级和堆栈大小。任务调度器根据任务的优先级和调度策略决定哪个任务被执行。

下图就是任务调度简单介绍
在这里插入图片描述

下面代码就是个简单的示例代码,通过调用osThreadCreate函数创建了两个任务LED_Thread1(驱动LED灯灭)和LED_Thread2(驱动LED灯亮)。在main函数中,通过调用osKernelStart函数启动了实时系统,使得任务可以被调度执行,由于两个任务都能不断运行,所以能驱动LED灯闪烁。

//定义任务函数1
void LED_Thread1(void const * argument)
{
  (void) argument;
  for (;;)
  {
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_SET);//PB4输出高,LED灭
  osDelay(100);//等待100ms
  }
}
//定义任务函数2
void LED_Thread2(void const * argument)
{
  (void) argument;
  for (;;)
  {
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_RESET);//PB4输出低,LED亮
  osDelay(250);//等待250ms
  }
}

int main(void)
{

  HAL_Init();
  SystemClock_Config();//外部8M晶振,系统168M主频
  MX_GPIO_Init();
  MX_FREERTOS_Init();
  osThreadDef(THREAD1, LED_Thread1, osPriorityNormal, 0, 128);
  THREAD1Handle = osThreadCreate(osThread(THREAD1), NULL);//建立任务1
  osThreadDef(THREAD2, LED_Thread2, osPriorityNormal, 0, 128);
  THREAD2Handle = osThreadCreate(osThread(THREAD2), NULL);//建立任务2
  osKernelStart();
  while (1)
  {
  }
 }

1.任务函数定义

无论采用何种方法创建任务,均需要用到任务函数。FreeRTOS 规定任务函数的返回值必须为void,而且带有一个void型指针参数。

void LED_Thread1(void const * argument)
{
  (void) argument;
  for (;;)
  {
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_SET);//PB4输出高,LED灭
  osDelay(100);//等待100ms
  }
}

STM32F407VET6单片机只有一个内核,那怎么让多个人同时干活呢?其实每个子任务虽然都是死循环,但并不是每个子任务一直都在执行,每个子任务在执行期间,可能需要延时,这边就通过 osDelay(100),等待100ms,单片机就可以停止此任务,然后切换到其它任务执行,这样看起来就是多个人在同时干活了。

2.任务的创建

osThreadDef(THREAD1, LED_Thread1, osPriorityNormal, 0, 128);//定义一个任务,任务名,任务函数,优先级,堆栈大小
THREAD1Handle = osThreadCreate(osThread(THREAD1), NULL);  //根据上面定义的任务,创建一个任务

osThreadDef函数中的128是任务栈大小定义:

任务栈大小指定了任务可以使用多少RAM来存储局部变量和其他临时数据。这个大小应该足够大,能够容纳任务在执行期间可能出现的最大需求。

osThreadDef函数中的LED_Thread1是任务函数:

任务函数是任务执行的代码,它应该是一个无返回值的函数,其参数是一个可选的指针,可以用来传递任何需要的数据,我们代码中的任务就是控制GPIO输出高或者低电平。

osThreadDef函数中的osPriorityNormal任务优先级:

任务优先级决定了任务在操作系统调度下的执行顺序。数值越大,优先级越高。

osThreadCreate函数的返回值THREAD1Handle是任务句柄:

任务句柄是一个指针,可以用来引用已经创建的任务,以便可以在任务创建后对其进行操作,例如删除、挂起、恢复等。

3.任务的调度原理

FreeRTOS默认使用抢占式调度策略,对同等优先级的任务使用时间片轮询调度,时间片轮询就是可轮流享有相同的单片机时间(可设置),一个时间片等于SysTick中断周期。
抢占式调度是指调度器始终运行优先级最高且处于可运行状态的任务,无论任务何时可以运行。如在中断服务函数中更改了优先级最高且可运行的任务,调度器会停止当前执行的低优先级任务,并启动高优先级任务。
刚才程序中的osDelay 是通过将当前任务加入到延时列表中,并设置一个定时器来在指定的延时时间,延时时间过去之后将任务从延时列表中移除并将其设置为就绪状态。这样当定时器触发时,任务重新被加入到就绪列表中,等待被调度器再次调度执行。

上面代码中的LED_Thread1(驱动LED灯灭)和LED_Thread2(驱动LED灯亮)两个任务的调度顺序以及时间,如下图所示,横坐标是时间,箭头代表运行顺序
在这里插入图片描述

下面代码截图就是操作系统底层寻找就绪任务的最高优先级,获取优先级最高的就绪任务的 TCB(任务控制块),然后更新到 pxCurrentTCB ,当前运行的任务只可能有一个,因此pxCurrentTCB只是单个TCB_t指针,它始终指向当前运行的任务。通过xPortPendSVHandler(PendSV_Handler)函数实现调度
在这里插入图片描述
PendSV_Handler 是 ARM Cortex-M 处理器中的一个特殊的中断处理函数,用于处理挂起 PendSV(Pending Supervisor Call)中断。PendSV 中断是 Cortex-M 架构中的一种特殊的软件中断,它可以用来实现任务切换或者其他与系统调度相关的操作。
PendSV_Handler 在中断向量表的位置
在这里插入图片描述

__asm void xPortPendSVHandler( void )
{
	extern uxCriticalNesting;
	extern pxCurrentTCB;
	extern vTaskSwitchContext;

	PRESERVE8

	mrs r0, psp
	isb
	/* Get the location of the current TCB. */
	ldr	r3, =pxCurrentTCB//获取当前TCB的位置 
	ldr	r2, [r3]

	/* 任务是否使用FPU上下文?如果是,则保存vfp寄存器 */
	tst r14, #0x10
	it eq
	vstmdbeq r0!, {s16-s31}

	/* 保存核心寄存器 */
	stmdb r0!, {r4-r11, r14}

	/* 将新的栈顶保存到TCB的第一个成员中*/
	str r0, [r2]

	stmdb sp!, {r0, r3}
	mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY
	msr basepri, r0
	dsb
	isb
	bl vTaskSwitchContext
	mov r0, #0
	msr basepri, r0
	ldmia sp!, {r0, r3}

	/*pxCurrentTCB中的第一项是堆栈的任务顶部 */
	ldr r1, [r3]
	ldr r0, [r1]

	/*弹出核心寄存器*/
	ldmia r0!, {r4-r11, r14}

	/* 任务是否使用FPU上下文?如果是,则弹出vfp寄存器 */
	tst r14, #0x10
	it eq
	vldmiaeq r0!, {s16-s31}

	msr psp, r0
	isb
	#ifdef WORKAROUND_PMU_CM001 /* XMC4000 specific errata */
		#if WORKAROUND_PMU_CM001 == 1
			push { r14 }
			pop { pc }
			nop
		#endif
	#endif

	bx r14
}

五.CubeMX配置一个FreeRTOS例程

1.硬件准备

STLINK接STM32F407VET6开发板,STLINK接电脑USB口。
在这里插入图片描述

2.创建工程

打开STM32CubeMX软件,新建工程
在这里插入图片描述
Part Number处输入STM32F407VE,再双击就创建新的工程
在这里插入图片描述

配置下载口引脚
在这里插入图片描述

配置外部晶振引脚
在这里插入图片描述

可以查看STM32F407VET6开发板原理图,PB4连接LED灯,所以配置PB4为GPIO输出

在这里插入图片描述

配置系统主频168Mhz,使用外部晶振
在这里插入图片描述
配置FreeRTOS
在这里插入图片描述

配置工程文件名,保存路径,KEIL5工程输出方式
在这里插入图片描述

生成工程
在这里插入图片描述

用Keil5打开工程
在这里插入图片描述

添加代码
在这里插入图片描述
在这里插入图片描述

3.调试FreeRTOS任务调度

调试代码,能更好理解任务调度。
下载调试,在LED_Thread1打断点,程序能运行到断点处停止
在这里插入图片描述

在LED_Thread2打断点,程序也能运行到断点处停止
在这里插入图片描述

在xPortPendSVHandler调度函数中打断点,可以看到操作系统将要跳转到任务1运行
在这里插入图片描述

单步执行,运行指针就跳转到任务1开始运行
在这里插入图片描述

xPortPendSVHandler调度函数中打断点,可以看到操作系统将要跳转到任务2运行
在这里插入图片描述

单步执行,运行指针就跳转到任务2开始运行
在这里插入图片描述

六.CubeMX工程源代码下载

通过网盘分享的文件:13.FREERTOS实验.zip
链接: https://pan.baidu.com/s/1nHEHJUsQn-xOAdiQx0s-1A 提取码: y5gh

如果链接失效,可以联系博主给最新链接

程序下载下来之后解压就行

七.小结

FreeRTOS实时操作系统能使在STM32软件开发中,程序结构清晰,单片机执行效率提升许多,在多个任务模块的代码中,可以考虑使用FreeRTOS。

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

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

相关文章

智慧校园建设解决方案建设系统简介

一、建设背景 1.1 政策背景 1.2 班牌的演变 1.3 建设愿景 二、 智慧班牌简介 三、智慧班牌系统 3.1 系统概述 3.2 软件平台功能交互简介 3.2.1 智慧班牌与管理平台间的功能关联 3.2.2 手机客户端(管理员、教师、家长端) 3.2.3 手机客户端&#x…

数据采集与预处理,前后端结合案例(有代码),Python连接MySQL,对MySQL的增删改查

Python对MySQL的增删改查 通过Python连接MySQL """连接MySQL数据库,并进行增删改查,同时查询了MySQL版本号,并做了动态注册的账号,实现过程:先向userinfo当中添加account、password新字段&#xff0c…

数据结构:内部排序

文章目录 1. 前言1.1 什么是排序?1.2 排序的稳定性1.3 排序的分类和比较 2. 常见的排序算法3. 实现常见的排序算法3.1 直接插入排序3.2 希尔排序3.3 直接选择排序3.4 堆排序3.5 冒泡排序3.6 快速排序3.6.1 hoare思想3.6.2 挖坑法3.6.3 lomuto前后指针法3.6.4 非递归…

软考(中级-软件设计师)计算机系统篇(0921)

I 计算机系统知识 一、考纲要求 数值及其转换 二进制、十进制和十六进制等常用数制及其相互转换 计算机内数据的表示 数值的表示(原码、反码、补码、移码表示,整数和实数的机内表示,精度和溢出)非数值表示(字符和汉字…

AI直播新浪潮:无人视频自动直播,出圈再造辉煌,创业者首选!

AI直播新浪潮:无人视频自动直播,出圈再造辉煌,创业者首选! 在数字化浪潮的汹涌澎湃中,AI技术正以前所未有的速度重塑着各行各业的边界,而直播行业作为数字内容消费的前沿阵地,正迎来一场由AI驱动的深刻变革…

MQ(RabbitMQ)笔记

初识MQ 同步调用优缺点 异步调用优缺点 总结: 时效性要求高,需要立刻得到结果进行处理--->同步调用 对调用结果不关心,对性能要求高,响应时间短--->异步调用

2024年华为杯-研赛F题论文问题一二讲解+代码分享

X射线脉冲星光子到达时间建模 摘要 脉冲星是一类高速自转的中子星,其自转形成规律性脉冲信号,类似于“宇宙中的灯塔”,因此被认为是极为精确的时钟。X射线脉冲星导航利用脉冲星信号为航天器提供时间和空间参考。通过比较脉冲信号到达航天器…

查找算法 01分块查找

自己设计一个分块查找的例子,不少于15个数据元素,并建立分块查找的索引 基于上述例子,计算查找成功的ASL、查找失败的ASL 拓展: ‌‌分块查找的平均查找长度(‌ASL)的计算公式如下‌:‌ ‌顺序…

Camunda流程引擎并发性能优化

文章目录 Camunda流程引擎一、JobExecutor1、工作流程2、主要作用 二、性能问题1、实际场景:2、性能问题描述3、总结 三、优化方案方案一:修改 Camunda JobExecutor 源码以实现租户 ID 隔离方案二:使用 max-jobs-per-acquisition 参数控制上锁…

ThreadLocal与AsyncLocal

简介 ThreadLocal 用于在多线程环境中创建线程局部变量,可以让每个线程独立地访问自己的变量副本,互不影响。 而 AsyncLocal 是 ThreadLocal 的异步版本,专门用于异步编程场景,在异步操作中它可以正确处理上下文切换。 ThreadLo…

ftp服务的管理及安全优化

1.ftp介绍 ftp : file transfer proto 互联中最老牌的文件传输协议 2.vsftpd安装及启用 环境 #server 主机 : # R3 # 192.168.10.130 # selinux 关闭 # 火墙开启 # dnf 安装设定完成 # #client 主机 : # R4 # 192.168.10.131 # selinux 关闭 …

C++之职工管理系统(细节Q)

指针初始化类 && 普通变量初始化类 抽象基类worker,只需编写 .h ,无需 .cpp 底层实现 类 记得声明权限public!!!不然默认private,主函数访问不了 记得继承父类 Worker * worker:指向Wo…

source insight学习笔记

目录 目的 基础配置 1、护眼的保护色 2、行号显示 基础操作 目的 记录一下使用source insight中遇到的问题。比如常见好用的基础配置,常用的基础操作等。主要是为了自己以后忘记了好找。自己写的东西总归看起来更舒服。 PS:目前是第一个版本&#…

Linux相关概念和重要知识点(5)(权限的修改、时间属性)

1.权限的修改 (1)提权行为 普通用户是会受到权限的限制,但root账户无视一切权限限制,因此当我们要获取更高的权限,有一种办法就是将自己变成root或者短暂拥有和root一样的权力。 普通用户 -> root :s…

NoSql数据库Redis知识点

数据库的分类 关系型数据库 ,是建立在关系模型基础上的数据库,其借助于集合代数等数学概念和方法来处理数据库 中的数据主流的 MySQL 、 Oracle 、 MS SQL Server 和 DB2 都属于这类传统数据库。 NoSQL 数据库 ,全称为 Not Only SQL &a…

网络丢包定位记录(二)

网卡驱动丢包 查看:ifconfig eth1/eth0 等接口 1.RX errors: 表示总的收包的错误数量,还包括too-long-frames错误,Ring Buffer 溢出错误,crc 校验错误,帧同步错误,fifo overruns 以及 missed pkg 等等。 …

K8S介绍+集群部署

Kubernetes介绍 官网:https://kubernetes.io/ 一、应用部署方式演变 1、传统部署:互联网早期,会直接将应用程序部署在物理机上 优点:简单,不需要其他技术的参与 缺点:不能为应用程序定义资源使用边界&a…

WAN广域网技术--PPP和PPPoE

广域网基础概述 广域网(Wide Area Network,WAN)是一种覆盖广泛地区的计算机网络,它连接不同地理位置的计算机、服务器和设备。广域网通常用于连接不同城市、州或国家之间的网络,它通过互联网服务提供商(ISP…

九芯电子革新健康检测!语音播报血压计ic芯片解决方案

血压计,可测量血压并将读数显示在屏幕上。为了提高老年人和视障人士的可用性,现代电子语音血压计已经开发出来,可提供当前血压读数的听觉反馈。这是通过集成语音芯片来实现的,该芯片将测量结果发声给用户。 (一&#x…

Java免税购物商城:Spring Boot技术实现

第二章 系统开发关键技术 2.1 JAVA技术 Java主要采用CORBA技术和安全模型,可以在互联网应用的数据保护。它还提供了对EJB(Enterrise JavaBeans)的全面支持,java servlet AI,JS(java server ages&#xff09…