一、系统配置说明
实际应用 FreeRTOS 的时候,我们需要根据产品需求配置 FreeRTOS,满足产品需求的同时,发挥 FreeRTOS 的最佳性能。
FreeRTOS 的系统配置文件为 FreeRTOSConfig.h,在此配置文件中可完成 FreeRTOS 的裁剪与配置。 初学的话,有个大概了解即可,随着后续的深入学习,再熟练设置每个配置选项。
FreeRTOSConfig.h 根据正在构建的应用程序定制 FreeRTOS 内核。因此,它特定于应用程序,而不是FreeRTOS,并且应该位于应用程序目录中,而不是位于 FreeRTOS 内核源代码目录中。
另外,大部分配置选项在 FreeRTOS.h 文件中都有默认的配置,在应用时,把需要的配置选项放在 FreeRTOSConfig.h 文件即可。
关于系统配置,官网也有详细介绍。
网址:freeRTOS官网
二、“Config” 开始的宏 - 内核配置
STM32cubeMX 中的配置:
2.1、configUSE_PREEMPTION
配置为1 使能抢占式调度器
配置为0 使能合作式调度器
2.2、configUSE_PORT_OPTIMISED_TASK_SELECTION
此配置用于优化优先级列表中要执行的最高优先级任务的算法。对 CM 内核的移植文件,默认已经在文件 portmacro.h 文件中使能。
通用方式 — 配置为 0:
所有平台的移植文件都可以配置为 0,因为这是通用方式。
纯 C 编写,比专用方式效率低。
可用的优先级数量不限制。
专用方式 — 配置为 1:
部分平台支持。
这些平台架构有专用的汇编指令,比如 CLZ(Count Leading Zeros)指令,通过这些指令可以加快算法执行速度。
比通用方式高效。
有最大优先级数限制,通常限制为 32 个。
2.3、configUSE_TICKLESS_IDLE
此配置用于使能 tickless 低功耗模式
配置为 1 使能 tickless 低功耗模式
配置为 0 禁能 tickless 低功耗模式
2.4、configCPU_CLOCK_HZ
此参数用于定义 CPU 的主频,单位 Hz
2.5、configTICK_RATE_HZ
此参数用于定义系统时钟节拍数,单位 Hz,一般取 1000Hz 即可。本教程配套的例子也全部采用这个时钟节拍数。过高的的系统时钟节拍将使得 FreeRTOS 内核运行占用过多的时间,增加系统负荷
2.6、configMAX_PRIORITIES
此参数用于定义可供用户使用的最大任务优先级数,如果这个定义的是 5,那么用户可以使用的优先级号是 0,1,2,3,4,不包含 5,对于这一点,初学者要特别的注意。
2.7、configMINIMAL_STACK_SIZE
此参数用于定义空闲任务的栈空间大小,单位字,即 4 字节。
2.8、configTOTAL_HEAP_SIZE
定义堆大小,FreeRTOS 内核,用户动态内存申请,任务栈,任务创建,信号量创建,消息队列创建等都需要用这个空间。
2.9、configMAX_TASK_NAME_LEN
定义任务名最大的字符数,末尾的结束符 '\0’也要计算在内。
2.10、configUSE_16_BIT_TICKS
系统时钟节拍计数使用 TickType_t 数据类型定义的。
如果用户使能了宏定义 configUSE_16_BIT_TICKS,那么 TickType_t 定义的就是 16 位无符号数,如 果没有使能,那么 TickType_t 定义的就是 32 位无符号数。对于 32 位架构的处理器,一定要禁止此宏定义,即设置此宏定义数值为 0 即可。而 16 位无符号数类型主要用于 8 位和 16 位架构的处理器。
2.11、configIDLE_SHOULD_YIELD
此参数用于使能与空闲任务同优先级的任务,只有满足以下两个条件时,此参数才有效果:
-
使能抢占式调度器。
-
有创建与空闲任务同优先级的任务。
配置为 1,就可以使能此特性了,实际应用中不建议用户使用此功能,将其配置为 0 即可。
2.12、configUSE_TASK_NOTIFICATIONS
配置为 1 使能任务间直接的消息传递,包含信号量,事件标志组和消息邮箱。
配置为 0 禁能此特性。
2.13、configUSE_MUTEXES
配置为 1 使能互斥信号量
配置为 0 禁能互斥信号量
2.14、configUSE_RECURSIVE_MUTEXES
配置为 1 使能递归互斥信号量
配置为 0 禁能递归互斥信号量
2.15、configUSE_COUNTING_SEMAPHORES
配置为 1 使能计数信号量
配置为 0 禁能计数信号量
2.16、configQUEUE_REGISTRY_SIZE
通过此定义来设置可以注册的信号量和消息队列个数。队列注册有两个目的,这两个目的都与内核调试有关:
注册队列的时候,可以给队列起一个名字,当使用调试组件的时候,通过名字可以很容易的区分不同队列
通过队列的相关信息,调试器可以很容易定位队列和信号量,能够定位信号量是因为 FreeRTOS 信号量也是基于队列实现的。当然,如果用户没有使用内核方面的调试器,这个宏定义是没有意义的。
2.17、configUSE_QUEUE_SETS
配置为 1 使能消息队列。
配置为 0 禁能消息队列。
2.18、configUSE_TIME_SLICING
配置为 1 使能时间片调度。
配置为 0 禁能时间片调度。
用户没有配置此选项如果用户没有配置此选项
默认在 FreeRTOS.h 文件中已经配置为 1,即使能时间片调度。
三、“Config” 开始的宏 - 其他配置
STM32cubeMX 中的配置:
3.1、钩子函数配置:
钩子函数的主要功能是用于函数的扩展,用户可以根据自己的需要往里面添加相关的测试函数。
3.1.1、configUSE_IDLE_HOOK
配置为 1 使能空闲任务的钩子函数
配置为 0 禁能空闲任务钩子函数
3.1.2、configUSE_MALLOC_FAILED_HOOK
当创建任务,信号量或者消息队列时,FreeRTOS 通过函数 pvPortMalloc() 申请动态内存。
配置为 1 使能动态内存申请失败时的钩子函数
配置为 0 禁能动态内存申请失败时的钩子函数
3.1.3、configUSE_TICK_HOOK
配置为 1 使能滴答定时器中断里面执行的钩子函数
配置为 0 禁能滴答定时器中断里面执行的钩子函数
3.1.4、configCHECK_FOR_STACK_OVERFLOW
FreeRTOS 的栈溢出检测支持两种方法,为了方便描述,我们这里将其称之为方法一和方法二。
配置为 2 栈溢出检测使用方法二。
配置为 1 栈溢出检测使用方法一。
配置为 0 禁止栈溢出检测。
3.2、任务运行信息获取配置:
3.2.1、configGENERATE_RUN_TIME_STATS
配置为 1 使能任务运行状态参数统计。
配置为 0 禁止此特性。
3.2.2、configUSE_TRACE_FACILITY
配置为 1 使能此配置将添加额外的结构体成员和函数,以此来协助可视化和跟踪
配置为 0 禁能此特性。
3.2.3、configUSE_STATS_FORMATTING_FUNCTIONS
用户配置宏定义 configUSE_TRACE_FACILITY 和 configUSE_STATS_FORMATTING_FUNCTIONS 都为 1 的时候,将使能函数 vTaskList() 和 vTaskGetRunTimeStats(),如果两者中任何一个为 0,那么这两个函数都将被禁能。
3.3、合作式任务配置:
3.3.1、configUSE_CO_ROUTINES
配置为 1 使能合作式调度相关函数。
配置为 0 禁能合作式调度相关函数。
3.3.2、configMAX_CO_ROUTINE_PRIORITIES
此参数用于定义可供用户使用的最大的合作式任务优先级数,如果这个定义的是 5,那么用户可以使用的优先级号是 0,1,2,3,4,不包含 5,对于这一点,初学者要特别的注意。
3.4、软件定时器配置:
3.4.1、configUSE_TIMERS
配置为 1 使能软件定时器。
配置为 0 禁能软件定时器。
3.4.2、configTIMER_TASK_PRIORITY
配置软件定时器任务的优先级。
3.4.3、configTIMER_QUEUE_LENGTH
配置软件定时器命令队列的长度。
3.4.4、configTIMER_TASK_STACK_DEPTH
配置软件定时器任务的栈空间大小
3.5、断言配置:
STM32cubeMX 生成的:
后续可以根据需要进行修改。
3.6、中断相关:
3.6.1、configLIBRARY_LOWEST_INTERRUPT_PRIORITY:
配置中断最低优先级,通常为 15(因为 STM32 的抢占式优先级最多设置为 4bit,优先级最低只能设置为 15),此参数用于配置 SysTick 与 PendSV。
3.6.2、configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY:
配置系统可管理的最高优先级,此参数用于配置 BASEPRI 寄存器。 如果设置为 5,则优先级数值为 0,1,2,3,4 的中断是不受 FreeRTOS 管理的,不可被屏蔽,也不能调用 FreeRTOS 中的 API 接口函数,而中断优先级在 5-15 的中断受系统 FreeRTOS 管理,可以被屏蔽。
四、“INCLUDE_” 开始的宏
以 “INCLUDE” 开头的宏允许您的应用程序将未使用的实时内核组件从您的工程中移除, 这可节约嵌入式应用程序所需的任何 ROM 或 RAM。
每个宏都采用以下形式:
INCLUDE_FunctionName
其中 FunctionName 表示可以选择性地排除的 API 函数(或函数集)。
要包含 API 函数,请将宏设置为 1,要排除该函数,请将宏设置为 0。
例如:
要包含 vTaskDelete() API 函数,请使用:
#define INCLUDE_vTaskDelete 1
要从构建中排除 vTaskDelete(),请使用:
#define INCLUDE_vTaskDelete 0
STM32cubeMX 中的配置: