第四章:Keil6建立一个工程文件夹(2025.3.31保姆级教程)
FreeRTOS移植详解
本文详细介绍了如何在STM32平台上移植FreeRTOS操作系统,包括源码获取、工程配置、文件修改等完整步骤。通过本文的学习,您将掌握FreeRTOS移植的关键技术点。
本文对应的工程代码已上传至GitHub:FreeRTOS移植工程
一、准备工作
1.1 打开工程文件夹
首先打开之前创建的keil6文件夹,准备进行FreeRTOS的移植工作。
1.2 下载FreeRTOS源码
访问FreeRTOS官网下载最新版本源码:
1.3 获取内核文档
在官网找到关于FreeRTOS内核的文档:
1.4 选择下载版本
点击下载FreeRTOS,选择最新版本FreeRTOS 202212.01(有条件也可以下载两个版本进行对比):
1.5 解压文件
将下载好的文件解压到创建的FreeRTOS目录下:
二、工程配置
2.1 创建新工程
- 新建一个002工程文件
- 将上节课的工程文件模板复制进来
- 添加FreeRTOS src和FreeRTOS portable文件夹
2.2 复制源文件
导航到...\FreeRTOSv202212.01\FreeRTOS\Source
,将所有.c文件复制到002的freertos src文件夹中:
2.3 复制移植文件
导航到...\FreeRTOSv202212.01\FreeRTOS\Source\portable
,将"MemMang"文件夹与"RVDS"文件夹拷贝到新建的freertos port文件夹中:
2.4 复制头文件
导航到...\FreeRTOSv202212.01\FreeRTOS\Source
,将include直接复制到工程文件夹并改名为freertos include:
2.5 整理文件结构
为了更好的文件组织,可以在002目录下新建一个FreeRTOS文件夹,并将刚才创建的三个文件夹放入其中:
2.6 配置FreeRTOSConfig.h
导航到...\FreeRTOSv202212.01\FreeRTOS\Demo\CORTEX_STM32F103_Keil
找到freertosconfig.h,将其复制到user文件夹下:
三、Keil工程配置
3.1 添加文件组
- 打开Keil,点击魔法棒右边的三个小箱子
- 添加freertos port组,添加以下文件:
...\Despacito\002\FreeRTOS\freertos portable\RVDS\ARM_CM3\port.c
...\Despacito\002\FreeRTOS\freertos portable\MemMang\heap_4.c
- 添加freertos src组,添加所有.c文件:
- 在user分组中添加FreeRTOSConfig.h文件:
3.2 配置头文件路径
点击魔法棒–>c/c++(AC6)–>include path,添加以下路径:
四、文件修改
4.1 修改FreeRTOSConfig.h
FreeRTOSConfig.h文件需要修改的内容不多,主要是:
- 修改开发板对应的头文件(如STM32F1系列使用
#include "stm32f10x.h"
) - 添加串口头文件
#include "stm32f10x_usart.h"
(用于断言操作打印信息)
4.2 修改stm32f10x_it.c
SysTick中断服务函数是FreeRTOS的心跳时钟,驱动着FreeRTOS的运行。FreeRTOS已经帮我们实现了:
- 在port.c中实现了
vPortSetupTimerInterrupt()
函数 - 实现了通用的
xPortSysTickHandler()
函数
我们只需要在stm32f10x_it.c中实现STM32平台上的SysTick_Handler()
函数即可。
同时,需要注释掉PendSV_Handler()
与SVC_Handler()
这两个函数,因为FreeRTOS已经在port.c中实现了xPortPendSVHandler()
与vPortSVCHandler()
函数。
/* 修改后的stm32f10x_it.c文件 */
#include "stm32f10x_it.h"
#include "FreeRTOS.h" //FreeRTOS使用
#include "task.h"
/* 其他代码保持不变 */
// 注释掉SVC_Handler
//void SVC_Handler(void)
//{
//}
// 注释掉PendSV_Handler
//void PendSV_Handler(void)
//{
//}
// 实现SysTick_Handler
void SysTick_Handler(void)
{
if(xTaskGetSchedulerState()!=taskSCHEDULER_NOT_STARTED) //系统已经运行
{
xPortSysTickHandler();
}
}
4.3 修改main.c
修改main.c文件,添加FreeRTOS相关头文件和初始化代码:
#include "stm32f10x.h"
#include "FreeRTOS.h"
#include "task.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_usart.h"
int main(void) {
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_13;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStruct);
while(1) {
GPIO_ResetBits(GPIOC, GPIO_Pin_13);
}
}
五、编译问题解决
5.1 常见编译错误
FreeRTOS移植编译错误主要由以下原因引起:
-
编译器版本与移植文件不兼容
__forceinline
关键字未识别:RVDS移植文件中的__forceinline
是ARM Compiler 5(AC5)特有的内联语法- 汇编语法错误:RVDS移植文件中的汇编指令语法与AC6不兼容
-
关键配置缺失
- 中断服务函数重命名问题
- 数据类型未定义
-
其他可能原因
- 中断优先级冲突
- 内存分配问题
5.2 解决方案
-
替换移植文件
- 删除portable/RVDS/ARM_CM3目录
- 复制FreeRTOS/portable/GCC/ARM_CM3中的文件到工程
- 更新Keil工程文件引用路径
-
修改编译器设置
- 在Keil的Options for Target → C/C++选项卡中:
- 使用AC5编译器
- 或启用AC6的GNU兼容模式
- 在Keil的Options for Target → C/C++选项卡中:
-
验证关键配置
// FreeRTOSConfig.h 关键配置示例
#define configUSE_TIMERS 1
#define configTIMER_TASK_PRIORITY (tskIDLE_PRIORITY + 3)
#define configTIMER_QUEUE_LENGTH 10
#define configKERNEL_INTERRUPT_PRIORITY 255
5.3 切换到GCC编译器
在Keil中切换到GCC编译器:
5.4 编译结果
编译后没有报错和警告,移植成功:
六、总结
通过以上步骤,我们成功完成了FreeRTOS在STM32平台上的移植。主要步骤包括:
- 获取并配置FreeRTOS源码
- 创建工程并添加必要文件
- 修改相关配置文件
- 解决编译问题
移植完成后,您就可以开始使用FreeRTOS进行开发了。FreeRTOS作为一个轻量级的实时操作系统,在嵌入式系统开发中有着广泛的应用。
七、参考资料
如果本文对您有帮助,欢迎点赞、收藏和关注!您的支持是我持续创作的动力。
第六章:freertosconfig.h核心函数详解(官方最新版,附FreeRTOSconfig.h归类完的完整中文注释)