文章目录
- 03. FreeRTOS系统配置
- 1. "config"配置项
- 2. "INCLUDE"配置项
- 3. 其他配置项
03. FreeRTOS系统配置
1. "config"配置项
-
基础配置项
基础配置项 功能 configUSE_PREEMPTION 设置系统的调度方式。
为1
时,系统使用抢占式调度;
为0
时,系统使用协程式调度。configUSE_PORT_OPTIMISED_TASK_SELECTION 选择下一个要执行的任务,分别为通用方法和特殊方法。
为0
时,使用通用方法。通用方法是完全使用C实现的软件算法,因此支持所用硬件,并且不限制任务优先级的最大值,但效率相较于特殊方法低。
为1
时,使用特殊方法。特殊方法的效率相较于通用方法高,但是特殊方法依赖于一个或多个特定架构的汇编指令(一般是类似计算前导零[CLZ]
的指令),因此特殊方法并不支持所有硬件,并且对任务优先级的最大值一般也有限制,通常为32。configUSE_TICKLESS_IDLE 为 1
时,使能tickless低功耗模式;
为0
时, tick中断则会移植运行。
tickless低功耗模式并不适用于所有硬件。configCPU_CLOCK_HZ 设置CPU的内核时钟频率,单位为Hz。 configSYSTICK_CLOCK_HZ 设置SysTick的时钟频率,当 SysTick
的时钟源频率与内核时钟频率不同时才可以定义,单位为Hz。configTICK_RATE_HZ 设置FreeRTOS系统节拍的中断频率,单位为Hz。 configMAX_PRIORITIES 定义系统支持的最大任务优先级数量,最大任务优先级数值为 configMAX_PRIORITIES
-1.configMINIMAL_STACK_SIZE 设置空闲任务的栈空间大小,单位为word。 configMAX_TASK_NAME_LEN 设置任务名的最大字符数 configUSE_16_BIT_TICKS 定义系统节拍计数器的数据类型
为1
时,系统节拍计数器的数据类型为16
位无符号整型;
为0
时,系统节拍计数器的数据类型为32
位无符号整型。configIDLE_SHOULD_YIELD 为 1
时,在抢占调度下,同等优先级的任务可抢占空闲任务,并延用空闲任务剩余的时间片。configUSE_TASK_NOTIFICATIONS 为 1
时,开启任务通知功能。当开启任务通知功能后,每个任务将多占用8字节的内存空间。configTASK_NOTIFICATION_ARRAY_ENTRIES 定义任务通知数组的大小。 configUSE_MUTEXES 使能互斥信号量,
为1
时,使能互斥信号量;
为0
时,则不使能互斥信号量。configUSE_RECURSIVE_MUTEXES 使能递归互斥信号量,
为1
时,使能递归互斥信号量;
为0
时,则不使能递归互斥信号量。configUSE_COUNTING_SEMAPHORES 使能计数型信号量,
为1
时,使能计数型信号量;
为0
时,则不使能计数型信号量。configUSE_ALTERNATIVE_API 已弃用 configQUEUE_REGISTRY_SIZE 定义可以注册的队列和信号量的最大数量。此宏定义仅用于调试使用。 configUSE_QUEUE_SETS 使能队列集,
为1
时,使能队列集;
为0
时,则不使能队列集。configUSE_TIME_SLICING 使能时间片调度,
为1
且使用抢占式调度时,使能时间片调度;
为0
时,则不使能时间片调度。configUSE_NEWLIB_REENTRANT 为每个任务分配一个NewLib重入结构体,
为1
时,FreeRTOS将为每个创建的任务的任务控制块中分配一个NewLib重入结构体。configENABLE_BACKWARD_COMPATIBILITY 用于兼容FreeRTOS老版本的API函数。 configNUM_THREAD_LOCAL_STORAGE_POINTERS 用于在任务控制块中分配一个线程本地存储指针数组,
为大于0
时, 为线程本地存储指针数组的元素个数;
为0
时,则禁用线程本地存储指针数组。configSTACK_DEPTH_TYPE 用于定义任务堆栈深度的数据类型,默认为 uint16_t
。configMESSAGE_BUFFER_LENGTH_TYPE 用于定义消息缓冲区中消息长度的数据类型,默认为 size_t
。代码具体体现:
/* 基础配置项 */ // 1: 抢占式调度器, 0: 协程式调度器, 无默认需定义 #define configUSE_PREEMPTION 1 // 1: 使用硬件计算下一个要运行的任务, 0: 使用软件算法计算下一个要运行的任务, 默认: 0 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 // 1: 使能tickless低功耗模式, 默认: 0 #define configUSE_TICKLESS_IDLE 0 // 定义CPU主频, 单位: Hz, 无默认需定义 #define configCPU_CLOCK_HZ SystemCoreClock // 定义SysTick时钟频率,当SysTick时钟频率与内核时钟频率不同时才可以定义, 单位: Hz, 默认: 不定义 #define configSYSTICK_CLOCK_HZ (configCPU_CLOCK_HZ / 8) // 定义系统时钟节拍频率, 单位: Hz, 无默认需定义 #define configTICK_RATE_HZ 1000 // 定义最大优先级数, 最大优先级=configMAX_PRIORITIES-1, 无默认需定义 #define configMAX_PRIORITIES 32 // 定义空闲任务的栈空间大小, 单位: Word, 无默认需定义 #define configMINIMAL_STACK_SIZE 128 // 定义任务名最大字符数, 默认: 16 #define configMAX_TASK_NAME_LEN 16 // 1: 定义系统时钟节拍计数器的数据类型为16位无符号数, 无默认需定义 #define configUSE_16_BIT_TICKS 0 // 1: 使能在抢占式调度下,同优先级的任务能抢占空闲任务, 默认: 1 #define configIDLE_SHOULD_YIELD 1 // 1: 使能任务间直接的消息传递,包括信号量、事件标志组和消息邮箱, 默认: 1 #define configUSE_TASK_NOTIFICATIONS 1 // 定义任务通知数组的大小, 默认: 1 #define configTASK_NOTIFICATION_ARRAY_ENTRIES 1 // 1: 使能互斥信号量, 默认: 0 #define configUSE_MUTEXES 1 // 1: 使能递归互斥信号量, 默认: 0 #define configUSE_RECURSIVE_MUTEXES 1 // 1: 使能计数信号量, 默认: 0 #define configUSE_COUNTING_SEMAPHORES 1 // 已弃用!!! #define configUSE_ALTERNATIVE_API 0 // 定义可以注册的信号量和消息队列的个数, 默认: 0 #define configQUEUE_REGISTRY_SIZE 8 // 1: 使能队列集, 默认: 0 #define configUSE_QUEUE_SETS 1 // 1: 使能时间片调度, 默认: 1 #define configUSE_TIME_SLICING 1 // 1: 任务创建时分配Newlib的重入结构体, 默认: 0 #define configUSE_NEWLIB_REENTRANT 0 // 1: 使能兼容老版本, 默认: 1 #define configENABLE_BACKWARD_COMPATIBILITY 0 // 定义线程本地存储指针的个数, 默认: 0 #define configNUM_THREAD_LOCAL_STORAGE_POINTERS 0 // 定义任务堆栈深度的数据类型, 默认: uint16_t #define configSTACK_DEPTH_TYPE uint16_t // 定义消息缓冲区中消息长度的数据类型, 默认: size_t #define configMESSAGE_BUFFER_LENGTH_TYPE size_t
-
内存分配项
配置项 功能 configSUPPORT_STATIC_ALLOCATION 为 1
时,FreeRTOS支持使用静态方式管理内存,默认设置为0。如果将设置为1,用户还需要提供两个回调函数:vApplicationGetIdleTaskMemory()
和vApplicationGetTimerTaskMemory()
configSUPPORT_DYNAMIC_ALLOCATION 为 1
时,FreeRTOS支持使用动态方式管理内存,默认设置为1。configTOTAL_HEAP_SIZE 用于定义用于FreeRTOS动态内存管理的内存大小,即FreeRTOS的内存堆,单位为 Byte。 configAPPLICATION_ALLOCATED_HEAP 用于自定义FreeRTOS的内存堆,当设置为1时,用户需要自行创建FreeRTOS的内存堆,否则FreeRTOS的内存堆将由编译器进行分配。利用此宏定义,可以使用FreeRTOS动态管理外扩内存。 configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 用于自定义动态创建和删除任务时,任务栈内存的申请与释放函数 pvPortMallocStack()
和vPortFreeStack()
,当设置为1时,用户需提供pvPortMallocStack()和vPortFreeStack()
函数。代码具体体现:
/* 内存分配相关定义 */ // 1: 支持静态申请内存, 默认: 0 #define configSUPPORT_STATIC_ALLOCATION 0 // 1: 支持动态申请内存, 默认: 1 #define configSUPPORT_DYNAMIC_ALLOCATION 1 // FreeRTOS堆中可用的RAM总量, 单位: Byte, 无默认需定义 #define configTOTAL_HEAP_SIZE ((size_t)(10 * 1024)) // 1: 用户手动分配FreeRTOS内存堆(ucHeap), 默认: 0 #define configAPPLICATION_ALLOCATED_HEAP 0 // 1: 用户自行实现任务创建时使用的内存申请与释放函数, 默认: 0 #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0
-
钩子函数项
配置项 功能 configUSE_IDLE_HOOK 使能使用空闲任务钩子函数,
为1
时,使能使用空闲任务钩子函数,用户需自定义相关钩子函数;
为0
时,则不使能使用空闲任务钩子函数。configUSE_TICK_HOOK 使能使用系统时钟节拍中断钩子函数,
为1
时,使能使用系统时钟节拍中断钩子函数,用户需自定义相关钩子函数;
为0
时,则不使能使用系统时钟节拍中断钩子函数。configCHECK_FOR_STACK_OVERFLOW 使能栈溢出检测,
为1
时,使用栈溢出检测方法一;
为2
时,使用栈溢出检测方法二;
为0
时,不使能栈溢出检测。configUSE_MALLOC_FAILED_HOOK 使能使用动态内存分配失败钩子函数,
为1
时,使能使用动态内存分配失败钩子函数,用户需自定义相关钩子函数;
为0
时,则不使能使用动态内存分配失败钩子函数。configUSE_DAEMON_TASK_STARTUP_HOOK 使能使用定时器服务任务首次执行前的钩子函数
为1
时,使能使用定时器服务任务首次执行前的钩子函数,此时用户需定义定时器服务任务首次执行的相关钩子函数;
为0
时,则不使能使用定时器服务任务首次执行前的钩子函数。代码具体体现:
/* 钩子函数相关定义 */ // 1: 使能空闲任务钩子函数, 无默认需定义 #define configUSE_IDLE_HOOK 0 // 1: 使能系统时钟节拍中断钩子函数, 无默认需定义 #define configUSE_TICK_HOOK 0 // 1: 使能栈溢出检测方法1, 2: 使能栈溢出检测方法2, 默认: 0 #define configCHECK_FOR_STACK_OVERFLOW 0 // 1: 使能动态内存申请失败钩子函数, 默认: 0 #define configUSE_MALLOC_FAILED_HOOK 0 // 1: 使能定时器服务任务首次执行前的钩子函数, 默认: 0 #define configUSE_DAEMON_TASK_STARTUP_HOOK 0
-
运行时间和任务状态统计相关定义
配置项 功能 configGENERATE_RUN_TIME_STATS 使能任务运行时间统计功能,
为1
时,使能任务运行时间统计功能,此时用户需要提供两个函数,一个是用于配置任务运行时间统计功能的函数portCONFIGURE_TIMER_FOR_RUN_TIME_STATS()
,一般是完成定时器的初始化,另一个函数是portGET_RUN_TIME_COUNTER_VALUE()
,该函数用于获取定时器的计时值;
为0
时,则不使能任务运行时间统计功能。configUSE_TRACE_FACILITY 使能可视化跟踪调试,
为1
时,使能可视化跟踪调试;
为0
时,则不使能可视化跟踪调试。configUSE_STATS_FORMATTING_FUNCTIONS 当此宏与 configUSE_TRACE_FACILITY
同时设置为1
时,将编译函数vTaskList()
和函数vTaskGetRunTimeStats()
,否则将忽略编译。代码具体体现:
/* 运行时间和任务状态统计相关定义 */ // 1: 使能任务运行时间统计功能, 默认: 0 #define configGENERATE_RUN_TIME_STATS 0 #if configGENERATE_RUN_TIME_STATS #include "./BSP/TIMER/btim.h" #define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() ConfigureTimeForRunTimeStats() extern uint32_t FreeRTOSRunTimeTicks; #define portGET_RUN_TIME_COUNTER_VALUE() FreeRTOSRunTimeTicks #endif // 1: 使能可视化跟踪调试, 默认: 0 #define configUSE_TRACE_FACILITY 1 // 1: configUSE_TRACE_FACILITY为1时,会编译vTaskList()和vTaskGetRunTimeStats()函数, 默认: 0 #define configUSE_STATS_FORMATTING_FUNCTIONS 1
-
协程相关定义
配置项 功能 configUSE_CO_ROUTINES 用于启用协程,
为1时,启用协程;
为0时,则不启用协程。configMAX_CO_ROUTINE_PRIORITIES 用于设置协程的最大任务优先级数量,协程的最大任务优先级数值为 configMAX_CO_ROUTINE_PRIORITIES-1
。代码具体体现:
/* 协程相关定义 */ // 1: 启用协程, 默认: 0 #define configUSE_CO_ROUTINES 0 // 定义协程的最大优先级, 最大优先级=configMAX_CO_ROUTINE_PRIORITIES-1, 无默认configUSE_CO_ROUTINES为1时需定义 #define configMAX_CO_ROUTINE_PRIORITIES 2
-
软件定时器相关定义
配置项 功能 configUSE_TIMERS 启用软件定时器功能,
为1时,启用软件定时器功能;
为0时,则不启用软件定时器功能。configTIMER_TASK_PRIORITY 设置软件定时器处理任务的优先级,当启用软件定时器功能时,系统会创建一个用于处理软件定时器的软件定时器处理任务。 configTIMER_QUEUE_LENGTH 定义软件定时器队列的长度,软件定时器的开启、停止与销毁等操作都是通过队列实现的。 configTIMER_TASK_STACK_DEPTH 设置软件定时器处理任务的栈空间大小,当启用软件定时器功能时,系统会创建一个用于处理软件定时器的软件定时器处理任务。 代码具体体现:
/* 软件定时器相关定义 */ // 1: 使能软件定时器, 默认: 0 #define configUSE_TIMERS 1 // 定义软件定时器任务的优先级, 无默认configUSE_TIMERS为1时需定义 #define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 1 ) // 定义软件定时器命令队列的长度, 无默认configUSE_TIMERS为1时需定义 #define configTIMER_QUEUE_LENGTH 5 // 定义软件定时器任务的栈空间大小, 无默认configUSE_TIMERS为1时需定义 #define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE * 2)
-
中断嵌套行为配置
配置项 功能 configPRIO_BITS 为MCU的8位优先级配置寄存器实际使用的位数。 configLIBRARY_LOWEST_INTERRUPT_PRIORITY 为MCU的最低中断优先等级,对于STM32,在使用FreeRTOS时,建议将中断优先级分组设置为组4,此时中断的最低优先级为15。此宏定义用于辅助配置宏 configKERNEL_INTERRUPT_PRIORITY
。configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 用于设置FreeRTOS可管理中断的最高优先级,当中断的优先级数值小于 configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY
时,此中断不受FreeRTOS管理。此宏定义用于辅助配置宏configMAX_SYSCALL_INTERRUPT_PRIORITY
。configKERNEL_INTERRUPT_PRIORITY 为MCU的最低中断优先等级在中断优先级配置寄存器中的值,对于STM32,即宏 configLIBRARY_LOWEST_INTERRUPT_PRIORITY
偏移4bit的值。configMAX_SYSCALL_INTERRUPT_PRIORITY 为FreeRTOS可管理中断的最高优先等级在中断优先级配置寄存器中的值,对于STM32,即宏 configLIBRARY_LOWEST_INTERRUPT_PRIORITY
偏移4bit的值。configMAX_API_CALL_INTERRUPT_PRIORITY 与宏 configMAX_SYSCALL_INTERRUPT_PRIORITY
是等价的。具体代码体现:
/* 中断嵌套行为配置 */ #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 // FreeRTOS可管理的最高中断优先级 #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 configMAX_API_CALL_INTERRUPT_PRIORITY configMAX_SYSCALL_INTERRUPT_PRIORITY
-
断言
配置项 功能 vAssertCalled(char, int) 用于辅助配置宏 configASSERT(x)
以通过串口打印相关信息configASSERT(x) 为FreeRTOS操作系统中的断言,断言会对表达式x进行判断,当x为假时,断言失败,表明程序出错,于是使用宏 vAssertCalled(char,int)
通过串口打印相关的错误信息。断言常用于检测程序中的错误,使用断言将增加程序的代码大小和执行时间,因此建议在程序调试通过后将宏configASSERT(x)
进行注释,以较少额外的开销。具体代码体现:
/* 断言 */ #define vAssertCalled(char, int) printf("Error: %s, %d\r\n", char, int) #define configASSERT( x ) if( ( x ) == 0 ) vAssertCalled( __FILE__, __LINE__ )
-
FreeRTOS MPU特殊定义
配置项 功能 configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS 暂不使用 configTOTAL_MPU_REGIONS 暂不使用 configTEX_S_C_B_FLASH 暂不使用 configTEX_S_C_B_SRAM 暂不使用 configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY 暂不使用 configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS 暂不使用 代码具体体现:
/* FreeRTOS MPU 特殊定义 */ //#define configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS 0 //#define configTOTAL_MPU_REGIONS 8 //#define configTEX_S_C_B_FLASH 0x07UL //#define configTEX_S_C_B_SRAM 0x07UL //#define configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY 1 //#define configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS 1
2. "INCLUDE"配置项
配置项 | 功能 |
---|---|
INCLUDE_vTaskPrioritySet | 设置任务优先级 |
INCLUDE_uxTaskPriorityGet | 获取任务优先级 |
INCLUDE_vTaskDelete | 删除任务 |
INCLUDE_vTaskSuspend | 挂起任务 |
INCLUDE_xResumeFromISR | 恢复在中断中挂起的任务 |
INCLUDE_vTaskDelayUntil | 任务绝对延时 |
INCLUDE_vTaskDelay | 任务延时 |
INCLUDE_xTaskGetSchedulerState | 获取任务调度器状态 |
INCLUDE_xTaskGetCurrentTaskHandle | 获取当前任务的任务句柄 |
INCLUDE_uxTaskGetStackHighWaterMark | 获取任务堆栈历史剩余最小值 |
INCLUDE_xTaskGetIdleTaskHandle | 获取空闲任务的任务句柄 |
INCLUDE_eTaskGetState | 获取任务状态 |
INCLUDE_xEventGroupSetBitFromISR | 在中断中设置事件标志位 |
INCLUDE_xTimerPendFunctionCall | 将函数的执行挂到定时器服务任务 |
INCLUDE_xTaskAbortDelay | 中断任务延时 |
INCLUDE_xTaskGetHandle | 通过任务名获取任务句柄 |
INCLUDE_xTaskResumeFromISR | 恢复在中断中挂起的任务 |
代码具体体现:
/* 可选函数, 1: 使能 */
#define INCLUDE_vTaskPrioritySet 1 // 设置任务优先级
#define INCLUDE_uxTaskPriorityGet 1 // 获取任务优先级
#define INCLUDE_vTaskDelete 1 // 删除任务
#define INCLUDE_vTaskSuspend 1 // 挂起任务
#define INCLUDE_xResumeFromISR 1 // 恢复在中断中挂起的任务
#define INCLUDE_vTaskDelayUntil 1 // 任务绝对延时
#define INCLUDE_vTaskDelay 1 // 任务延时
#define INCLUDE_xTaskGetSchedulerState 1 // 获取任务调度器状态
#define INCLUDE_xTaskGetCurrentTaskHandle 1 // 获取当前任务的任务句柄
#define INCLUDE_uxTaskGetStackHighWaterMark 1 // 获取任务堆栈历史剩余最小值
#define INCLUDE_xTaskGetIdleTaskHandle 1 // 获取空闲任务的任务句柄
#define INCLUDE_eTaskGetState 1 // 获取任务状态
#define INCLUDE_xEventGroupSetBitFromISR 1 // 在中断中设置事件标志位
#define INCLUDE_xTimerPendFunctionCall 1 // 将函数的执行挂到定时器服务任务
#define INCLUDE_xTaskAbortDelay 1 // 中断任务延时
#define INCLUDE_xTaskGetHandle 1 // 通过任务名获取任务句柄
#define INCLUDE_xTaskResumeFromISR 1 // 恢复在中断中挂起的任务
3. 其他配置项
配置项 | 功能 |
---|---|
xPortPendSVHandler | |
vPortSVCHandler | |
secureconfigMAX_SECURE_CONTEXTS |
代码具体体现:
/* FreeRTOS中断服务函数相关定义 */
#define xPortPendSVHandler PendSV_Handler
#define vPortSVCHandler SVC_Handler