【FreeRTOS】使用CubeMX快速移植FreeRTOS工程到蓝桥杯开发板(STM32G431RBT6)

news2024/11/28 9:37:29

使用CubeMX快速创建FreeRTOS工程到蓝桥杯开发板(STM32G431RBT6)

  • CubeMX配置
    • CubeMX基础工程的配置
    • ☆FreeRTOS相关配置
    • FreeRTOS配置选项卡的解释
  • 软件工程架构与程序设计
  • 小综合:任务的创建删除、挂起与恢复设计
    • cubexMX配置创建任务
    • 软件程序设计

  随着CubeMX软件的不断推广使用,STM32HAL库的使用也不断增加,并且某些系列开发板只支持HAL开发。最近参加完蓝桥杯后,继续深入学习FreeRTOS操作系统,但在移植RTOS的时候,大多数教程都是基于正点原子F系列开发板根据固件库或者HAL例程进行移植,移植过程相对比较复杂,因此特此整理一篇直接通过CubeMX生成的FreeRTOS工程教程到蓝桥杯的STM32G431RB系列的开发板中,方便后续通过蓝桥杯开发板深入学习RTOS操作系统。

  • 对于手动移植过程复杂且繁琐,对新手不友好。如有需要手动移植,可参照以下文章:
    1. FreeRTOS移植到STM32
    2. FreeRTOS移植stm32详细步骤介绍

CubeMX配置

对于CubeMX创建基础工程这里仅进行简单概述,详细步骤可参考:

1. STM32 CubeMX新建工程+GPIO的研究

2. Cubemx新建工程引脚配置与点亮LED

CubeMX基础工程的配置

使能外部高速时钟:

配置LED与按键引脚

配置开启调试串口

工程相关配置


☆FreeRTOS相关配置

更改/配置时钟源:

  1. 在 SYS 选项里,将 Debug 设为 Serial Wire,并且将 Timebase Source 设为TIM6(其它定时器也行)。
  2. 裸机的时钟源默认是 SysTick,但是开启FreeRTOS后,FreeRTOS会占用SysTick(用来生成1ms 定时,用于任务调度),所以需要需要为其他总线提供另外的时钟源。

使能FREERTOS选项
将 Interface 配置为CMSIS_V1,V2的内核版本更高,功能更多,在大多数情况下V1版本的内核完全够用

创建第二个任务

至此,FreeRTOS多任务工程已配置完毕,可直接生成工程代码!!!


FreeRTOS配置选项卡的解释

FreeRTOS 各配置选项卡的解释

  • Events:事件相关的创建
  • Task and Queues: 任务与队列的创建
  • Timers and Semaphores: 定时器和信号量的创建
  • Mutexes: 互斥量的创建
  • FreeRTOS Heap Usage: 用于查看堆使用情况
  • config parameters: 内核参数设置,用户根据自己的实际应用来裁剪定制FreeRTOS 内核
  • Include parameters: FreeRTOS 部分函数的使能
  • User Constants: 相关宏的定义,可以自建一些常量在工程中使用
  • Advanced settings:高级设置

内核配置、函数使能的一些翻译

查看用户堆的使用情况

FreeRTOS部分函数使能配置

内核参数设置,用户可根据自己的实际应用来裁剪定制FreeRTOS 内核

内核参数的理解内容非常多,可以参考以下文章:FreeRTOS内核配置说明

软件工程架构与程序设计

软件工程架构

主函数中初始化RTOS并且开启内核任务调度:

在app_freertos.c中创建任务,并实现对任务的具体实现

程序设计
通过CubeMX生成的FreeRTOS工程创建了2个任务,通过程序设计实现对两个LED灯分别以不同的时间周期进行闪烁。

LED翻转功能函数

void led_toggle(uint8_t led)
{
	HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);
	HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_8<<(led-1));
	HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
}

任务的具体实现

//任务1控制LED1小灯每秒闪烁一次
void StartDefaultTask(void const * argument)
{
  /* USER CODE BEGIN StartDefaultTask */
  /* Infinite loop */
  for(;;)
  {
	led_toggle(1);
    osDelay(250);
  }
  /* USER CODE END StartDefaultTask */
}

