FreeRTOSConfig.h 是 FreeRTOS 的应用层配置文件,用于裁剪内核功能、设置参数、适配硬件。每个使用 FreeRTOS 的项目都需要提供这个文件。

下面按类别整理最常用的配置宏。

基础配置

configTICK_RATE_HZ

系统节拍中断(Tick)的频率,单位 Hz。

#define configTICK_RATE_HZ  1000   // 每毫秒一个 Tick,常用值
  • 值越大,时间精度越高,但 Tick 中断越频繁,系统开销越大
  • 1000(1ms 精度)适用于大多数 ARM Cortex-M 应用
  • 对资源极紧张的 MCU 可以设为 100(10ms 精度)

configTOTAL_HEAP_SIZE

堆内存大小(字节),详见 09-内存管理

#define configTOTAL_HEAP_SIZE  ((size_t)(15 * 1024))  // 15KB 堆

configMAX_PRIORITIES

最大可用优先级数量。优先级范围为 0(最低)到 configMAX_PRIORITIES - 1(最高)。

#define configMAX_PRIORITIES  8   // 可用优先级:0~7

不要设太大

通用调度器(C 实现)对这个值没有上限,但设得越大,查找最高优先级任务时遍历的列表越长。通常 8~32 足够。如果你使用架构优化的任务选择(configUSE_PORT_OPTIMISED_TASK_SELECTION = 1),建议设为 32 以内(通常是 8 的倍数)。

configMINIMAL_STACK_SIZE

空闲任务的栈大小(为单位,不是字节)。

// 128 字 × 4 字节 = 512 字节(Cortex-M)
#define configMINIMAL_STACK_SIZE  ((unsigned short)128)

你创建任务时的栈深度不要小于这个值。

configMAX_TASK_NAME_LEN

任务名称字符串的最大长度(包括结尾的 \0)。

#define configMAX_TASK_NAME_LEN  16

功能开关(INCLUDE_ 开头)

INCLUDE_ 开头的宏控制某个 API 函数是否编译进内核。不需要的功能设为 0 可以减小固件体积。

#define INCLUDE_vTaskPrioritySet       1   // vTaskPrioritySet()
#define INCLUDE_uxTaskPriorityGet      1   // uxTaskPriorityGet()
#define INCLUDE_vTaskDelete            1   // vTaskDelete()
#define INCLUDE_vTaskSuspend           1   // vTaskSuspend()/vTaskResume()/portMAX_DELAY
#define INCLUDE_vTaskDelayUntil        1   // vTaskDelayUntil()
#define INCLUDE_vTaskDelay             1   // vTaskDelay()
#define INCLUDE_xTaskGetSchedulerState 1   // 查询调度器状态
#define INCLUDE_xTaskGetCurrentTaskHandle 1  // 获取当前任务句柄
#define INCLUDE_uxTaskGetStackHighWaterMark 1  // 栈高水位检测(调试用)
#define INCLUDE_xTaskGetIdleTaskHandle 1   // 获取空闲任务句柄
#define INCLUDE_eTaskGetState          1   // 查询任务状态
#define INCLUDE_xTimerPendFunctionCall 1   // xTimerPendFunctionCall()(定时器需要)
#define INCLUDE_xTaskAbortDelay        1   // vTaskAbortDelay()
#define INCLUDE_xTaskGetHandle         1   // 通过名称查找任务句柄
#define INCLUDE_xTaskResumeFromISR     1   // xTaskResumeFromISR()

按需裁剪

不需要的 API 设为 0,可以节省 Flash 和 RAM。初次使用全部设为 1,等项目稳定后再裁剪。

调度器配置

configUSE_PREEMPTION

是否启用抢占式调度

#define configUSE_PREEMPTION  1   // 1=抢占式(推荐),0=协作式

详见 02-任务管理与调度 > 调度算法

configUSE_TIME_SLICING

是否启用时间片轮转(同优先级任务之间轮流执行)。

#define configUSE_TIME_SLICING  1   // 1=启用(推荐),0=不轮转

configIDLE_SHOULD_YIELD

空闲任务是否主动让出时间片给同优先级(优先级 0)的用户任务。

