第03章 FreeRTOS移植
约 982 字大约 3 分钟
2026-01-19
3.1 移植源码
文件移植:
1. 拷贝 FreeRTOS/Source 文件夹中的 7个.c 文件
2. 拷贝 FreeRTOS/Source/include 文件夹
3. 拷贝 FreeRTOS/Source/portable/RVDS/ARM_CM3 文件夹中的 2个 .c 源文件
4. 拷贝 FreeRTOS/Source/portable/RVDS/MemMang 文件夹中的 heap_4.c 文件
5. 拷贝 FreeRTOS/Demo/CORTEX_STM32F103_Keil 文件夹中的 FreeRTOSConfig.h 文件最终我们项目中的FreeRTOS部分目录结构如下:
📦FreeRTOS
┣ 📂include
┃ ┣ 📜atomic.h
┃ ┣ 📜croutine.h
┃ ┣ 📜deprecated_definitions.h
┃ ┣ 📜event_groups.h
┃ ┣ 📜FreeRTOS.h
┃ ┣ 📜list.h
┃ ┣ 📜message_buffer.h
┃ ┣ 📜mpu_prototypes.h
┃ ┣ 📜mpu_wrappers.h
┃ ┣ 📜portable.h
┃ ┣ 📜projdefs.h
┃ ┣ 📜queue.h
┃ ┣ 📜semphr.h
┃ ┣ 📜StackMacros.h
┃ ┣ 📜stack_macros.h
┃ ┣ 📜stdint.readme
┃ ┣ 📜stream_buffer.h
┃ ┣ 📜task.h
┃ ┗ 📜timers.h
┣ 📂portable
┃ ┣ 📜heap_4.c
┃ ┣ 📜port.c
┃ ┗ 📜portmacro.h
┣ 📜croutine.c
┣ 📜event_groups.c
┣ 📜FreeRTOSConfig.h
┣ 📜list.c
┣ 📜queue.c
┣ 📜stream_buffer.c
┣ 📜tasks.c
┗ 📜timers.c3.2 修改配置
FreeRTOSConfig.h 中添加如下3个配置:
// 宏替换:将FreeRTOS提供的中断服务函数名称替换为标准的STM32中断服务函数的名称
#define xPortPendSVHandler PendSV_Handler
#define vPortSVCHandler SVC_Handler
#define xPortSysTickHandler SysTick_Handler如果时基单元和FreeRTOS共用SysTick,SysTick 中断服务函数需要按照下面方式修改:
stm32f10xx_it.c 中修改 SysTickHandler() 函数,
#include "FreeRTOS.h" // FreeRTOS 需要在 tasks.h 之前包含
#include "task.h"
extern void xPortSysTickHandler(void);
void SysTick_Handler(void)
{
if(xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED)
{
xPortSysTickHandler();
}
}3.3 源码介绍
① 配置项
FreeRTOSConfig.h 配置文件作用:对FreeRTOS的功能进行配置和裁剪,以及API函数的使能等。
官网中文说明:https://www.freertos.org/zh-cn-cmn-s/a00110.html
整体的配置项可以分为三类:
INCLUDE开头:一般是“INCLUDE_函数名”,函数的使能,1表示可用,0表示禁用。
config开头:FreeRTOS的一些功能配置,比如基本配置、内存配置、钩子配置、中断配置等。
其他配置:PendSV宏定义、SVC宏定义。② 类型定义
TickType_t
#if ( configUSE_16_BIT_TICKS == 1 )
typedef uint16_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffff
#else
typedef uint32_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffffffffULBaseType_t
typedef long BaseType_t;UBaseType_t
typedef unsigned long UBaseType_t;StackType_t
#define portSTACK_TYPE uint32_t
typedef portSTACK_TYPE StackType_t;③ 命名规范
变量
(1)变量名称使用驼峰式大小写,具有明确的描述性,并使用完整的单词(没有缩写,但普遍接受的缩写除外)。
(2)uint32_t 类型变量以 ul 为前缀,其中“u”表示“unsigned” ,“l”表示“long”。
(3)uint16_t 类型变量以 us 为前缀,其中“u”表示“unsigned” , “s”表示“short”。
(4)uint8_t 类型变量以 uc 为前缀,其中“u”表示“unsigned” , “c”表示“char ”。
(5)非 stdint 类型的变量以 x 为前缀。例如,BaseType_t 和 TickType_t,二者分别是可移植层定义的定义类型,主要架构的自然类型或最有效类型,以及用于保存 RTOS ticks 计数的类型。
(6)非 stdint 类型的无符号变量存在附加前缀 u。例如,UBaseType_t(无符号的BaseType_t)类型变量以 ux 为前缀。
(7)size_t 类型变量也带有 x 前缀。
(8)枚举变量以 e 为前缀
(9)指针以附加 p 为前缀,例如,指向 uint16_t 的指针将以 pus 为前缀。
(10)根据 MISRA 指南,无符号 char 类型仅可包含 ASCII 字符,并以 c 为前缀。
(11)根据 MISRA 指南,char * 类型变量仅可包含指向 ASCII 字符串的指针,并以 pc 为前缀。函数
(1)函数名称使用驼峰式大小写,具有明确的描述性,并使用完整的单词(无缩写,但普遍接受的缩写除外)。
(2)文件作用域静态(私有)函数以 prv 为前缀。
(3)根据变量定义的相关规定,API 函数以其**返回类型为前缀**,并为 void 添加前缀 v。
(4)API 函数名称以定义 API 函数文件的名称开头。比如一个函数 vTaskDelay , 从函数名可以得到如下信息:v表示这个函数的返回值是void, Task表示这个函数定义在Task.c文件中, Delay表示函数的功能
宏
(1)宏具有明确的描述性,并使用完整的单词(无缩写,但普遍接受的缩写除外)。
(2)宏以定义宏的文件为前缀。前缀为小写。例如,在 FreeRTOSConfig.h 中定义 configUSE_PREEMPTION。
(3)除前缀外,所有宏均使用大写字母书写,并使用下划线来分隔单词。