//任务2控制LED2小灯每500ms闪烁一次
void StartTask02(void const * argument)
{
  /* USER CODE BEGIN StartTask02 */
  /* Infinite loop */
  for(;;)
  {
	led_toggle(2);
    osDelay(500);
  }
  /* USER CODE END StartTask02 */
}

小综合:任务的创建删除、挂起与恢复设计

通过对FreeRTOS的理论基础知识及其系统的移植,通过设计按键控制任务的创建与删除,挂起与恢复巩固系统的移植与相关理论知识的。

  • 在此之前需掌握RTOS任务的调度、任务的状态以及任务的创建与删除相关理论基础知识:RTOS理论基础知识快速入门
  • 同时需要掌握通过CubeMX移植FreeRTOS工程,因为该实验建立在上述移植的工程上进行修改

设计要求描述:
创建 4 个任务:taskLED1,taskLED2,taskKEY1,taskKEY2,任务要求如下:
taskLED1:间隔 500ms 闪烁 LED1;
taskLED2:间隔 1000ms 闪烁 LED2;
taskKEY1:如果 taskLED1 存在,则按下 KEY1 后删除 taskLED1 ,否则创建 taskLED1 ;
taskKEY2:如果 taskLED2 正常运行,则按下 KEY2 后挂起 taskLED2 ,否则恢复 taskLED2

cubexMX配置创建任务

  通过设计要求分析,在tasks选项中创建四个任务,分别为taskLED01,taskLED02,taskKEY01,以及taskKEY02,将任务优先级均设置为相同的Normal优先级,代码创建定义设置为若定义,方便后续用户在user.c内对函数进行重写,其中创建方式如下图所示。
注意:由于创建的任务过多,会使得堆空间不够,因此这里将Interface设置为CMSIS_V2版本。

软件程序设计

任务一和任务二分别控制LED小灯以不同的时间周期进行闪烁

void taskLED01(void * argument)
{
	uint task1_num = 0;
	while(1)
	{
		led_toggle(1);
		osDelay(250);
		task1_num++;
		printf("task1 num:%d\r\n",task1_num);
	}
}
void taskLED02(void * argument)
{
	uint task2_num = 0;
	while(1)
	{
		led_toggle(2);
		osDelay(500);
		task2_num++;
		printf("task2 num:%d\r\n",task2_num);
	}
}

按键一任务控制LED1任务的创建与删除

void taskKEY01(void * argument)
{
	while(1)
	{
		//按下
		if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0) == 0)
		{
			//消抖
			osDelay(10);
			if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0) == 0)
			{
				//等待抬起
				while(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0) == 0);
				printf("key1 按下\r\n");
				if(taskLED1Handle != NULL)
				{
					//删除任务1
					osThreadTerminate(taskLED1Handle);
					taskLED1Handle = NULL;
					led_show(1,0);
					printf("taskLED01 删除成功\r\n");
				}
				else
				{
					//创建任务
					taskLED1Handle = osThreadNew(taskLED01, NULL, &taskLED1_attributes);
					if(taskLED1Handle != NULL)
						printf("taskLED01 创建成功\r\n");
					else
						printf("taskLED01 创建失败\r\n");
				}
			}
		}
		osDelay(10);
	}
}

按键二任务控制LED2任务的挂起与恢复

void taskKEY02(void * argument)
{
	static uchar key2_flag = 0;
	while(1)
	{
		//按下
		if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1) == 0)
		{
			//消抖
			osDelay(10);
			if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1) == 0)
			{
				//等待抬起
				while(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1) == 0);
				printf("key2 按下\r\n");
				//挂起
				if(key2_flag == 0)
				{
					osThreadSuspend(taskLED2Handle);
					printf("任务2已挂起\r\n");
				}
				//恢复
				else
				{
					osThreadResume(taskLED2Handle);
					printf("任务2已恢复\r\n");
				}
				key2_flag = !key2_flag;
			}
		}
		osDelay(10);
	}
}

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

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

