转载:FreeRTOS 配置文件详细功能解释

本文详细介绍FreeRTOS配置文件FreeRTOSConfig.h中的各项配置选项,包括基本配置、钩子函数配置、任务运行信息获取配置等,帮助初学者理解并熟练操作FreeRTOS配置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原文链接:http://blog.sina.com.cn/s/blog_98ee3a930102wf8c.html

    本章节为大家讲解FreeRTOS的配置文件FreeRTOSConfig.h中每个选项的作用。初学的话,一定要有个了解,随着以后的学习一定要熟练操作每个配置选项。

本章节内容主要整理自官网:http://www.freertos.org/a00110.html

7.1 配置选项说明

7.2 基本配置

7.3 钩子函数配置

7.4 任务运行信息获取配置

7.5 合作式任务配置

7.6 软件定时器配置

7.7 内核配置

7.8 断言配置

7.9 函数Include配置

7.10       总结

 

 

7.1  配置选项说明

对于初学者来说,要在以后的时间里达到熟练操作FreeRTOS的配置选项。大部分的选项在FreeRTOS.h文件里面都有默认的配置。用户在使用时,把用到配置选项放在FreeRTOSConfig.h文件配置即可。

7.2   基本配置

基本配置是FreeRTOS中经常用到的配置,下面分别进行介绍,这里有个感性认识即可,随着后面的使用中会熟练起来。

7.2.1      configUSE_PREEMPTION

u  配置为1

使能抢占式调度器。

u  配置为0

使能合作式调度器。

7.2.2     configUSE_PORT_OPTIMISED_TASK_SELECTION

此配置用于优化优先级列表中要执行的最高优先级任务的算法。对CM内核的移植文件,默认已经在文件portmacro.h文件中使能。

u  通用方式---配置为0:

l  所有平台的移植文件都可以配置为0,因为这是通用方式。

l  纯C编写,比专用方式效率低。

l  可用的优先级数量不限制。

u  专用方式---配置为1:

l  部分平台支持。

l  这些平台架构有专用的汇编指令,比如CLZ(Count Leading Zeros)指令,通过这些指令可以加快算法执行速度。

l  比通用方式高效。

l  有最大优先级数限制,通常限制为32个。

7.2.3     configUSE_TICKLESS_IDLE

此配置用于使能tickless低功耗模式

u  配置为1

使能tickless低功耗模式

u  配置为0

禁能tickless低功耗模式

7.2.4     configCPU_CLOCK_HZ

此参数用于定义CPU的主频,单位Hz。

7.2.5     configTICK_RATE_HZ

此参数用于定义系统时钟节拍数,单位Hz,一般取1000Hz即可。本教程配套的例子也全部采用这个时钟节拍数。过高的的系统时钟节拍将使得FreeRTOS内核运行占用过多的时间,增加系统负荷。

7.2.6     configMAX_PRIORITIES

此参数用于定义可供用户使用的最大优先级数,如果这个定义的是5,那么用户可以使用的优先级号是0,1,2,3,4,不包含5,对于这一点,初学者要特别的注意。

7.2.7     configMINIMAL_STACK_SIZE

此参数用于定义空闲任务的栈空间大小,单位字,即4字节。

7.2.8     configTOTAL_HEAP_SIZE

定义堆大小,FreeRTOS内核,用户动态内存申请,任务栈,任务创建,信号量创建,消息队列创建等都需要用这个空间。

7.2.9     configMAX_TASK_NAME_LEN

定义任务名最大的字符数,末尾的结束符 '\0'也要计算在内。

7.2.10configUSE_16_BIT_TICKS

系统时钟节拍计数使用TickType_t数据类型定义的。

如果用户使能了宏定义 configUSE_16_BIT_TICKS,那么TickType_t定义的就是16位无符号数,如果没有使能,那么TickType_t定义的就是32位无符号数。对于32位架构的处理器,一定要禁止此宏定义,即设置此宏定义数值为0即可。而16位无符号数类型主要用于8位和16位架构的处理器。

7.2.11configIDLE_SHOULD_YIELD

此参数用于使能与空闲任务同优先级的任务,只有满足以下两个条件时,此参数才有效果:

1.     使能抢占式调度器。

2.     有创建与空闲任务同优先级的任务。

配置为1,就可以使能此特性了,实际应用中不建议用户使用此功能,将其配置为0即可。

7.2.12configUSE_TASK_NOTIFICATIONS

u  配置为1

使能任务间直接的消息传递,包含信号量,事件标志组和消息邮箱。

u  配置为0

禁能此特性。

7.2.13configUSE_MUTEXES

u  配置为1

使能互斥信号量

u  配置为0

禁能互斥信号量

7.2.14configUSE_RECURSIVE_MUTEXES

u  配置为1

