基于STM32CubeMX创建FreeRTOS—以STM32F429为例

目录

1. 实验任务

2. 使用STM32CubeMX创建基础工程

2.1 打开STM32CubeMX

2.2 创建新项目

2.3 时钟设置

2.5 修改时钟基准,打开串行调试

2.6 配置串口

2.7 配置状态指示灯

2.8 FreeRTOS

2.9 配置工程输出项

3. 代码编辑

3.1 printf重映射

3.1.1 使用ARMCC 5编译器时的printf重映射方法

3.2 使用FreeRTOS任务编写代码

3.3  运行效果

4 多任务相关知识

4.1 任务基础知识

4.2 任务状态

4.3 任务优先级

4.4 任务实现


 

1. 实验任务

利用STM32CubeMX,创建MDK工程,STM32CubeMX移植FreeRTOS。

开发环境准备:

Win11、MDK5、STM32CubeMX、STM32F429IGT6开发板

STM32CubeMX v6.10

2. 使用STM32CubeMX创建基础工程

2.1 打开STM32CubeMX

0a5154f9efce4dddb1b38b7df035c195.png

2.2 创建新项目

MCU型号选择STM32F429IGT6,开始项目。

fbea6d54b74248fe90eb74824f430ffb.png

2.3 时钟设置

选择使用外部高速时钟,时钟源为外部晶振(25MHz),配置系统时钟,根据外部晶振频率,将系统时钟配置到180MHz。

d13fbb6831ac44f7ac0d41d14f6e30d4.png

2.4 时钟配置树

0ca734433eaf46d6ab5fb24549c3bc72.png

2.5 修改时钟基准,打开串行调试

  • FreeRTOS使用systick系统嘀嗒定时器当作心跳,此处须修改HAL库的时钟基准。
  • 由于FreeRTOS和HAL库不能同时使用SysTick定时器,将HAL库的定时器改成TIM4

f03cb0bdd9f94a23852b0f559a1bdec4.png

2.6 配置串口

采用异步通信方式,通讯参数此处为默认值。

4719c78c016249d0889bef61aa31f189.png

2.7 配置状态指示灯

88ed322f4714405aac83ee6d5225e1b7.png

 

2.8 FreeRTOS配置

STM32CubeMX已经将FreeRTOS集成到工具中,并且将RTOS的接口封装为CMSIS-RTOS V1/V2,相较之于V1版本的CMSIS-RTOS API,V2版本的API的兼容性更高,为了将来的开发和移 植,建议开发者使用V2版本的API。

选择Middleware-FreeRTOS,Interface中选择CMSIS_V2:

ddf2631d34e1474cb265a107ae0a402c.png

选择CMSIS V2接口后,还要进一步配置FreeRTOS的参数和功能。
FreeRTOS的参数包括时基频率、任务堆栈大小、是否使能互斥锁等等,需要开发者根据自己对FreeRTOS的了解以及项目开发的需求,来定制参数。此处使用默认参数不需要修改。
使用STM32CubeMX,可以手工添加任务、队列、信号量、互斥锁、定时器等等。为提高代码的可移植性和灵活性,建议大家不要严重依赖STM32CubeMX,尽量不使用STM32CubeMX来添加这些对象,而是手写代码来使用这些对象。

建立双任务:

任务1:LED指示灯闪烁

任务2:串口打印输出

94da16ba15f9407bb841ad713d153315.png

提示:留意下串口中断的问题,由于FreeRTOS只允许5以上的中断级别,需要中断的话请设置大于等于5的值。

2.9 配置工程输出项

e77c2463f8b0486b9dca41f9c34509b5.png

6e7c0a73545743e8ab3d182dc1114c5b.png

 

3. 代码编辑

3.1 printf重映射

3.1.1 使用ARMCC 5编译器时的printf重映射方法

printf函数重映射,可以直接使用printf在串口一中打印数据,定位到usart.c文件中。

/* USER CODE BEGIN 0 */
#include "stdio.h"
/* USER CODE END 0 */
/* USER CODE BEGIN 1 */
int fputc(int ch,FILE *f)
{HAL_UART_Transmit(&huart1,(uint8_t*)&ch,1,10);return(ch);
}
/* USER CODE END 1 */