相关文章

前端服务请求跨域被拦截,Java后端Springboot服务解决办法

跨域问题 跨域前端遇到的问题&#xff1a; Access to XMLHttpRequest at ‘http://www.xxx.xxxx/api/x/d/xc’ from origin ‘http://127.0.0.1:3000’ has been blocked by cors policy: No ‘Access-Contorl-Allow-Origin’ header is present on the requested resource. …

8.Jetson AGX Orin Ubuntu20.04 gRPC编译安装

Jetson AGX Orin Ubuntu20.04 gRPC编译安装 一、CMake版本检查 grpc编译cmake要求最低版本为3.15。首先&#xff0c;cmake -version 查看当前cmake版本&#xff0c;如果低于3.15&#xff0c;按照以下步骤进行安装。 1.1 卸载已经安装的旧版的CMake sudo apt-get autoremove…

Golang插件系统实现

插件可以在解耦的基础上灵活扩展应用功能&#xff0c;本文介绍了如何基于Golang标准库实现插件功能&#xff0c;帮助我们构建更灵活可扩展的应用。原文: Plugins with Go 什么是插件 简单来说&#xff0c;插件就是可以被其他软件加载的软件&#xff0c;通常用于扩展应用程序的功…

嵌入式学习56-ARM5(linux驱动启动程序)

知识零碎&#xff1a; bootm&#xff1a; 启动内核同时给内核传参 …

VAR:自回归家族文生图新SOTA,ImageNet上超越Diffusion与DiTs

一、背景&#xff1a; 在人工智能领域&#xff0c;尤其是计算机视觉和自然语言处理中&#xff0c;自回归&#xff08;AR&#xff09;大型模型&#xff08;如GPT系列&#xff09;因其强大的生成能力和在多种任务上的通用性而受到广泛关注。这些模型通过自监督学习策略&#xff0…

Android 性能优化(七):APK安装包体积优化

包体积优化重要性 移动 App 特别关注投放转化率指标&#xff0c;而 App 包体积是影响用户新增的重要因素&#xff0c;而 App 的包体积又是影响投放转化率的重要因素。 Google 2016 年公布的研究报告显示&#xff0c;包体积每上升 6MB 就会带来下载转化率降低 1%&#xff0c; …

获取公募基金净值【数据分析系列博文】

摘要 从指定网址获取公募基金净值数据&#xff0c;快速解析并存储数据。 &#xff08;该博文针对自由学习者获取数据&#xff1b;而在投顾、基金、证券等公司&#xff0c;通常有Wind、聚源、通联等厂商采购的数据&#xff09; 导入所需的库&#xff1a;代码导入了一些常用的库…

CSS3 伪元素与伪类选择器区别、详解与应用实例

伪元素与伪类两者都是通过在选择器后附加一个特定的关键字来定义&#xff0c;遵循相似的语法规则&#xff0c;并在 CSS 规则块中设置相应的样式。伪元素 能够通过 content 属性添加或替换内容。例如&#xff0c;:before 和 :after 可以插入文本、图像或其他生成的内容。伪类 仅…

Go 单元测试之Mysql数据库集成测试

文章目录 一、 sqlmock介绍二、安装三、基本用法四、一个小案例五、Gorm 初始化注意点 一、 sqlmock介绍 sqlmock 是一个用于测试数据库交互的 Go 模拟库。它可以模拟 SQL 查询、插入、更新等操作&#xff0c;并且可以验证 SQL 语句的执行情况&#xff0c;非常适合用于单元测试…

数据赋能(58)——要求:数据赋能实施部门能力

“要求&#xff1a;数据赋能实施部门能力”是作为标准的参考内容编写的。 在实施数据赋能中&#xff0c;数据赋能实施部门的能力体现在多个方面&#xff0c;关键能力如下图所示。 在实施数据赋能的过程中&#xff0c;数据赋能实施部门应具备的关键能力如下。 理性思维与逻辑分…

ES源码四:网络通信层流程

