1. 引言

2. 准备工作

  • 硬件需求
    • STM32F4XX开发板(本文以STM32F407为例)。
  • 软件需求
    • 开发环境:Keil MDK。
    • STM32标准外设库(版本1.8.0或更高)。
    • FreeRTOS源码(版本10.4.3或更高)。

3. 创建基础STM32F4标准库工程

  • 步骤详解
    • 在Keil MDK中新建工程,选择STM32F4XX芯片型号。
    • 添加标准外设库文件:启动文件、系统初始化代码、外设驱动。
    • 配置工程选项:设置编译器优化、链接脚本。

4. 集成FreeRTOS到工程

4.1 最新维护版本下载

FreeRTOS源码地址:\FreeRTOS-LTS\FreeRTOS\FreeRTOS-Kernel

在这里插入图片描述

4.2 历史版本下载

源码下载地址:https://github.com/FreeRTOS/FreeRTOS/releases/tag/202411.00
在这里插入图片描述

下面以最新源码进行部署!!!

4.3 核心目录结构

FreeRTOSv202406.04-LTS
├── FreeRTOS          # 内核源码及演示项目
│   ├── Source        # 实时内核源码
│   │   ├── include   # 核心头文件(task.h/queue.h等)
│   │   ├── portable  # 硬件/编译器适配层
│   │   │   └── RVDS/ARM_CM4F  # STM32F4 Cortex-M4F移植文件
│   │   │       ├── port.c       # 任务切换/中断处理底层代码
│   │   │       └── portmacro.h # 硬件寄存器定义
│   │   └── MemMang    # 内存管理算法
│   │       └── heap_4.c        # 动态内存分配方案
│   └── Demo          # 官方示例工程
│       └── CORTEX_STM32F4_Keil # STM32F4移植模板+配置文件
└── FreeRTOS-Plus     # 扩展功能库(可选)
  1. FreeRTOS-Kernel(内核源码)
    准备工作:
    准备三个文件夹用于对源码的重新分装,如下图所示:
    在这里插入图片描述

    • Source/include:头文件(如task.hqueue.h),定义API接口和内核数据结构。
      在这里插入图片描述

    • Source/portable:硬件/编译器适配层

    • RVDS/ARM_CM4F:STM32F4(Cortex-M4内核)的移植文件(如port.cportmacro.h),包含任务切换、中断处理等底层代码。
      在这里插入图片描述

    • MemMang:内存管理算法(如heap_4.c五选一),实现动态内存分配。
      在这里插入图片描述

    • Source:内核核心文件

      • tasks.c:任务管理
      • list.c:双向链表实现
      • queue.c:队列和信号量
      • timers.c:软件定时器
        在这里插入图片描述
  2. Demo/CORTEX_STM32F4_Keil:官方示例工程,含STM32F4的移植模板和配置文件(如\FreeRTOS-LTS\FreeRTOS\FreeRTOS-Kernel\examples\template_configuration\FreeRTOSConfig.h)。
    在这里插入图片描述

  3. FreeRTOS-Plus:扩展功能库(如TCP/IP、加密模块),可按需集成。

4.3 关键文件功能详解

  • FreeRTOSConfig.h:内核配置文件,需根据硬件定制

  • port.c:硬件适配核心

    • 实现任务上下文切换(xPortPendSVHandler)、SysTick中断处理等。
    • STM32F4需使用ARM_CM4F目录下的文件,支持FPU(浮点单元)。
  • heap_4.c:内存管理方案,提供动态内存分配和碎片合并。

4.4 STM32F4XX标准库部署步骤

  1. 源码集成
    • FreeRTOS-Kernel/Source全部文件添加至工程。
      在这里插入图片描述
    • 复制portable/RVDS/ARM_CM4F到工程目录,包含port.cportmacro.h
      在这里插入图片描述
    • 添加portable/MemMang/heap_4.c到工程。