使能递归互斥信号量

u  配置为0

禁能递归互斥信号量

7.2.15configUSE_COUNTING_SEMAPHORES

u  配置为1

使能计数信号量

u  配置为0

禁能计数信号量

7.2.16configUSE_ALTERNATIVE_API

此配置将在以后的版本中被删除,建议用户不要再使用。

7.2.17configQUEUE_REGISTRY_SIZE

通过此定义来设置可以注册的信号量和消息队列个数。

队列注册有两个目的,这两个目的都与内核调试有关:

u  注册队列的时候,可以给队列起一个名字,当使用调试组件的时候,通过名字可以很容易的区分不同队列。

u  通过队列的相关信息,调试器可以很容易定位队列和信号量,能够定位信号量是因为FreeRTOS信号量也是基于队列实现的。

当然,如果用户没有使用内核方面的调试器,这个宏定义是没有意义的。

7.2.18configUSE_QUEUE_SETS

u  配置为1

使能消息队列。

u  配置为0

禁能消息队列。

7.2.19configUSE_TIME_SLICING

u  配置为1

使能时间片调度。

u  配置为0

禁能时间片调度。

u  用户没有配置此选项

如果用户没有配置此选项,默认在FreeRTOS.h文件中已经配置为1,即使能时间片调度。

7.2.20configUSE_NEWLIB_REENTRANT

u  配置为1

每个任务创建的时候将分配Newlib的重入结构体。

u  配置为0

禁止此特性。

7.2.21configENABLE_BACKWARD_COMPATIBILITY

u  配置为1

使能新版本对老版本的兼容特性,即向后兼容或者说向下兼容。

u  配置为0

禁止此特性。

7.2.22configNUM_THREAD_LOCAL_STORAGE_POINTERS

此配置用于定义线程局部指针变量的个数。

7.3  钩子函数配置

钩子函数的主要功能是用于函数的扩展,用户可以根据自己的需要往里面添加相关的测试函数。

7.3.1     configUSE_IDLE_HOOK

u  配置为1

使能空闲任务的钩子函数

u  配置为0

禁能空闲任务钩子函数

7.3.2     configUSE_MALLOC_FAILED_HOOK

当创建任务,信号量或者消息队列时,FreeRTOS通过函数pvPortMalloc()申请动态内存。

u  配置为1

使能动态内存申请失败时的钩子函数

u  配置为0

禁能动态内存申请失败时的钩子函数

7.3.3     configUSE_TICK_HOOK

u  配置为1

使能滴答定时器中断里面执行的钩子函数

u  配置为0

禁能滴答定时器中断里面执行的钩子函数

7.3.4     configCHECK_FOR_STACK_OVERFLOW

FreeRTOS的栈溢出检测支持两种方法,为了方便描述,我们这里将其称之为方法一和方法二。

u  配置为2

栈溢出检测使用方法二。

u  配置为1

栈溢出检测使用方法一。

u  配置为0

禁止栈溢出检测。

7.4  任务运行信息获取配置

7.4.1     configGENERATE_RUN_TIME_STATS

u  配置为1

使能任务运行状态参数统计。

u  配置为0

禁止此特性。

7.4.2     configUSE_TRACE_FACILITY

u  配置为1

使能此配置将添加额外的结构体成员和函数,以此来协助可视化和跟踪,在使用IAR中的FreeRTOS插件时要使能这个配置,否则无法显示任务栈的使用情况。

u  配置为0

禁能此特性。

7.4.3     configUSE_STATS_FORMATTING_FUNCTIONS

用户配置宏定义configUSE_TRACE_FACILITY和configUSE_STATS_FORMATTING_FUNCTIONS都为1的时候,将使能函数vTaskList() 和 vTaskGetRunTimeStats(),如果两者中任何一个为0,那么这两个函数都将被禁能。

7.5  合作式任务配置

7.5.1     configUSE_CO_ROUTINES

u  配置为1

使能合作式调度相关函数。

u  配置为0

禁能合作式调度相关函数。

7.5.2     configMAX_CO_ROUTINE_PRIORITIES

此参数用于定义可供用户使用的最大的合作式任务优先级数,如果这个定义的是5,那么用户可以使用的优先级号是0,1,2,3,4,不包含5,对于这一点,初学者要特别的注意。

7.6  软件定时器配置

7.6.1     configUSE_TIMERS

u  配置为1

使能软件定时器。

u  配置为0

禁能软件定时器。

7.6.2     configTIMER_TASK_PRIORITY

配置软件定时器任务的优先级。

7.6.3     configTIMER_QUEUE_LENGTH

配置软件定时器命令队列的长度。

7.6.4     configTIMER_TASK_STACK_DEPTH

配置软件定时器任务的栈空间大小。

7.7  内核配置

内核配置相关的几个宏定义参看第12章的12.3小节,这几个配置稍复杂些,专门放在了12.3小节进行详细说明。

 

7.8  断言配置

FreeRTOS中的断言函数configASSERT()和标准C中的断言函数assert()是一样的,如果断言函数的参数为0时将触发断言函数的执行。

FreeRTOS的断言功能在调试阶段是非常有用的,可以有效地检查参数错误和运行中的错误,但在正式发布软件时,请将此功能关闭,因为断言功能会增加工程代码大小并降低工程执行效率。关闭断言也比较简单,如果FreeRTOSConfig.h文件中有断言的宏定义,将其注释掉即可,如果没有宏定义,默认在FreeRTOS.h文件中就是关闭的。

教程配套的例子统一采用如下的断言方法:

 

#define configASSERT( ( x ) )     if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); for( ;; ); }

在使用调试器的情况下,一旦出现断言失败,会关闭中断,程序会死在这个for循环中,此时用户可以很容易就锁定函数出错位置。

当然,采用下面这种方法也是可以的:

 

#define configASSERT( ( x ) )     if( ( x ) == 0 ) vAssertCalled( __FILE__, __LINE__ )

其中关键字 __LINE__ 表示源代码行号,关键字__FILE__表示源代码文件名。用户可以自行测试下这个函数vAssertCalled,在这个函数里面调用一下串口打印之类的功能,将出现错误的源文件和代码行号打印出来。这种方法也可以很方便的锁定出错的位置。

调试阶段出现断言失败的情况下,不限制以上两种处理方法,用户采用适合自己的方法即可。

7.9  函数Include配置

函数Include配置主要是指用户可以根据需要使能或者禁止在工程中使用相应的函数,配置为1,表示使能,即可以在工程中使用相应函数。配置为0,表示禁止,即禁止在工程中使用相应函数。可以这样设置的函数主要有如下几种:

 

#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     0

#define INCLUDE_xTaskGetIdleTaskHandle          0

#define INCLUDE_xTimerGetTimerDaemonTaskHandle  0

#define INCLUDE_pcTaskGetTaskName               0

#define INCLUDE_eTaskGetState                   0

#define INCLUDE_xEventGroupSetBitFromISR        1

#define INCLUDE_xTimerPendFunctionCall          0

对于配置1,但用户在工程中没有用到的函数,编译器一般都会把这些冗余函数删掉,不会添加到最终的hex文件中。

7.10总结

本章节仅是对每个配置选项进行介绍,等有了几次工程的配置经验后基本就熟练了。

转载于:https://www.cnblogs.com/w-smile/p/9889028.html