注意:重写printf后运行代码前一定要勾选Use MicroLiB,否则项目烧录后无法执行。

eca30f0165d74349ba36aa3515d1d3a6.png

3.1.2 使用ARM 6编译器时的printf重映射方法

参见博文:

基础篇007. 串行通信(一)--阻塞方式发送接收_串口阻塞-CSDN博客文章浏览阅读1.7k次,点赞2次,收藏10次。在学习C语言时我们经常使用C语言标准函数库输入输出函数,比如printf、scanf、getchar等。为让开发板也支持这些函数需要把USART发送和接收函数添加到这些函数的内部函数内。在C语言HAL库中,fputc函数是printf函数内部的一个函数,功能是将字符ch写入到文件指针f所指向文件的当前写指针位置。fgetc函数与fputc函数非常相似,实现字符读取功能。在使用scanf函数时需要注意字符输入格式。文中引入可使用#if …… #elif …… #endif方式调试代码。_串口阻塞https://blog.csdn.net/qcmyqcmy/article/details/130674914

基础篇007. 串行通信(二)--中断方式接收数据_串口设备通信0xffff-CSDN博客文章浏览阅读2.1k次。目录1. 实验任务2. 硬件原理3. 利用STM32CubeMX创建MDK工程3.1 STM32CubeMX工程创建3.2 配置调试方式3.3 配置时钟电路3.4 配置GPIO3.5 配置串口参数3.6 配置时钟3.7 项目配置4. 串行通信实验4.1 UART串口printf,scanf函数串口重定向4.2 开启中断4.3 中断回调函数4.4 main()函数修改5.调试与验证6.总结利用STM32CubeMX,创建MDK工程,使用中断方式,实现串口接收数据,然后在转发到串口。本实验是串行通信的第二部分,_串口设备通信0xffffhttps://blog.csdn.net/qcmyqcmy/article/details/130716056

3.2 使用FreeRTOS任务编写代码

在freertos.c中的任务函数里面写相应的程序

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "usart.h"
/* USER CODE END Includes */

84a54a428adf42bea6fff2f6e7de2841.png

/* USER CODE BEGIN Variables */
uint8_t USART1_BUF[] = "Hello FreeRTOS\r\n";
/* USER CODE END Variables */

825a2e34c8a748c19a8ef4aea6a07edd.png

/* USER CODE BEGIN Header_StartTask01 */
/*** @brief  Function implementing the myTask01 thread.* @param  argument: Not used* @retval None*/
/* USER CODE END Header_StartTask01 */
void StartTask01(void *argument)
{/* USER CODE BEGIN StartTask01 *//* Infinite loop */for(;;){HAL_GPIO_TogglePin(LED_GPIO_Port,LED_Pin);osDelay(1000);}/* USER CODE END StartTask01 */
}

0091760d0cff49308bfad957353a4324.png

/* USER CODE BEGIN Header_StartTask02 */
/**
* @brief Function implementing the myTask02 thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_StartTask02 */
void StartTask02(void *argument)
{/* USER CODE BEGIN StartTask02 *//* Infinite loop */for(;;){printf("USART1: %s", USART1_BUF);osDelay(1000);}/* USER CODE END StartTask02 */
}

40ef596dc8364a5fa6be11b2f5d66979.png

 

一点说明:

main.c函数中,osKernelStart()是任务调度函数,通过它可以进入操作系统,注释该语句后,程序就可进入后面的while语句了。

  /* Start scheduler */osKernelStart();

b71ec3c652d24e98807c85cd39ebb7ea.png

 

3.3  运行效果

待补充...

 

4 多任务相关知识

4.1 任务基础知识

 

单片机裸机(未使用系统)运行时,一般都是在main函数中用循环来处理所有事件,循环调用相应的函数完成事件的处理。有时候也可以通过中断完成一些处理。相对多任务系统而言,这种就是单任务系统,也称作前后台系统,中断服务函数作为前台程序,大循环while(1)作为后台程序。

e7fc79b8aba64298b89ad3f8a1e57c5e.png

