实时操作系统
将 FreeRTOS 移植到 STM32F103C8T6 工程中需要以下步骤,以 Keil MDK 开发环境为例:
1. 准备工程和 FreeRTOS 源码
(1) 创建/打开现有 STM32F103 基础工程
-
确保工程已正确配置时钟、GPIO 等基础外设(例如使用标准库或 HAL 库)。
-
创建文件夹
freertos
里面包含inc
,src
,port
三个子文件夹
(2) 下载 FreeRTOS 源码
- 官网下载:FreeRTOS.org
这个版本
2. 添加 FreeRTOS 文件到工程
(1) 复制 FreeRTOS 核心文件到工程目录
- 将以下文件从 FreeRTOS 源码复制到工程文件夹(例如
test_01/freertos
):-
FreeRTOS/Source/*.c
(核心文件:croutine.c
,tasks.c
,queue.c
,list.c
,timers.c
,event_groups.c
)到src
文件夹 -
FreeRTOS/Source/include/
(头文件:croutine.h
,deprecated_definitions.h
,event_groups.h
,FreeRTOS.h
,list.h
,
mpu_prototypes.h
,mpu_wrappers.h
,portable.h
,projdefs.h
,queue.h
,semphr.h
,stack_macros.h
,StackMacros.h
,task.h
,timers.h
)到inc
文件夹 -
FreeRTOS/Source/portable/[编译器]/ARM_CM3
(针对 Cortex-M3 的移植层文件,如port.c
和portmacro.h
)到port
文件夹- Keil 编译器路径:
FreeRTOS/Source/portable/RVDS/ARM_CM3
- Keil 编译器路径:
-
FreeRTOS/Source/portable/MemMang/
(文件:heap_4.c
)到port
文件夹 -
FreeRTOS/Demo/CORTEX_STM32F103_Keil/
(头文件:FreeRTOSConfig.h
)到freertos
-
(2) 在 Keil 工程中添加文件
- 右键工程 → Add Group,创建
freerots/inc
、freerots/port
和freerots/src
组。 - 向
freerots/src
添加核心源文件:croutine.c
,tasks.c
,queue.c
,list.c
,timers.c
,event_groups.c
。
- 向
freerots/port
添加移植层文件:port.c
,heap_4.c
。
- 向
freerots/inc
添加头文件:croutine.h
,deprecated_definitions.h
,event_groups.h
,FreeRTOS.h
,list.h
,
mpu_prototypes.h
,mpu_wrappers.h
,portable.h
,projdefs.h
,queue.h
,semphr.h
,stack_macros.h
,StackMacros.h
,task.h
,timers.h
还有FreeRTOSConfig.h
。
3. 配置 FreeRTOS
(1) 修改FreeRTOSConfig.h
-
在末尾增加关键配置(示例):
#define xPortPendSVHandler PendSV_Handler #define vPortSVCHandler SVC_Handler #define xPortSysTickHandler SysTick_Handler
(2) 包含头文件路径
- 在 Keil 的工程选项(Options for Target → C/C++ → Include Paths)中添加:
../test_01/freertos
../test_01/freertos/inc
../test_01/freertos/src
../test_01/freertos/port
(3) 注释代码
-
注释
stm32f10x_it.c
第108
行的SVC_Handler
函数,第126
行的PendSV_Handler
函数,第135
行的SysTick_Handler
函数
-
FreeRTOS 已在
port.c
中实现了这些中断服务函数。
4. 编写测试任务
(1) 创建简单任务
在 main.c
中添加以下代码:
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "OLED.h"
#include "freertos.h"
#include "task.h"
TaskHandle_t Task1Handler;
TaskHandle_t Task2Handler;
// 任务1:闪烁 LED1
void Task1(void *pvParameters) {
while(1) {
GPIO_WriteBit(GPIOC, GPIO_Pin_13, Bit_SET);
vTaskDelay(500);
GPIO_WriteBit(GPIOC, GPIO_Pin_13, Bit_RESET);
vTaskDelay(500);
}
}
// 任务2:闪烁 LED2
void Task2(void *pvParameters) {
while(1) {
GPIO_WriteBit(GPIOA, GPIO_Pin_1, Bit_SET);
vTaskDelay(300);
GPIO_WriteBit(GPIOA, GPIO_Pin_1, Bit_RESET);
vTaskDelay(300);
}
}
int main(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &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);
// 创建任务(推荐带句柄 + 合理栈大小)
xTaskCreate(Task1, "Task1", 512, NULL, 1, &Task1Handler);
xTaskCreate(Task2, "Task2", 512, NULL, 1, &Task2Handler);
// 启动调度器
vTaskStartScheduler();
while (1)
{
}
}
通过以上步骤,FreeRTOS 即可成功运行在 STM32F103C8T6 上,实现多任务调度!