在这里插入图片描述

  1. 配置文件调整
    • 在工程中创建FreeRTOSConfig.h,配置参数如:

      #define configCPU_CLOCK_HZ SystemCoreClock // 使用系统定义的时钟
      

      在这里插入图片描述

      编译错误:在 FreeRTOSConfig.h 中启用了 configCHECK_FOR_STACK_OVERFLOW,但没有实现 vApplicationStackOverflowHook 函数。

      .\Objects\Q3310-2035.axf: Error: L6218E: Undefined symbol vApplicationStackOverflowHook (referred from tasks.o).
      Not enough information to list image symbols.
      

      禁用栈溢出检查
      在这里插入图片描述

      编译错误:在Cortex-M3/M4处理器上,configMAX_SYSCALL_INTERRUPT_PRIORITY 必须设置为一个非零值,用于定义能够调用FreeRTOS API的中断的最高优先级。

      ..\..\FreeRTOS\port\port.c(42): error:  #35: #error directive: configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0.  See http: /*www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */
            #error configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0.  See http: /*www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */
      ..\..\FreeRTOS\port\port.c: 0 warnings, 1 error
      

      为什么这样设置?

      优先级数值范围:STM32F4使用4位优先级,范围是0-15(0最高,15最低)

      配置含义

      configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY = 5
      
      优先级 高于5 的中断:不能调用FreeRTOS API,不会被RTOS延迟
      
      优先级 5及以下 的中断:可以调用FreeRTOS API,可能被RTOS延迟
      

      典型分配:

      优先级0-4:用于系统关键中断(如SysTick、PendSV)
      
      优先级5-15:用于普通外设中断,可以安全调用FreeRTOS API
      

      快速修复检查清单

      ✅ 确保 configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 设置为 1-15 之间的值
      
      ✅ 确保 configLIBRARY_LOWEST_INTERRUPT_PRIORITY 设置为 15
      
      ✅ 确保 configPRIO_BITS 设置为 4(对于STM32F4)
      
      ✅ 重新编译工程
      

      在这里插入图片描述

      编译报错:configTICK_TYPE_WIDTH_IN_BITS 定义了系统节拍计数器(tick count)的位宽,但设置的值不被当前移植层支持。

      ..\..\FreeRTOS\port\portmacro.h(73): error:  #35: #error directive: configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
            #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
      ..\..\FreeRTOS\src\croutine.c: 0 warnings, 1 error
      
      /* 在 FreeRTOSConfig.h 中添加以下配置 */
      
      /* 系统节拍计数器位宽 - 设置为32位(最常用) */
      #define configTICK_TYPE_WIDTH_IN_BITS    32
      
      /* 或者设置为16位(如果32位不支持) */
      // #define configTICK_TYPE_WIDTH_IN_BITS    16
      

      在这里插入图片描述