多任务系统会把大问题划成很多的小问题,逐个将小问题解决掉,大问题也就会随之解决。这些小问题是并发处理的,并不是说同一时刻一起执行很多任务,而是由于每个任务执行的时间很短,看起来像同一时刻执行了很多任务。通过FreeRTOS里面的任务调度器完成任务的先后执行。在FreeRTOS中是一个抢占式的实时多任务系统,其任务调度器也是抢占式的。

20f9db76ef6446468682c7daa3a07bb1.png

高优先级的任务可以打断低优先级任务的运行而取得CPU的使用权,这样就保证了那些紧急任务的运行。高优先级的任务执行完成以后重新把CPU的使用权归还给低优先级的任务,这个就是抢占式多任务系统的基本原理。

4.2 任务状态

FreeRTOS中的任务永远只有运行态、就绪态、阻塞态、挂起态。任务状态图切换如下:

095c5619c6e14cf2a3e937f7513ac29a.png

(1)运行态

当一个任务正在运行时,那么就说这个任务处于运行态,处于运行态的任务就是当前正在使用处理器的任务。如果使用的是单核处理器的话那么不管在任何时刻永远都只有一个任务处于运行态。

(2)就绪态

处于就绪态的任务是那些已经准备就绪(这些任务没有被阻塞或者挂起),可以运行的任务,但是处于就绪态的任务还没有运行,因为有一个同优先级或者更高优先级的任务正在运行!

(3)阻塞态

如果一个任务当前正在等待某个外部事件的话就说它处于阻塞态,比如说如果某个任务调用了函数vTaskDelay0的话就会进入阻塞态,直到延时周期完成。任务在等待队列、信号量、事件组、通知或互斥信号量的时候也会进入阻塞态。任务进入阻塞态会有一个超时时间,当超过这个超时时间任务就会退出阻塞态,即使所等待的事件还没有来临!

(4)挂起态

像阻塞态一样,任务进入挂起态以后也不能被调度器调用进入运行态,但是进入挂起态的任务没有超时时间。任务进入和退出挂起态通过调用函数vTaskSuspend()和xTaskResume()。

4.3 任务优先级

每个任务都可以分配一个从0~(configMAX_PRIORITIES-1)的优先级,configMAX_PRIORITIES在文件FreeRTOSConfig.h中有定义。如果所使用的硬件平台支持类似计算前导零这样的指令(可以通过该指令选择下一个要运行的任务,Cortex-M处理器是支持该指令的),并且宏configUSE_PORT_OPTIMISED_TASK_SELECTION也设置为了1,那么宏configMAX_PRIORITIES不能超过32!也就是优先级不能超过32级。其他情况下宏configMAX_PRIORITIES可以为任意值,但是考虑到RAM的消耗,宏configMAX_PRIORITIES最好设置为一个满足应用的最小值。优先级数字越低表示任务优先级越低,0的优先级最低,configMAX_PRIORITIES-1的优先级最高。空闲任务的优先级最低,为0。FreeRTOS调度器确保处于就绪态或运行态的高优先级的任务获取处理器使用权,换句话说就是处于就绪态的最高优先级的任务才会运行。当宏configUSE_TIME_SLICING定义为1的时候多个任务可以共用一个优先级,数量不限。默认情况下宏configUSE_TIME_SLICING在文件FreeRTOS.h中已经定义为1。此时处于就绪态的优先级相同的任务就会使用时间片轮转调度器获取运行时间。

4.4 任务实现

在使用FreeRTOS的过程中,需要使用xTaskCreat()或者xTaskCreatStatic()来创建任务,这两个函数的第一个参数为pxTaskCode,就是任务函数本体。任务函数就是完成本任务工作的函数。FreeRTOS官方给出的任务函数模板为:

void vATaskFunction(void *pvParameters){        (1)for(;;){                                    (2)--任务应用程序--                          (3)vTaskDelay();                            (4)
}VTaskDelete(NULL);                          (5)
}

(1)、任务函数本质也是函数,所以肯定有任务名什么的,不过这里要注意:任务函数的返回类型一定要为void类型,也就是无返回值,而且任务的参数也是void指针类型的!任务函数名可以根据实际情况定义。