<think>嗯,用户的问题是关于FreeRTOS中静态创建任务时需要配置的宏和必须实现的函数。用户已经知道需要将configSUPPORT_STATIC_ALLOCATION设置为1,并且需要实现vApplicationGetIdleTaskMemory和vApplicationGetTimerTaskMemory这两个函数。用户还提到这两个函数用于设定空闲任务和定时器任务的堆栈大小,必须由用户自己分配,而不是动态分配。 首先,我需要确认用户的理解是否正确。静态创建任务意味着任务的控制块和堆栈内存由用户预先分配,而不是由FreeRTOS动态分配。因此,确实需要启用configSUPPORT_STATIC_ALLOCATION宏。同时,空闲任务和定时器任务在静态分配的情况下也需要用户提供内存,所以那两个函数是必须的。 接下来,用户可能想知道为什么必须实现这两个函数。我需要解释这两个函数的作用:它们为FreeRTOS提供空闲任务和定时器任务所需的内存空间,当使用静态分配时,系统不会自动分配,所以用户必须手动分配静态内存区域。 用户可能存在的疑问点包括:如何正确实现这两个函数?需要分配多大的内存?静态分配和动态分配的区别是什么?以及为什么必须将宏设置为1。此外,用户可能对如何具体操作和配置这些部分不太清楚,需要给出示例代码和步骤说明。 我需要确保回答结构清晰,分步骤解释,并提供示例代码帮助理解。同时,要强调静态分配的优势,比如确定性和避免内存碎片,以及需要注意的地方,比如内存大小计算和配置文件的修改。 可能还需要提醒用户,如果不使用静态分配,这些函数可能不需要实现,但一旦启用静态分配,就必须提供这些内存区域,否则编译会出错。此外,确保用户了解如何计算堆栈大小,避免分配不足导致任务崩溃。 最后,总结关键点,确保用户明确配置步骤和实现方法,以及背后的原理,帮助他们正确应用静态内存分配在FreeRTOS项目中。</think>--- ### 一、**静态创建任务的核心条件** 在FreeRTOS中,**静态创建任务**需要满足以下两个必要条件: 1. **启用静态内存分配支持**: 在`FreeRTOSConfig.h`中定义宏`configSUPPORT_STATIC_ALLOCATION = 1`,告知FreeRTOS允许使用静态内存分配API(如`xTaskCreateStatic()`)。 2. **实现内存分配函数**: 用户需手动为**空闲任务(Idle Task)**和**定时器任务(Timer Task)**分配静态内存,通过实现以下两个回调函数: - `vApplicationGetIdleTaskMemory()` - `vApplicationGetTimerTaskMemory()` --- ### 二、**为何需要这两个函数?** FreeRTOS在启动时会自动创建两个系统任务: 1. **空闲任务(Idle Task)**: 负责释放已删除任务的内存(若启用了`configUSE_PREEMPTION`)和低功耗管理。 2. **定时器任务(Timer Task)**: 用于处理软件定时器回调(若启用了`configUSE_TIMERS`)。 **关键点**: 当使用静态内存分配时,**所有任务(包括系统任务)的内存必须由用户静态分配**,因此需要通过这两个函数提供空闲任务和定时器任务的内存控制块(TCB)及堆栈空间。 --- ### 三、**函数实现详解** #### 1. `vApplicationGetIdleTaskMemory()` **功能**:为**空闲任务**分配静态内存。 **参数**: - **ppxIdleTaskTCBBuffer**:指向TCB(任务控制块)指针的指针。 - **ppxIdleTaskStackBuffer**:指向堆栈空间指针的指针。 - **pulIdleTaskStackSize**:返回堆栈大小(单位为字,例如uint32_t)。 **示例实现**: ```c // 静态分配空闲任务的TCB和堆栈 static StaticTask_t xIdleTaskTCB; static StackType_t xIdleTaskStack[configMINIMAL_STACK_SIZE]; void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize) { *ppxIdleTaskTCBBuffer = &xIdleTaskTCB; *ppxIdleTaskStackBuffer = xIdleTaskStack; *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE; } ``` #### 2. `vApplicationGetTimerTaskMemory()` **功能**:为**定时器任务**分配静态内存。 **参数**:同空闲任务函数。 **示例实现**: ```c // 静态分配定时器任务的TCB和堆栈 static StaticTask_t xTimerTaskTCB; static StackType_t xTimerTaskStack[configTIMER_TASK_STACK_DEPTH]; void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize) { *ppxTimerTaskTCBBuffer = &xTimerTaskTCB; *ppxTimerTaskStackBuffer = xTimerTaskStack; *pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH; } ``` --- ### 四、**静态分配与动态分配的区别** | **特性** | **静态分配** | **动态分配** | |-------------------|--------------------------------------------|---------------------------------------| | 内存来源 | 用户预定义的静态数组或全局变量 | FreeRTOS堆内存(如`heap_4.c`) | | 内存确定性 | 确定性强,无内存碎片风险 | 依赖堆管理,可能产生碎片 | | 适用场景 | 对实时性要求高、资源受限的嵌入式系统 | 灵活性要求高的应用 | | API函数 | `xTaskCreateStatic()` | `xTaskCreate()` | | 系统任务内存管理 | 需用户手动分配(通过回调函数) | 由FreeRTOS自动分配 | --- ### 五、**配置与验证步骤** 1. **修改FreeRTOSConfig.h**: ```c #define configSUPPORT_STATIC_ALLOCATION 1 #define configUSE_TIMERS 1 // 若需定时器任务 ``` 2. **实现回调函数**: 按上述示例代码实现`vApplicationGetIdleTaskMemory()`和`vApplicationGetTimerTaskMemory()`。 3. **编译验证**: 若未实现这两个函数,编译时会报错: ``` undefined reference to `vApplicationGetIdleTaskMemory' ``` --- ### 六、**常见问题** #### 1. **堆栈大小如何确定?** - **空闲任务**:通常使用`configMINIMAL_STACK_SIZE`(默认值在`FreeRTOSConfig.h`中定义)。 - **定时器任务**:使用`configTIMER_TASK_STACK_DEPTH`,需根据定时器回调复杂度调整。 #### 2. **是否可以不实现这两个函数?** - **动态分配场景**:若仅使用动态分配(`configSUPPORT_STATIC_ALLOCATION = 0`),则无需实现。 - **静态分配场景**:必须实现,否则链接失败。 #### 3. **静态内存的生命周期** 静态分配的内存需在全局或静态作用域定义,确保在任务运行期间始终有效。 --- ### 七、**总结** - **核心逻辑**:静态分配要求用户完全掌控内存管理,包括系统任务。 - **实现要点**: - 启用`configSUPPORT_STATIC_ALLOCATION`。 - 为系统任务分配静态内存并实现回调函数。 - **优势**:提高系统确定性,避免动态内存管理的风险。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值