5. 创建和管理FreeRTOS任务

  • 步骤详解

    • 定义任务函数和优先级。
    • 使用xTaskCreate API创建任务。
    • 启动调度器:调用vTaskStartScheduler
  • 代码示例

    #include "FreeRTOS.h"
    #include "task.h"
    
    void vTaskLed(void *pvParameters) {
        for(;;) {
            GPIO_ToggleBits(GPIOD, GPIO_Pin_12);
            vTaskDelay(500 / portTICK_PERIOD_MS); // 500ms延时
        }
    }
    
    int main(void) {
         // 初始化系统时钟和GPIO
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
        GPIO_InitTypeDef GPIO_InitStruct;
        GPIO_InitStruct.GPIO_Pin = GPIO_Pin_12;
        GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
        GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOD, &GPIO_InitStruct);
        xTaskCreate(vTaskLed, "LED Task", configMINIMAL_STACK_SIZE, NULL, 1, NULL);
        vTaskStartScheduler(); // 启动FreeRTOS调度器
        while(1); // 不应执行到此
    }
    

    处理中断

    FreeRTOS对中断向量的修改
    FreeRTOS需要接管以下三个系统异常:
    
    SVC_Handler - 用于任务启动
    
    PendSV_Handler - 用于上下文切换
    
    SysTick_Handler - 用于系统节拍
    
    在你的中断服务程序文件(如 stm32f4xx_it.c)中,需要确保系统中断与FreeRTOS的移植层连接。通常需要:
    
    实现 SysTick_Handler(),并在其中调用 xPortSysTickHandler()。
    
    实现 PendSV_Handler(),并在其中调用 xPortPendSVHandler()。
    
    注释掉 SVC_Handler() 函数,因为FreeRTOS在移植层已经提供了自己的实现。
    

    方法一:

    // 在 FreeRTOSConfig.h 的最开始定义
    #define xPortPendSVHandler    PendSV_Handler
    #define vPortSVCHandler       SVC_Handler  
    #define xPortSysTickHandler   SysTick_Handler
    
    // stm32f4xx.h删除三个中断函数
    

    在这里插入图片描述在这里插入图片描述
    方法二: 在启动文件中添加EXTERN声明,替换FreeRTOS中断

    ; 在 startup_stm32f40_41xxx.s 文件的开头,在 AREA 之前添加
        EXTERN vPortSVCHandler
        EXTERN xPortPendSVHandler
        EXTERN xPortSysTickHandler
    
    ; 原有的 AREA 定义继续
        AREA    RESET, DATA, READONLY
        EXPORT  __Vectors
        ; ...
    
    ; 在向量表中使用
    __Vectors       DCD     __initial_sp               ; Top of Stack
                    DCD     Reset_Handler              ; Reset Handler
                    DCD     NMI_Handler                ; NMI Handler
                    DCD     HardFault_Handler          ; Hard Fault Handler
                    DCD     MemManage_Handler          ; MPU Fault Handler
                    DCD     BusFault_Handler           ; Bus Fault Handler
                    DCD     UsageFault_Handler         ; Usage Fault Handler
                    DCD     0                          ; Reserved
                    DCD     0                          ; Reserved
                    DCD     0                          ; Reserved
                    DCD     0                          ; Reserved
                    DCD     vPortSVCHandler            ; SVCall Handler
                    DCD     DebugMon_Handler           ; Debug Monitor Handler
                    DCD     0                          ; Reserved
                    DCD     xPortPendSVHandler         ; PendSV Handler
                    DCD     xPortSysTickHandler        ; SysTick Handler
                    ;...
                    
    ; 在文件后面保留弱符号:
    SVC_Handler     PROC
                    EXPORT  SVC_Handler                [WEAK]
                    B       .
                    ENDP
    
    PendSV_Handler  PROC
                    EXPORT  PendSV_Handler             [WEAK]
                    B       .
                    ENDP
    
    SysTick_Handler PROC
                    EXPORT  SysTick_Handler            [WEAK]
                    B       .
                    ENDP
    

在这里插入图片描述

6. 编译、下载与测试

  • 编译步骤
    • 在Keil MDK中编译工程,解决潜在错误(如未定义符号)。
  • 下载到开发板
    • 使用ST-Link烧录固件。
  • 测试验证
    • LED闪烁任务:观察开发板LED是否按预期闪烁。
    • 串口输出调试:添加UART任务输出日志,确认任务调度正常。
    • 常见测试用例:创建多个任务测试优先级切换。

7. 常见问题与解决方案

  • 堆栈溢出
    • 症状:系统崩溃或未定义行为。
    • 解决:增大任务堆栈大小(configMINIMAL_STACK_SIZE)。
  • 调度器未启动
    • 症状:程序卡在vTaskStartScheduler前。
    • 解决:检查FreeRTOS宏配置和中断向量表对齐。
  • 优先级反转
    • 症状:高优先级任务被阻塞。
    • 解决:使用互斥锁或优先级继承机制

8. 总结与进阶

https://github.com/FreeRTOS/FreeRTOS/tags
https://github.com/FreeRTOS/FreeRTOS/releases/tag/202411.00
https://download.csdn.net/download/qq_38364548/92256099

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