基于STM32的FreeRTOS学习之FreeRTOS配置文件FreeRTOSConfig.h解读(三)

记录一下,方便以后翻阅~

1. FreeRTOSConfig.h文件

1.1 "INCLUDE_"开始的宏
使用"INCLUDE_"开头的宏用来使能或失能FreeRTOS中相应的API函数,如下图,INCLUDE_vTaskPrioritySet设置为1,表示使用vTaskPrioritySet函数。
在这里插入图片描述
其作用就是条件编译,这样可以根据实际需求减少系统占用的ROM和RAM大小。在移植的FreeRTOS_CORE分组中的task.c源文件里,有如下函数,这样就理解了吧。
在这里插入图片描述
1.2 "config"开始的宏
"config"开始的宏和"INCLUDE_"开头的宏作用一样,都是用来完成FreeRTOS的配置和裁剪。

在这里插入图片描述
接下来对"config"开始的宏进行简单解读

1)configAPPLICATION_ALLOCATED_HEAP
默认情况下FreeRTOS的堆内存是由编译器来分配的,将configAPPLICATION_ALLOCATED_HEAP定义为1可由用户自行设置,堆内存在heap_1.c、heap_2.c、heap_3.c、heap_4.c、heap_5.c有定义。在前章节移植时采用heap_4.c,如下图定义:

在这里插入图片描述
如果configAPPLICATION_ALLOCATED_HEAP定义为1,那么堆内存由ucHeap决定,否则由编译器来分配。

2)configASSERT
FreeRTOS内核中的关键点都会用configASSERT(x),当x为0时说明有错误发生,该函数一般在调试阶段使用,因为开销较大。
使用举例:

#define vAssertCalled(char,int) printf("Error:%s,%d\r\n",char,int)
#define configASSERT((x))  if((x)==0)  vAssertCalled(__FILE_,__LINE__);

一般vAssertCalled()函数有用户定义,当参数x错误时通过串口打印发送错误文件名和错误号。

3)configCHECK_FOR_STACK_OVERFLOW
设置堆栈溢出检测,每个任务都有一个任务堆栈:
若使用函数xTaskCreate()创建一个任务的话那么这个任务的堆栈是自动从FreeRTOS的堆(ucHeap)中分配的,堆栈的大小是由函数xTaskCreate()的参数usStackDepth来决定的;
若使用xTaskCreateStatic()创建任务的话,其任务堆栈是由用户设置的,参数pxStackBuffer为任务堆栈,一般是一个数组。
堆栈溢出会导致应用程序不稳定。
FreeRTOS提供两个机制来检测和调试堆栈溢出,即configCHECK_FOR_STACK_OVERFLOW不为0时,必须提供一个回调函数,当内核检测到堆栈溢出后就调用这个回调函数:

void vApplicationStackOverflowHook(TaskHandle_t xTask, char*  pcTaskName);

参数xTask是任务句柄,pcTaskName是任务名字,查看变量pxCurrentTCB可确定哪个任务发生堆栈溢出。

4)configCPU_CLOCK_HZ
设置CPU的频率

5)configSUPPORT_DYNAMIC_ALLOCATION
1时,创建FreeRTOS内核对象时需要的RAM从FreeRTOS的堆中动态获取内存;0时需要用户自行提供。默认设1。

6)configENABLE_BACKWARD_COMPATIBILITY
默认1,保证代码从v8.0.0之前版本升级到最新版本后不需要修改。

7)configGENERATE_RUN_TIME_STATS
设置为1开启时间统计功能,相应API函数会被编译,且还要定义如下的宏;为0时关闭统计功能。

在这里插入图片描述
8)configIDLE_SHOULD_YIELD
定义了与空闲任务(idle Task)处同等优先级的其他用户任务的行为,为0时空闲任务不会为其他处于同等优先级的任务让出CPU使用权;为1时就让出使用权,除非没有就绪的用户任务,这样话费在空闲任务上的时间会很少,但也有副作用
在这里插入图片描述
参考上图进一步说明,有三个用户任务:A、B、C,还有一个空闲任务I,用户任务和空闲任务处于同一优先级,任务切换发生在T0 ~ T7时刻。T0 ~ T1之间的时间为一个时间片。开始任务后,B、C执行了一个完整的时间片,T2时刻空闲任务I开始运行,运行一段时间后被A任务抢走CPU使用权,A任务运行到T3时刻发生任务切换,B任务开始运行。可以看出任务I和任务A一起使用了一个时间片,即A任务运行时间比其他任务少。
一般建议关闭该功能。

9)configMAX_CO_ROUTINE_PRIORITIES
设置可以分配给协程的最大优先级,即协程的优先级数。优先级可以从0(最低优先级) ~ configMAX_CO_ROUTINE_PRIORITIES-1(最高优先级)。

10)configMAX_PRIORITIES
设置任务的优先级数量,优先级从0(最低优先级) ~ configMAX_PRIORITIES-1(最高优先级)。

11)configMAX_TASK_NAME_LEN
设置任务名最大长度。

12)configMINIMAL_STACK_SIZE
设置空闲任务的最小任务堆栈大小,以字为单位,不是字节。如设为100的话,则堆栈大小是100*4=400字节。