(2)、任务的具体执行过程是一个大循环,for(;;)就代表一个循环,作用和while(1)一样,笔者习惯用while(1)。

(3)、循环里面就是真正的任务代码了,此任务具体要干的活就在这里实现!

(4)、FreeRTOS的延时函数,此处不一定要用延时函数,其他只要能让FreeRTOS发生任务切换的API函数都可以,比如请求信号量、队列等,甚至直接调用任务调度器。只不过最常用的就是FreeRTOS的延时函数。

(5)、任务函数一般不允许跳出循环,如果一定要跳出循环的话在跳出循环以后一定要调用函数vTaskDelete(NULL)删除此任务!FreeRTOS的任务函数和UCOS的任务函数模式基本相同的,不止FreeRTOS,其他RTOS的任务函数基本也是这种方式的。

 

 

 

 

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

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

相关文章

【JavaEE】网络初识 (IP地址, 端口号, 协议, 封装和分用)

文章目录 前言网络通信基础一.IP地址概念格式特殊IP 二.端口号概念注意事项 三.协议概念知名协议的默认端口五元组协议分层OSI七层模型TCP/IP五层模型 四.封装和分用 前言 本章来介绍一下网络中的一些基本概念, 例如 : IP地址, 端口号, 协议, 协议分层, 封装, 分用等等. 网络…

计组原理:系统概论与基本组成

系统概论与基本组成 系统概论硬件软件 计算机系统的层次结构系统复杂性的管理方法1:抽象 计算机的基本组成冯诺依曼计算机系统复杂性的管理方法 2:(3’Y) 计算机的工作步骤上机前的准备:计算机的解题过程存储器的基本组…

AI教我学编程之C#类的实例化与访问修饰符

前言 在这篇文章中,我将带大家深入了解C#编程语言的核心概念,包括类的实例化、访问修饰符的应用,以及C#中不同数据类型的默认值。我会通过逐步分析和具体实例,详细解释如何在C#中正确创建和操作对象,并探讨如何通过访…

维基百科推广的12种方法帮你建立强大的品牌-华媒舍

维基百科是全球最大、最权威的多语言网络百科全书。它是许多人搜索信息、获取知识的首选平台,也是许多品牌建立强大影响力的重要途径。本文将介绍维基百科推广的12种方法,帮助你在维基百科上建立强大的品牌形象。 1. 准备工作 在开始维基百科推广之前&a…

IDEA怎么用Devtools热部署

IDEA怎么用Devtools热部署 大家知道在项目开发过程中,有时候会改动代码逻辑或者修改数据结构,为了能使改动的代码生效,往往需要重启应用查看改变效果,这样会相当耗费时间。 重启应用其实就是重新编译生成新的Class文件&#xff0…

机器学习:何为监督学习和无监督学习

目录 一、监督学习 (一)回归 (二)分类 二、无监督学习 聚类 一、监督学习 介绍:监督学习是指学习输入到输出(x->y)映射的机器学习算法,监督即理解为:已知正确答案…

C语言总结十一:自定义类型:结构体、枚举、联合(共用体)

本篇博客详细介绍C语言最后的三种自定义类型,它们分别有着各自的特点和应用场景,重点在于理解这三种自定义类型的声明方式和使用,以及各自的特点,最后重点掌握该章节常考的考点,如:结构体内存对齐问题&…

C++PythonC# 三语言OpenCV从零开发(5):ROI截取