#define configIDLE_SHOULD_YIELD  1
  • 1:空闲任务每次循环迭代时,如果有其他优先级 0 的就绪任务,主动让出 CPU
  • 0:空闲任务用完自己的时间片才会切换

通常设为 1

如果你有优先级为 0 的用户任务,设为 1 可以让它们更快获得 CPU。如果空闲钩子做了重要工作(如低功耗),可以设为 0。

configUSE_PORT_OPTIMISED_TASK_SELECTION

是否使用架构优化的任务选择算法(用汇编实现的 CLZ/前导零计数指令快速查找最高优先级任务)。

#define configUSE_PORT_OPTIMISED_TASK_SELECTION  1
  • 1:性能更好,执行时间恒定,但要求 configMAX_PRIORITIES ≤ 32
  • 0:通用 C 实现,对优先级数量无限制

Cortex-M 等支持 CLZ 指令的架构建议设为 1。

软件定时器配置

#define configUSE_TIMERS                1   // 启用软件定时器
#define configTIMER_TASK_PRIORITY       (configMAX_PRIORITIES - 1)  // 定时器守护任务优先级
#define configTIMER_QUEUE_LENGTH        10  // 定时器命令队列长度
#define configTIMER_TASK_STACK_DEPTH    configMINIMAL_STACK_SIZE    // 守护任务栈大小

详见 05-软件定时器

定时器守护任务优先级建议设高

如果定时器优先级设得太低,定时器回调会被其他任务延迟,定时精度下降。建议设为最高或次高优先级。

中断优先级配置(Cortex-M 专用)

这部分是 Cortex-M 移植中最容易配错的,务必仔细。

// FreeRTOS 内核自己的中断优先级(SysTick、PendSV 等)
// 必须设为最低逻辑优先级(最大数字值)
#define configKERNEL_INTERRUPT_PRIORITY         (7 << 5)   // STM32 用 4 位优先级时,15(最低)= 0xF0 或 7 << 5

// 可以安全调用 FreeRTOS FromISR API 的最高中断优先级
// 优先级高于此值(数字更小)的中断不能调用任何 FromISR API
#define configMAX_SYSCALL_INTERRUPT_PRIORITY    (5 << 5)   // 逻辑优先级 5

Cortex-M 优先级数字和逻辑的关系

Cortex-M 使用 3~8 位优先级(取决于芯片),数字越小逻辑优先级越高

  • 优先级 0(数字最小)= 最高逻辑优先级,不受 FreeRTOS 管理,可以做极低延迟的中断处理,但不能调用任何 FromISR API
  • 优先级 configMAX_SYSCALL_INTERRUPT_PRIORITY 以下(数字更大)= 可以调用 FromISR API
  • configKERNEL_INTERRUPT_PRIORITY = 最低逻辑优先级(最大数字),FreeRTOS SysTick 用这个

STM32(4位优先级,即 0~15)常见配置:

#define configPRIO_BITS  4  // STM32 使用 4 位优先级
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY         15
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY    5
#define configKERNEL_INTERRUPT_PRIORITY         (configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS))
#define configMAX_SYSCALL_INTERRUPT_PRIORITY    (configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS))

钩子函数配置

#define configUSE_IDLE_HOOK           0   // 空闲任务钩子
#define configUSE_TICK_HOOK           0   // Tick 中断钩子(每次 Tick 调用,要极短!)
#define configCHECK_FOR_STACK_OVERFLOW  2  // 栈溢出检测(调试阶段建议开,发布可关)
#define configUSE_MALLOC_FAILED_HOOK  1   // malloc 失败钩子

栈溢出检测

configCHECK_FOR_STACK_OVERFLOW 设为 1 或 2 时,内核会检测栈溢出,溢出时调用:

void vApplicationStackOverflowHook(TaskHandle_t xTask, char *pcTaskName)
{
    // pcTaskName 是溢出的任务名,方便定位
    taskDISABLE_INTERRUPTS();
    for(;;);
}
  • 1:简单检测,在任务切换时检查栈指针是否超出边界(快但可能漏检)
  • 2:更全面检测,在栈末尾填充已知模式,检查是否被改写(稍慢但更准确)

