【STM32】FreeRTOS的移植(一)(详细流程)

发布于:2025-07-28 ⋅ 阅读:(18) ⋅ 点赞:(0)

第一部分:FreeRTOS移植

这篇文章详细的讲述了如何将 FreeRTOS 移植到 STM32F1xx(以 STM32F103 为例) 的过程。你可以在你的工程创建中,按照步骤整理出完整的移植流程(并且我提供了测试任务,编写了创建说明),方便你学习和 创建FreeRTOS的实例 参考。

1、FreeRTOS 移植步骤

1.1 准备基础工程:

选择一个稳定可用的 STM32 工程作为基础。
这里我推荐使用“跑马灯实验”作为模板,因为其结构简单、易于调试。

1.2 获取 FreeRTOS 源码:

(1)、FreeRTOS官网下载。
(2)、固件库工程模板。

在这里插入图片描述
在这里插入图片描述

1.3 示例工程路径选择:

FreeRTOS 提供了丰富的示例,推荐从 Demo 文件夹中查找对应 MCU 的例程
STM32F103 示例路径如图 1.3.2.2 所示:
FreeRTOS\FreeRTOSvX.X.X\FreeRTOS\Demo\CORTEX_STM32F103_Keil

在这里插入图片描述


1.4 工程结构搭建

从零开始创建一个FreeRTOS例程

1 、准备基础工程
要移植 FreeRTOS,肯定需要一个基础工程,基础工程越简单越好,这里我们用的基础例程中的跑马灯实验来作为基础工程。

2、FreeRTOS 系统源码
FreeRTOS 系统源码已经详细的讲解过如何获取了,这里我们会将 FreeRTOS 的系统源码放到资料中去,路径为:资料->FreeRTOS 资料->FreeRTOS 源码

添加 FreeRTOS 源码

📁 1. 创建 FreeRTOS 文件夹(如下图):

在你的基础工程中添加 FreeRTOS 文件夹,用于放置 RTOS 所有源文件。
在这里插入图片描述

📁 2. 添加源码文件:

然后,创建 FreeRTOS 文件夹以后就可以将 FreeRTOS 的源码添加到这个文件夹中:

将以下内容复制到 FreeRTOS 文件夹:

include/
portable/
croutine.c
event_groups.c
list.c
queue.c
tasks.c
timers.c

在这里插入图片描述

📁 3. 精简 portable 目录:

只保留与 STM32 + Keil 相关的三个文件夹:

Keil/
MemMang/
RVDS/

进入 portable 文件夹,我们只需要留下 keilMemMangRVDS 这三个文件夹,其他的都可以删除掉:
在这里插入图片描述

🗂️ 4. 在 Keil 中新建分组:

打开基础工程,新建分组 FreeRTOS_CORE 和 FreeRTOS_PORTABLE,然后向这两个分组中添加文件:

FreeRTOS_CORE:添加核心 C 文件
FreeRTOS_PORTABLE:添加 port.cheap_4.c

在这里插入图片描述

1.5 添加头文件路径

添加完 FreeRTOS 源码中的 C 文件以后还要添加 FreeRTOS 源码的头文件路径:
在 Keil 中添加以下路径到 Include Paths

.\FreeRTOS\include
.\FreeRTOS\portable\RVDS\ARM_CM3

在这里插入图片描述

1.6 配置中断函数

FreeRTOS 会使用以下三个中断函数:

void SVC_Handler(void)
void PendSV_Handler(void)
void SysTick_Handler(void)

⚠️ 注意:不要在 startup 文件或 stm32f10x_it.c 中重复定义,否则会报错:
Error: L6200E: Symbol PendSV_Handler multiply defined


解决方法:注释掉默认的这三个 Handler 定义,只保留 FreeRTOS 中定义的。

在这里插入图片描述

配置好后,文件结构为:

在这里插入图片描述

使用FreeRTOS的 SysTick 调度器

在这里插入图片描述


第二部分:FreeRTOS 移植测试代码编写

1、FreeRTOS系统配置(宏配置(FreeRTOSConfig.h))

如果要使用静态方法的话需要将宏:打开 FreeRTOSConfig.h,启用静态任务创建功能:

#define configSUPPORT_STATIC_ALLOCATION    1
2、任务创建和删除实验(静态方法)
1、实验目的
学习 xTaskCreateStatic ()和 vTaskDelete()这两个函数的使用 ,即静态方法创建任务。

2、设计实验
本实验设计三个任务: start_task、 task1_task 和 task2_task ,这三个任务的任务功能如下:
start_task:用来创建其他两个任务。
task1_task :当此任务运行 5 此以后就会调用函数 vTaskDelete()删除任务 task2_task,此任务也会控制 LED0 的闪烁,并且周期性的刷新 LCD 指定区域的背景颜色。
task2_task : 此任务普通的应用任务,此任务也会控制 LED1 的闪烁。

测试任务设计要求(实现 3 个任务 + 1 个浮点测试任务):

任务名 优先级 堆栈大小(x4) 说明
start_task 3 128 创建其他任务
led0_task 4 128 控制 LED0 闪烁
led1_task 5 128 控制 LED1 闪烁
float_task 6 128 测试 FPU 与调度
3、创建任务结构(静态)
StaticTask_t xTaskBuffer;
StackType_t xStack[128];

xTaskCreateStatic(TaskFunction, "TaskName", 128, NULL, 3, xStack, &xTaskBuffer);
4、删除任务函数使用
vTaskDelete(NULL); // 删除当前任务
vTaskDelete(xHandle); // 删除指定任务
问题排查:
问题							原因									解决方案
编译报重复定义 Handler		startup 文件中重复定义中断函数			注释掉 startup 中定义
堆栈溢出						任务堆栈太小							增加任务堆栈大小
LED 不闪						任务没执行							检查任务是否创建成功,调度器是否启动
测试:
1、FreeRTOS测试软件设计
	2.1、测试软件设计要求:
	(1)、创建一个start_task任务,Start任务用来创建其他任务。
	(2)、创建一个led0_task任务,用来控制LED0的亮灭。
	(3)、创建一个led1_task任务,用来控制LED1的亮灭。

在这里插入图片描述

因为内容篇幅有限,下一篇文章承接此文,继续完成 FreeRTOS 的代码部分(提供完整项目实例代码),编写完整的 FreeRTOS 测试软件设计 的核心部分 —— 任务创建与实现。 构建一个包含 3 个任务的基础多任务系统。

以上,欢迎有从事同行业的电子信息工程、互联网通信、嵌入式开发的朋友共同探讨与提问,我可以提供实战演示或模板库。希望内容能够对你产生帮助!


网站公告

今日签到

点亮在社区的每一天
去签到