13)configNUM_THREAD_LOCAL_STORAGE_POINTERS
设置每个任务的本地存储指针数组大小,任务控制块中有本地存储数组指针,用户应用程序可以在这些本地存储中存入一些数据。

14)configQUEUE_REGISTRY_SIZE
设置可以注册队列和信号量的最大数量,在使用内核调试器查看信号量和队列的时候需要设置此宏,且要先将消息队列和信号量进行注册,只有注册了队列和信号量才会再内核调试器中看到。

15)configSUPPORT_STATIC_ALLOCATION
当此宏定义为1,在创建一些内核对象时需要用户指定RAM,为0时使用heap.c中的动态内存管理函数来自动申请RAM。

16)configTICK_RATE_HZ
设置FreeRTOS的系统时钟节拍频率,单位Hz,此频率就是滴答定时器的中断频率。

17)configTIMER_QUEUE_LENGTH
配置FreeRTOS软件定时器的命令队列长度,软件定时器API函数会通过命令队列向软件定时器任务发送消息。

18)configTIMER_TASK_PRIORITY
设置软件定时器任务的优先级。

19)configTIMER_TASK_STACK_DEPTH
设置定时器服务任务的任务堆栈大小。

20)configTOTAL_HEAP_SIZE
设置堆大小,如果使用了动态内存管理的话,FreeRTOS在创建任务、信号量、队列等时候会使用heap.c中的内存申请函数来申请内存。这些内存是从堆ucHeap[configTOTAL_HEAP_SIZE]中申请的,堆的大小由configTOTAL_HEAP_SIZE定义。

21)configUSE_16_BIT_TICKS
设置系统节拍计数器变量数据类型,1时为16位,0时为32位。

22)configUSE_APPLICATION_TASK_TAG
1时,configUSE_APPLICATION_TASK_TAGF()和xTaskCallApplicationTaskHook()会被编译。

23)configUSE_CO_ROUTINES
1时启动协程,协程可以节省开销,但功能有限。建议关闭。

24)configUSE_COUNTING_SEMAPHORES
1时开启计算型信号量。

25)configUSE_DAEMON_TASK_STARTUP_HOOK
当宏configUSE_TIMERS和configUSE_DAEMON_TASK_STARTUP_HOOK都为1时,定义vApplicationDaemonTaskStartupHook()函数。

26)configUSE_IDLE_HOOK
1时使用空闲任务回调函数(钩子函数)。

27)configUSE_MALLOC_FAILED_HOOK
1时使用内存分配失败回调函数。

28)configUSE_MUTEXES
1时使用互斥信号量。

29)configUSE_PORT_OPTIMISED_TASK_SELECTION
FreeRTOS有两种方法选择下一个要运行的任务:
一是通用方法,特点如下:
1)当宏configUSE_PORT_OPTIMISED_TASK_SELECTION为0,或硬件不支持时;
2)希望所有硬件通用;
3)全部用C语言实现,但效率比特殊方法低;
4)不限制最大优先级数目的时候。
二是特殊方法(硬件方法),用MCU自带硬件指令实现,特点如下:
1)不是所有的硬件都支持;
2)当宏configUSE_PORT_OPTIMISED_TASK_SELECTION为1时;
3)硬件拥有特殊指令,如计算前导零(CLZ)指令;
4)比通用方法效率高;
5)会限制优先级数目,一般是32个。

30)configUSE_PREEMPTION
1时使用抢占式调度器,0时使用协程。
使用抢占式调度器时,内核会每个时钟节拍中断进行任务切换;
使用协程时,在如下地方进行任务切换:
1)一个任务调用了函数taskYIELD();
2)一个任务调用了可以使任务进入阻塞态的API函数;
3)应用程序明确定义了在中断中执行上下文切换。

31)configUSE_QUEUE_SETS
1时启用队列集功能。

32)configUSE_RECURSIVE_MUTEXES
1时使用递归互斥信号量。

33)configUSE_STATS_FORMATTING_FUNCTIONS
宏configUSE_TRACE_FACILITY和configUSE_STATS_FORMATTING_FUNCTIONS都为1时,函数vTaskList()和vTaskGetRunTimeStats()会被编译。

34)configUSE_TASK_NOTIFICATIONS
1时使用任务通知功能,开启后每个任务会多消耗8个字节。

35)configUSE_TICK_HOOK
1时使能时间片回调函数。

36)configUSE_TICKLESS_IDEL
1时使能低功耗tickless模式。

37)configUSE_TIMERS
1时使用软件定时器。当configUSE_TIMERS为1时,configTIMER_TASK_PRIORITY、configTIMER_QUEUE_LENGTH和configTIMER_TASK_STACK_DEPTH必须定义。

38)configUSE_TIME_SLICING
默认情况,FreeRTOS使用抢占式调度器,这意味调度器永远都在执行已经就绪了的最高优先级任务,优先级相同的任务在时钟节拍中断中进行切换,当宏configUSE_TIME_SLICING为0时不会在时钟节拍中断中执行相同优先级任务的任务切换。默认设1。

39)configUSE_TRACE_FACILITY
1时启用可视化跟踪调式。

对于FreeRTOSConfig头文件的解读就到此了。

猜你喜欢

转载自blog.csdn.net/Leisure_ksj/article/details/114683059
今日推荐