听说ES网络层很难&#xff1f;今天来卷它&#x1f604; 前言 ES网络层比较复杂&#xff0c;分为两个部分&#xff1a; 基于HTTP协议的REST服务端基于TCP实现的PRC框架 插件化设计的网络层模块&#xff08;NetworkModule&#xff09; 入口还是上一章的创建Node构造方法的地方…

如何爬出 Kotlin 协程死锁的坑?

作者&#xff1a;悬衡 一、前言 在 Java 中有一个非常经典的死锁问题, 就是明明自己已经占用了线程池, 却还继续去申请它, 自己等自己, 就死锁了, 如下图和代码: // 这段代码将死锁到天荒地老final ExecutorService executorService Executors.newSingleThreadExecutor();exe…

4月27日复旦大学-华盛顿大学EMBA项目教授分享暨招生说明会

复旦大学-华盛顿大学EMBA项目2024年4月27日精彩看点&#xff1a;      国际视野助推商业价值&#xff0c;“她力量”赋能管理      数字营销浪潮中&#xff0c;如何重新定义价值创造      主讲嘉宾    复旦大学-华盛顿大学EMBA项目教授分享暨招生说明会     …

Redmi Turbo 3新品发布,天星金融(原小米金融)优惠加持护航新机体验

Redmi新十年使命不变&#xff0c;挑战不断升级。Redmi Turbo 3&#xff0c;作为Turbo系列的开篇之作&#xff0c;将自身定位为新生代性能旗舰&#xff0c;决心重塑中端性能新格局。据悉&#xff0c;Redmi Turbo 3于4月10日已正式发布。预售期间更是连续数日&#xff0c;蝉联小米…

C++:文件内容完全读入

在上一篇文章中我留下了一点小坑&#xff1a;使用>> 运算符&#xff0c;这个运算符默认将空格作为分隔符&#xff0c;所以在文件内容读取的时候发现在读到空格时就会停止读取&#xff0c;导致读取内容不完整&#xff0c;这显然不符合日常的使用用能&#xff0c;那么今天就…

科学突破可能开创6G通信新时代

格拉斯哥大学开发的火柴盒大小的天线可以为全息通话、改进自动驾驶和更好的医疗保健的世界铺平道路。 格拉斯哥大学表示&#xff0c;这种创新的无线通信天线将超材料的独特特性与复杂的信号处理相结合&#xff0c;有助于构建未来的 6G 网络。 数字编码动态超表面天线&#xf…

python-flask结合bootstrap实现网页小工具实例-半小时速通版

参考&#xff1a; Python之flask结合Bootstrap框架快速搭建Web应用_支持bootstrap的python软件-CSDN博客 https://blog.csdn.net/lovedingd/article/details/106696832 Bootstrap 警告框 | 菜鸟教程 https://www.runoob.com/bootstrap/bootstrap-alert-plugin.html flask框架…

机器学习实验二-----决策树构建

决策树是机器学习中一种基本的分类和回归算法&#xff0c;是依托于策略抉择而建立起来的树。本文学习的是决策树的分类 1. 构建决策树流程 选择算法&#xff1a;常用的算法包括ID3、C4.5、CART等。 划分节点&#xff1a;根据数据特征和算法选择&#xff0c;递归地划分节点&…

C++算法题 - 矩阵

目录 36. 有效的数独54. 螺旋矩阵48. 旋转图像73. 矩阵置零289. 生命游戏 36. 有效的数独 LeetCode_link 请你判断一个 9 x 9 的数独是否有效。只需要 根据以下规则 &#xff0c;验证已经填入的数字是否有效即可。 数字 1-9 在每一行只能出现一次。 数字 1-9 在每一列只能出现…

Linux安装和使用Android Debug Bridge(ADB)

目录 1、开发环境和工具 2、ADB是什么&#xff1f; 3、安装ADB 3.1、使用包管理器安装 ADB 3.2、手动安装 ADB 4、使用ADB 4.1、连接设备 4.2、执行shell命令 4.3、安装应用程序 4.4、截取屏幕截图 4.5、模拟按键和手势 4.6、上传文件到Android设备 4.7、从Android设备下载文件…