开发阶段务必开启

栈溢出是嵌入式开发中最常见的 bug 之一,开启检测能帮你快速定位问题。

其他有用配置

configUSE_TASK_NOTIFICATIONS

#define configUSE_TASK_NOTIFICATIONS  1   // 启用任务通知(默认 1,强烈建议开)

启用后每个任务多 8 字节 RAM,但获得 08-任务通知 这个最快的 IPC 方式。

configUSE_TRACE_FACILITY

#define configUSE_TRACE_FACILITY   0   // 1=启用追踪功能(调试/可视化工具用)

开启后会额外记录任务状态信息,供 SystemView 等调试工具使用。

configGENERATE_RUN_TIME_STATS

#define configGENERATE_RUN_TIME_STATS  0  // 运行时间统计(CPU 利用率)

开启后可通过 uxTaskGetSystemState() 获取每个任务的运行时间,用于性能分析。需要配置一个定时器提供时基。

configUSE_16_BIT_TICKS(已废弃)

// 不要再用这个宏,使用 configTICK_TYPE_WIDTH_IN_BITS 替代
#define configTICK_TYPE_WIDTH_IN_BITS  TICK_TYPE_WIDTH_32_BITS

configSTACK_DEPTH_TYPE

栈深度变量的类型,默认是 uint16_t(最大 65535 字 = 256KB),一般够用。如果你的栈特别大(比如 32 位以上系统),可以改为 size_tuint32_t

#define configSTACK_DEPTH_TYPE  uint32_t

configUSE_CO_ROUTINES

协程支持,已过时,设为 0:

#define configUSE_CO_ROUTINES  0

配置示例(Cortex-M 最小配置)

#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H

/* Cortex-M 特定 */
#ifdef __NVIC_PRIO_BITS
  #define configPRIO_BITS  __NVIC_PRIO_BITS
#else
  #define configPRIO_BITS  4
#endif
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY       15
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY   5
#define configKERNEL_INTERRUPT_PRIORITY     (configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8-configPRIO_BITS))
#define configMAX_SYSCALL_INTERRUPT_PRIORITY (configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8-configPRIO_BITS))

/* 基础 */
#define configUSE_PREEMPTION                1
#define configUSE_TIME_SLICING              1
#define configUSE_PORT_OPTIMISED_TASK_SELECTION  1
#define configCPU_CLOCK_HZ                  SystemCoreClock
#define configTICK_RATE_HZ                  1000
#define configMAX_PRIORITIES                8
#define configMINIMAL_STACK_SIZE            128
#define configMAX_TASK_NAME_LEN             16
#define configTOTAL_HEAP_SIZE               ((size_t)(15*1024))

/* API */
#define INCLUDE_vTaskPrioritySet            1
#define INCLUDE_uxTaskPriorityGet           1
#define INCLUDE_vTaskDelete                 1
#define INCLUDE_vTaskSuspend                1
#define INCLUDE_vTaskDelayUntil             1
#define INCLUDE_vTaskDelay                  1
#define INCLUDE_xTaskGetSchedulerState      1
#define INCLUDE_xTaskGetCurrentTaskHandle   1
#define INCLUDE_eTaskGetState               1
#define INCLUDE_xTimerPendFunctionCall      1

/* 定时器 */
#define configUSE_TIMERS                    1
#define configTIMER_TASK_PRIORITY           (configMAX_PRIORITIES-1)
#define configTIMER_QUEUE_LENGTH            10
#define configTIMER_TASK_STACK_DEPTH        configMINIMAL_STACK_SIZE

/* 钩子 */
#define configCHECK_FOR_STACK_OVERFLOW      2
#define configUSE_MALLOC_FAILED_HOOK        1

/* 中断 */
#define vPortSVCHandler     SVC_Handler
#define xPortPendSVHandler  PendSV_Handler
#define xPortSysTickHandler SysTick_Handler

#endif /* FREERTOS_CONFIG_H */

相关:01-基础与文件结构02-任务管理与调度05-软件定时器09-内存管理返回目录