文章目录 前言ROI测试图片部分区域截取CCsharpPython 颜色区域分割CCsharpPython 颜色通道合并CCsharpPython 总结 前言 C&Python&Csharp in OpenCV 专栏 【2022B站最好的OpenCV课程推荐】OpenCV从入门到实战 全套课程(附带课程课件资料课件笔记&#xff09…

Mybatis Plus baomidou EasyCode插件自动生成驼峰字段实体类,而不是全小写字段实体类

开发环境: springboot 2.4.3baomidou 3.4.0mybatis plus 3.4.0jdk8 问题描述: 1、mybatis 使用baomidou 插件,EasyCode自动生成实体类,但字段都是全部小写的,不太符合编码规范。 2、mysql表字段全是驼峰&#xff0c…

大数据技术原理及应用课实验3 :熟悉常用的HBase操作

目录 实验3 熟悉常用的HBase操作 一、实验目的 二、实验平台 三、实验步骤(每个步骤下均需有运行截图) (一)编程实现以下指定功能,并用Hadoop提供的HBase Shell命令完成相同任务: 1.列出HBase所有的表…

科大讯飞将于1月30日发布星火大模型 V3.5,基于全国产化算力底座训练

科大讯飞即将发布全新AI大模型——星火认知大模型 V3.5,该模型将于14:00正式发布。据透露,相比于去年10月24日发布的V3.0版本,V3.5在逻辑推理、文本生成、数学答题及小样本学习能力上均实现了显著提升。 科大讯飞官网链接:讯飞星…

Leetcode的AC指南 —— 栈与队列:20. 有效的括号

摘要: **Leetcode的AC指南 —— 栈与队列:20. 有效的括号 **。题目介绍:给定一个只包括 ‘(’,‘)’,‘{’,‘}’,‘[’,‘]’ 的字符串 s ,判断字符串是否有效。 有效字…

CMeet系列技术生态沙龙---城市开发者组织年度聚会·杭州 《把握未来趋势,持续学习创新》

CSDN始终致力于促进城市区域内尖端新兴技术开发者交流,提供开放自由的切磋平台。在这个充满挑战和机遇的一年即将结束之际,通过本次聚会,汇聚杭州本地各行各业的开发者朋友,回顾过去一年城市社区的成就和收获,感谢携手同行的各位,…

makefile的机制,执行命令的流程分析

makefile的机制,流程分析 calc:add.o sub.o multi.ogcc add.o sub.o multi.o calc.cpp -o calcadd.o:add.cppgcc -c add.cpp -o add.osub.o:sub.cppgcc -c sub.cpp -o sub.omulti.o:multi.cppgcc -c multi.cpp -o multi.oclean:rm -rf *.o calc按照这个例子分析&am…

常见网站结构

网站架构与部署架构 1、初始阶段的网站架构 一般来讲,大型网站都是从小型网站发展而来,一开始的架构都比较简单,随着业务复杂和用户量的激增,才开始做很多架构上的改进。当它还是小型网站的时候,没有太多访客&#…

数据结构之栈和队列

数据结构之栈和队列 1、栈1.1、栈的定义及基本运算1.2、栈的存储结构 2、队列2.1、队列的定义及基本运算2.2、队列的存储结构2.3、队列的应用 数据结构是程序设计的重要基础,它所讨论的内容和技术对从事软件项目的开发有重要作用。学习数据结构要达到的目标是学会从…

FDM3D打印系列——宝可梦妙蛙种子

fdm打印妙蛙种子 大家好,我是阿赵。   每次打印3D模型,都有新的感觉,这次打印了个宝可梦里面的妙蛙种子,也就是俗称的蒜头王八。   先来看看成果,然后在后面再聊一下关于3D打印的一些体会。使用创想三维的Sermoon …

华为机考入门python3--(0)测试题1-句子平均重量

分类:字符串 知识点: 获取输入 input().strip().split(" ") 拼接列表 " ".join(list) 输出指定位数的浮点数 print("%.2f" % value) 题目来自【华为招聘模拟考试】 # If you need to import additional packages or c…

Dell戴尔XPS 8930笔记本电脑原装Win10系统 恢复出厂预装OEM系统

链接:https://pan.baidu.com/s/1eaTQeX-LnPJwWt3fBJD8lg?pwdajy2 提取码:ajy2 原厂系统自带所有驱动、出厂主题壁纸、系统属性联机支持标志、系统属性专属LOGO标志、Office办公软件、MyDell等预装程序 文件格式:esd/wim/swm 安装方式&am…

一文梳理金融风控建模全流程(Python)

▍目录 一、简介 风控信用评分卡简介 Scorecardpy库简介 二、目标定义与数据准备 目标定义 数据准备 三、安装scorecardpy包 四、数据检查 五、数据筛选 六、数据划分 七、变量分箱 卡方分箱 手动调整分箱 八、建立模型 相关性分析 多重共线性检验VIF KS和AUC …