STM32Cube高效开发教程<高级篇><FreeRTOS>(二)-----FreeRTOS的文件组成和基本原理

   声明:本人水平有限,博客可能存在部分错误的地方,请广大读者谅解并向本人反馈错误。
   本专栏博客参考《STM32Cube高效开发教程(高级篇)》,有意向的读者可以购买正版书籍辅助学习,本书籍由王维波老师、鄢志丹老师、王钊老师倾力打造,书籍内容干货满满。

一、 FreeRTOS的文件组成

  STM32Cube高效开发教程<高级篇><FreeRTOS>(一)-----FreeRTOS基础示例中,与FreeRTOS相关的程序文件主要分为可修改的用户程序文件和不可修改的FreeRTOS源程序文件。上一篇博客中介绍的freertos.c是可修改的用户程序文件,FreeRTOS中任务、信号量等对象的创建,用户任务函数都在这个文件里实现。项目中FreeRTOS的源程序文件都在目录\Middlewares\ThirdParty\FreeRTOS\Source下,这些是针对选择的MCU型号做好了移植的文件。使用CubeMX生成代码时,用户无须关心FreeRTOS的移植问题,所需的源程序文件也为用户组织好了。
  虽然无须自己进行程序移植和文件组织,但是了解FreeRTOS的文件组成以及主要文件的功能,对于掌握FreeRTOS的原理和使用还是有帮助的。FreeRTOS的源程序文件大致可以分为5类,如下图所示:
在这里插入图片描述

1.1 用户配置和程序文件

  用户配置和程序文件包括如下2个文件,用于对FreeRTOS进行各种配置和功能裁剪,以及实现用户任务的功能

  • 文件FreeRTOSConfig.h:是对FreeRTOS进行各种配置的文件,FreeRTOS的功能裁剪就是通过这个文件里的各种宏定义实现的。
  • 文件feertos.c:包含FreeRTOS对象初始化函数MXFREERTOS_InitO和任务函数,是编写用户代码的主要文件。

1.2 FreeRTOS通用功能文件

  这些是实现FreeRTOS的任务、队列、信号量、软件定时器、事件组等通用功能的文件。这些功能与硬件无关。源程序文件在\Source目录下,头文件在\Source\Include目录下。这两个目录下的源程序文件和头文件如下图所示。
在这里插入图片描述
  这些通用功能文件及其功能如下表。在一个嵌入式操作系统中,任务管理是必需的,某些功能是在用到时才需要加入的,如事件组、软件定时器、信号量、流缓冲区等。CubeMX在生成代码时,将这些文件全部复制到了项目里,但是它们不会被全部编译到最终的二进制文件里。用户可以对FreeRTOS的各种参数进行配置,实现功能裁剪这些参数配置实际就是各种条件编译的条件定义。

文件功能
croutine.h/.c实现协程(co-routine)功能的程序文件,协程主要用于内存非常小的MCU,现在已经很少使用
event_groups.h/.c实现事件组功能的程序文件
list.h/list.c实现链表功能的程序文件,FreeRTOS的任务调度器用到链表
queue.h/queue.c实现队列功能的程序文件
semphr.h实现信号量功能的文件,信号量是基于队列的,信号量操作的函数都是宏函数,其实现都是调用队列处理的函数
task.h/tasks.c实现任务管理功能的程序文件
timers.h/timers.c实现软件定时器功能的程序文件
stream_buffer.h/stream_buffer.c实现l流缓冲区功能的程序文件。流缓冲区是一种优化的进程间通信机制,是在V10版本中才引入的功能
message_buffer.h实现消息缓冲区的文件。实现消息缓冲区功能的所有函数都是宏函数,因为消息缓冲区是基于流缓冲区实现的,都调用流缓冲区的函数。消息缓冲区是在V10版本中才引入的功能
mpu_prototypes.hMPU(内存保护单)功能的头文件。该文件定义的函数是在标准函数前面增加前缀“MPU”,当应用程序使用MPU功能时,FreeRTOSmpu wrappers.h内核会优先执行此文件中的函数

1.3 FreeRTOS通用定义文件

  目录\Source\include下有几个与硬件无关的通用定义文件。
  (1)文件FreeRTOS.h。这个文件包含FreeRTOS的默认去定义、数据类型定义、接口函数定义等。FreeRTOS.h中有一些默认的用于FreoRTOS功能裁剪的宏定义,例如:

#ifndef configIDLE_SHOULD_YIELD
	#define configIDLE_SHOULD_YIELD 1
#endif
#ifndef INCLUDE_vTaskDelete
	#define INCLUDE_yTaskDelete     0
#endif

  FreeRTOS的功能裁剪就是通过这些宏定义实现的,这些用于配置的宏定义主要分为如下两类

  • 前缀为“config”的宏表示某种参数设置,一般地,值为1表示开启此功能,值为0表示禁用此功能,如configIDLE_SHOULD_YIELD表示空闲任务是否对同优先级的任务让出处理器使用权。
  • 前缀为“INCLUDE_”的宏表示是否编译某个函数的源代码,例如,宏INCLUDE_vTaskDelete的值为1,就表示编译函数vTaskDelete()的源代码,值为0就表示不编译函数vTaskDelete()的源代码。

  在FreeRTOS中,这些宏定义通常称为参数,因为它们决定了系统的一些特性。文件FreeRTOS.h包含系统默认的一些参数的宏定义,不要直接修改此文件的内容。用户可修改的配置文件FreeRTOSConfigh,这个文件也包含大量前缀为“config”和“INCLUDE”的宏定义。如果文件FreeRTOSConfig.h中没有定义宏,就使用文件FreeRTOS.h中的默认定义。
  FreeRTOS的大部分功能配置都可以通过CubeMX可视化设置完成,并生成文件FreeRTOSConfig.h中的宏定义代码。
  (2)文件projdefs.h。这个文件包含FreeRTOS中的一些通用定义,如错误编号宏定义,逻
辑值的宏定义等。文件projdef.h中常用的几个宏定义及其功能见下表。

宏定义功能
PdFALSE0表示逻辑值false
pdTRUE1表示逻辑值true
pdFAIL0表示逻辑值false
pdPASS1表示逻辑值true
pdMS_TO_TICKS(xTimelnMs)-这是个宏函数,其功能是将xTimelnMs表示的毫秒数转换xTimelnMs为时钟节拍数,因为延时函数vTaskDelayO的输入参数是节拍数

  (3)文件stack_macros.h和StackMacros.h。这两个文件的内容完全一样,只是为了向后兼容,才出现了两个文件。这两个文件定义了进行栈溢出检查的函数,如果要使用栈溢出检查功能,需要设置参数configCHECKFOR_STACK_OVERFLOW的值为1或者2。

1.4 CMSIS-RTOS标准接口文件

  目录ISource\CMSIS_RTOS_V2下是CMSIS-RTOS标准接口文件,如下图所示。这些文件里的宏定义、数据类型、函数名称等的前缓都是”os”。原理上来说,这些函数和数据类型的名称与具体的RTOS无关,它们是CMSIS-RTOS标准的定义。在具体实现上,这些前缀为“os”的函数调用具体移植的RTOS的实现函数,例如,若移植的是FreeRTOS,“os”函数就调用FreeRTOS的
实现函数,若移植的是uC/OS-Ⅱ,“os”函数就调用uC/OS-Ⅱ的实现函数。
在这里插入图片描述
  本系列博客使用的是FreeRTOS,所以这些“os”区函数调用的都是FreeRTOS的函数。例如,CMSIS-RTOS的延时函数.osDelay()的内部就是调用了FreeRTOS的延时函数vTaskDelay()。
  在上一篇博客示例中,使用过一些类似的函数:osThreadNew()的内部调用
xTaskCreate()或福xTaskCreateStatic()创建任务;osKernelStart()的内部调用vTaskStartScheduler()启动FreeRTOS内核运行
  从原理上来说,如果在程序中使用这些CMSIS-RTOS标准接口函数和类型定义,可以减少与具体RTOS的关联。例如,一个应用程序原先是使用FreeRTOS写的,后来要改为使用uC/OS-II,则只需改RTOS移植部分的程序,而无须改应用程序。但是这种情况可能极少。
  在本博客中,为了讲解FreeRTOS的使用,后面在编写用户功能代码时,将尽量直接使用FreeRTOS的函数,而不使用CMSIS-RTOS接口函数。但是CubeMX自动生成的代码使用的基本都是CMSIS-RTOS接口函数,这些是不需要去更改的,明白两者之间的关系即可。

1.5 硬件相关的移植文件

  硬件相关的移植文件就是需要根据硬件类型进行改写的文件,一个移植好的版本称为一个端口(port),这些文件在目录\Source\portable下,又分为架构与编译器、内存管理两个部分,如下图所示:
在这里插入图片描述
  (1)处理器架构和编译器相关文件。处理器架构和编译器部分有2个文件,即portmacro.h和port.c。这两个文件里是些与硬件相关的基础数据类型、宏定义和函数定义。因为某些函数的功能实现涉及底层操作,其实现代码甚至是用汇编语言写的,所以与硬件密切相关。
  FreeRTOS需要使用一个基础数据类型定义头文件stdint.h,这个头文件定义的是uint8_t、uint32_t等基础数据类型,STM32的HAL库包含这个文件。
  在文件pormacro.h中,我们重新定义了一些基础数据类型的类型符号,定义的代码如下。Cortex-M4是32位处理器,这些类型定义对应的整数或浮点数类型见注释。

#define PortCHAR           char       //int8t
#define PortFLOAT          float      //4字节浮点数
#define portDOUBLE         double     //8字节浮点数
#define PortLONG           long       //int32t
#define portSHORT          short      //int16t
#define portSTACK_TYPE     uint32_t    //栈数据类型
#define PortBASE_TYPE      long       //int32_t
typedef PortSTACK_TYPE     StackType_t; //栈数据类型stackType_t,是uint32_t
typedef long               BaseType_t;  //基础数据类型Baserype_t,是int32_t
typedef unsigned long      UBaseType_t; //基础数据类型UBaserype_t,是uint32_
typedef uint32_t           Tickrype_t;  //节拍数类型TickType_t,是uint32_t

  重新定义的4个数据类型符号是为了移植方便,它们的等效定义和意义如下表所示。

数据类型符号等效定义意义
BaseType_tint32_t基础数据类型,32位整数
UBaseType_tuint32_t基础数据类型,32位无符号整数
StackType_tuint32_t栈数据类型,32位无符号整数
Tickrype_tuint32_t基础时钟节拍数类型,无符号整数

  (2)内存管理相关文件。内存管理涉及内存动态分配和释放等操作,与具体的处理器密切相关。FreeRTOS提供5种内存管理方案,即heap_1至heap_5,在CubeMX里设置FreeRTOS参数时,选择1种即可。在上图中,内存管理文件是heap_4.c,这也是默认的内存管理方案。
  文件heap_4.c实现了动态分配内存的函数pvPorMalloc(),释放内存的函数vPortFree(),以及其他几个函数。heap_4.c以目录\Sourcelinclude下的portable.h文件为头文件。

二、 FreeRTOS的编码规则

  FreeRTOS的核心源程序文件遵循一套编码规则,其变量命名、函数命名、宏定义命名等都有规律,知道这些规律有助于理解函数名、宏定义的意义。

2.1 变量名

  变量名使用类型前缀。通过变量名的前缓,用户可以知道变量的类型

  • 对于stdinth中定义的各种标准类型整数,前缀“c”表示char类型变量,前“s”表示it16_t(short)类型变量,前缀1表示inf32-类型变量。对于无符号(unsigned)整数,再在前面增加前缀“u”,如“uc”表示uint8类型,“us”表示uint16t,“ul”表示uint32t类型。
  • BaseTypet和所有其他非标准类型的变量名,如结构体变量、任务句板、队列句柄等都用前缀"x"。
  • UBaseTypet类型的变量使用前缀"ux"。
  • 指针类型变量在前面再增加一个“p”,例如,“pc”表示Char*类型。

2.2 函数名

  函数名的前缀由返回值类型和函数所在文件组成,若返回值为void类型,则类型前缀是"v",举例如下。

  • 函数xTaskCreate(),其返回值为BaseTyPe类型,在文件task.h中定义。
  • 函数vQueueDelete(),其返回值为void,在文件queue.h中定义。
  • 函数pcTimerGetName(),其返回值为char *,在文件timer.h中定义。
  • 函数pvPortMalloc(),其返回值为void *,在文件portable.h中定义。

  如果函数是用static声明的文件内使用的有函数则其前级为prv”.例如,tasks.c文件中的函数prvAddNewTaskToRegdyListO,因为私有函数不会被外部调用,所以函数名中就不用包括返回值类型和所在文件的前缀了。
  CMSIS-RTOS相关文件中定义的函数前都是“os”,不包括返回值类型和所在文件的前缀。例如,cmsis_os2.h中的函数osThreadNew()、osDelay()等。

2.3 宏名称

  宏定义和宏函数的名称一般用大写字母,并使用小写字母前缀表示宏的功能分组。FreeRTOS中常用的宏名称前级见下表。

前缀意义所在文件实例
config用于系统功能配置的宏FreeRTOSConfig、EreeRTOS.hconfigUSE_MUTEXES、configTICK_RATE_HZ
INCLUDE_条件编译某个函数的宏FreeRTOSConfig.h、FreeRTOS.hINCLUDE_vTaskDelay、INCLUDE_vTaskDelete
task任务相关的宏task.h、task.ctaskENTER_CRITICAL()、taskIDLE_PRIORITY
queue队列相关的宏queue.hqueueQUEUE_TYPE_MUTEX
pd项目通用宏定义projdefs.hPdTRUE,pdFALSE
port修植接口文件定义的宏portablc.h、portmacro.h、port.cportBYTE_ALIGNMENT_MASK、portCHAR、portMAX_24_BIT_NUMBER
tmr软件定时器相关的宏timer.htmrCOMMAND_START
osCMSIS-RTO3接口相关的宏cmsis_os.h、cmsis_os2.hosFeature_SysTick、osFlagsWaitAll

三、FreeRTOS的配置和功能裁剪

  FreeRTOS的配置和功能裁剪主要是通过文件FeoRTOSConfig.h和FreeRTOS.h中的一些宏定义实现的,前缀为“config”的宏用于配置FreeRTOS的一些参数,前级为“INCLUDE_”的宏用于控制是否编译某些函数的源代码。文件FreeRTOS.h中的宏定义是系统默认的宏定义,请勿直接修改。FeeRTOSConfig.h是用户可修改的配置文件,如果一个宏没有在文件
FeeRTOSConfig.h中重新定义,就使用文件FreeRTOS.h中的默认定义。
  在CubeMX中,FreeRTOS的配置界面中有Config parameters和Includ eparameters两个页面,用于对这两类宏进行设置。在本节中,我们介绍CubeMX中设置的这些宏的意义,但很多概念需要在后面才会具体讲到,如果读者对这些概念不工解也没关系,在后面的博客中会详细介绍。

3.1 “config”类的宏

  前缀为“config”的宏用于对FreeRTOS的一些参数进行配置。上一博客中的示例完全使用了FreeRTOS的默认配置,例如,文件FeeRTOSConfig.h中部分这类宏定义代码如下:

#define configENABLE_FPU                         0
#define configENABLE_MPU                         0

#define configUSE_PREEMPTION                     1
#define configSUPPORT_STATIC_ALLOCATION          1
#define configSUPPORT_DYNAMIC_ALLOCATION         1
#define configUSE_IDLE_HOOK                      0
#define configUSE_TICK_HOOK                      0
#define configCPU_CLOCK_HZ                       ( SystemCoreClock )
#define configTICK_RATE_HZ                       ((TickType_t)1000)
#define configMAX_PRIORITIES                     ( 56 )
#define configMINIMAL_STACK_SIZE                 ((uint16_t)128)
#define configTOTAL_HEAP_SIZE                    ((size_t)15360)
#define configMAX_TASK_NAME_LEN                  ( 16 )
#define configUSE_TRACE_FACILITY                 1
#define configUSE_16_BIT_TICKS                   0
#define configUSE_MUTEXES                        1
#define configQUEUE_REGISTRY_SIZE                8
#define configUSE_RECURSIVE_MUTEXES              1
#define configUSE_COUNTING_SEMAPHORES            1
#define configUSE_PORT_OPTIMISED_TASK_SELECTION  0
/* Software timer definitions. */
#define configUSE_TIMERS                         1
#define configTIMER_TASK_PRIORITY                ( 2 )
#define configTIMER_QUEUE_LENGTH                 10
#define configTIMER_TASK_STACK_DEPTH             256

  在CubeMX中修改了值的参数都会在文件FreeRTOSConfig.h中生成语句。有默认值的宏
定义在文件FreeRTOS.h中,例如,文件FreeRTOS.h中有如下的定义:

#ifndef configIDLE_SHOULD_YIELD
	#define configIDLE_SHOULD_YIELD		1
#endif

  默认情况下,文件FreeRTOSConfig.h中没有定义宏configIDLE_SHOULD_YIELD,就使用
文件FreeRTOS.h中的默认定义。如果通过CubeMX修改了这个参数,在FreeRTOSConfig.h中
生成了如下的宏定义,那么就使用FreeRTOSConfig.h中的定义。

#define configIDLE_SHOULD_YIELD		0

  在CubeMX中,FreeRTOS参数配置的ConfigParameters页面的参数,分为好几组,这些参数对应于文件FreoRTOSConfig.h和FreeRTOS.h中相应的宏,下面我们分别介绍这几组参数设置的内容。
  (1)MPU/FPU。这组有两个参数,用于设置是否使用内存保护单元MPU和浑点数单元FPU,如下图所示。
在这里插入图片描述

  • ENABLE_MPU,使用MPU功能。虽然MCU硬件支持MPU,但是需要FreeRTOS的本地代码支持。
  • ENABLE_FPU,是否在FreeRTOS中使用FPU功能。STM32F4系列MCU是有FPU的。

  (2)Kernel settings,内核设置。这组是FreeRTOS内核的一些参数,设置的具体参数及其默认值如下图所示。某些参数是不允许修改的,就显示为灰色字体。某些参数只能选择一个参数值,例如,USE_MUTEXES只能选择Enabled。
在这里插入图片描述
  上图中所示的参数与文件FreeRTOSConfig.h或FreeRTOS.h中的宏是对应的,只是去掉
了前缀“config”,如USE_PREEMPTION对应的宏是configUSE_PREEMPTION。界面中逻辑型参数的可选值是Enabled和Disabled,对应于宏定义的值是1和0,这些宏一般是条件编译的条件,用于条件编译某段代码。上图中的这些参数的意义和默认值见下表。

配置参数默认值意义
USE_PREEMPTIONEnabledEnabled 表示使用抢占式(pie-cmpivc)任务调Enabled度器:Disabled表示使用合作式(co-operative)任务调度器
CPU_LCLOCK_HZSystemCorcClock系统核心时钟,即MCU的HCLK时钟
TICK_RATE_HZ1000系统响哈时控频率,设置范围为1至1000,默认为1000Hz所以周期建1ms
MAX_PRIORITIES56任务的最多优先级个数,这里固定为56,不可修改
MINIMAL_STACK_SIZE128 Words系统空闲任务的栈空间的最小值,设置范围为64至3840。在FreeRTOS中,栈空间的大小单位是字,在Corex-M架构中,一个字是4字节
MAX_TASK_NAME_LEN16任务名称字符串的最大长度,设置范围为12至255
USE_16_BIT_TICKSDisabled决定文件portmacro.h中定义的节拍数据类型TickType_t的具体类型,若这个值是Disabled,则TickType_t是uin32_类型,否则,是uint16类型。Cortex-M架构上TickType_t是uint32类型
IDLE_SHOULD_YIELDEnabled空闲任务是否对同众先级的任务主动让出CPU使用权
USE_MUTEXESEnabled是否使用互斤量,只能选择Enabled
USE_RECURSIVE_MUTEXESEnabled是否使用递归互斤量,只能选择Enabled
USE_COUNTING_SEMAPHORESEnabled是否使用计数信号量,只能选择Enabled
QUEUE_REGISTRY_SIZE8可注册的队列和信号量的最大数量,设置范围为0至255。使用内核调试器查看信号量和队列时,需要先注册队列和信号量
USE_APPLICATION_TASK_TAGDisabled是否使用应用程序的任务标(tag),若对应的宏是1,则会编译一些代码段,特别是文件tasks.c中的3个相关函数:vTaskSetApplicationTaskTag()、xTaskGetApplicationTaskTag()、xTaskCallApplicationTaskHook()
ENABLE_BACKWARD_COMPATIBILITYBnabled是否向后兼容旧的版本
USE_PORT_OPTIMISED_TASK_SELECTIONDisabled任务调度时,选择下一个运行任务的方法。表示使用通用的方法,不依赖于具体的硬件。在使用Cortex-MO或CMSIS-RTOS V2时,只能是Disabled
USE_TICKLESS_IDLEDisabled是否使用无节拍(tickless)的低功耗模式。若Disabled设置为Enabled,可自动进入低功耗模式降低系统功耗
USE_TASK_NOTIFICATIONSEnabled是否使用任务通知功能。若设置为Enabled,则编译相关的函数,每个任务的栈多消耗8字节空间
RECORD_STACK_HIGH ADDRESSDisabled是否将栈的起始地址保存到每个任务的任务控制块中(假设找是向下生长的)

  (3)Memorymanagemcutseties,内存管理设置。内存管理的参数设置界面如下图所示,只有3个参数。
在这里插入图片描述

  • MemoryAllocation,内存分配方式,固定为Dynamic/Static,也就是同时支持动态分配和静态分配。这个参数对应于文件]FreeRTOSConfig.h中的两个宏。这个参数的值不能在CubeMX里修改,但可以在文件FreeRTOSConfig.h里修改,便FreeRTOS同时支持动态分配和静态分配,或只支持一种内存分配方式。
	#define configSUPPORT_STATIC_ALLOCATION          1
	#define configSUPPORT_DYNAMIC_ALLOCATION         1
  • TOTAL_HEAP_SIZE,FreeRTOS总的堆空间大小,设置范围为512B~128KB。FreeRTOS中创建的所有对象,如任务、队列、软件定时器、信号量、互序量等,都需要从FreeRTOS的堆空间分配内存。在CubeMX中,FreeRTOS Heap Usage页面显示了当前配置下,FreeRTOS的堆空间使用情况,如下图所示。界面中显示了剩余的可用内存,以及各个任务、各种对象使用的内存量。
    在这里插入图片描述
  • MemoryManagementscheme,内存管理方案。有5种可选的内存管理方案,从heap_1到heap_5,使用哪种方案,就在文件FreeRTOSConfig.h中生成对应那种方案的宏定义。例如,使用方案heap_4,生成的宏定义如下:
#define USE_FreeRTOS_HEAP_4 

  内存管理是与硬件密切相关的,每一种内存管理方案对应一个源程序文件,如heap_4.c,这些文件在目录\Source\portable\MemMang下。
  FreeRTOS的5种内存管理方案各有特点和适用场合,其详细介绍可参考文献Mastering the FreeRTOS Real Time Kernel的第2章。heap_4是献认的内存管理方案,它使用第一匹配(first fit)算法分配内存,能将紧邻的空白内存块整合成一个大的空白内存块,降低产生内存碎片的风险,且速度比标准库中的函数mallocO和fteeQ要快。
  (4) Hook function related definitions,钩子函数相关定义。钩子函数类似于回调函数,就是在某个功能或函数执行时要调用的一个函数。钩子函数的代码由用户编写,用于实现一些自定义的处理。
  钩子函数的设置界面如下图所示。默认情况下,这些参数值都是Disabled,也就是不实现相应的钩子函数。如果设置为Enabled,CubeMX会在文件freertos.c中自动生成相应钩子函数的函数框架。
在这里插入图片描述
  下图中各个参数的意义以及设置为Enabled时对应的钩子函数名称见下表,表中只列出了函数名称,省略了函数参数。

钩子函数配置参数调用场合对应的钩子函数名称
USE_IDLE_HOOK空闲任务里调用vApplicationldleHook()
USE_TICK_HOOK滴嗒定时器虫断服务函数里调用vApplicationTickHook()
USE_MALLOC_FAILED_HOOK使用pvPortMalloc0分配内存失败时调用vApplicationMallocFailedHook()
USE_DAEMON_TASK_STARTUP_HOOK守护Daemon任务启动时调用vApplicationDaemonTaskStartupHook()
CHECK_FOR_STACK_OVERFLOW栈溢出时调用vApplicationStackOverflowHook()

  CHBCKFORSTACK_OVERFLOW的选项比较特殊,它提供Option1和Option2两个选项,对应于FreeRTOS内部两种不同的栈溢出处理方法,但是对应的钩子函数名称是相同的。
  (5)Runtime and task stats gathering related definitions,运行时间和任务状态收集相关定义。FreeRTOS可以收集任务运行时间和任务状态信息,相关参数的设置界面如下图所示。
在这里插入图片描述

  • GENERATE_RUNTIME_STATS,若设置为Enabled,则会启动任务运行时间统计功能,并可以通过函数vTaskGetRunTimeStats()读取这些信息。
  • USE_TRACE_FACILITY,若设置为Enabled,则会增加一些结构体成员和函数,用于可视化和跟踪调试。
  • USE_STATS_FORMATTING_FUNCTIONS,若USE_TRACE_FACILITY和这个参数都设置为Enabled,则会编译函数vTaskList()和yTaskGetRunTimeStats()两个参数中只要有一个设置为Disabled,就不会编译这两个函数。
      (6)Co-routine related definitions,协程相关定义,使用协程可以节省内存,主要用于功能有限、内存很小的MCU,现在的MCU内存一般比较充足,就很少使用协程了,所以禁用此功能即可,如下图所示。
    在这里插入图片描述
      (7)Software timer definitions,软件定时器定义。FreeRTOS可以创建软件定时器,其功能类似于高级语言(如C++)中的软件定时器。软件定时器相关参数的设置界面如下图所示。在后面会介绍软件定时器的使用。
    在这里插入图片描述
  • USE_TIMERS,是否使用软件定时器,默认设置为Enabled,且不可修改。
  • TIMER_TASK_PRIORITY,定时器服务任务的优先级,默认值是2,属于比较低的优先级。设置范围是0到55,因为总的优先级个数是56。
  • TIMER_QUEUE_LENGTH,定时器指令队列的长度,设置范围是1到255。
  • TIMER_TASK_STACK_DEPTH,定时器服务任务的栈空间大小,默认值256个字,设置范围是128到32768个字。注意,栈空间的单位是字,而不是字节。

  (8) Interruptiheshng behaviour configuration,中断嵌套行为配置。如下图所示,这两个参数与硬件中断相关,在后面会有介绍。
在这里插入图片描述

  • LIBRARY_LOWEST_INTERRUPT_PRIORITY,最低中断优先级,设置范围是1到15,默认值是15。因为CubeMX使用FreeRTOS时,优先级分组方案中4位都用作抢占优先级,所以最低优先级是15。
  • LIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY,系统能管理的最高中断优先级,设置范围是1到15,默认值是5。在中断服务函数中,只能调用FreeRTOSAPI函数的中断安全版本,如果一个中断的优先级高于这个值,就不能在此中断的ISR里调用FreeRTOS的中断安全API函数。

  (9)Addedwith10.2.1support,V10.2.1版本中新增支持的参数。下图所示的是FreeRTOSV10.2.1版本中新增支持的两个参数。
在这里插入图片描述

  • MESSAGE_BUFFER_LENGTH_TYPE,消息缓冲区长度类型。消息缓冲区的相关内容在后面会介绍。
  • USE_POSIX_ERRNO,使用POSIX标准的错误编号。POSIX(Portable Operating System Interface)即可移植操作系统接口,是操作系统设计的一种接口标准。

  ConfigParameters页面中这几组参数,覆盖了文件FreeRTOSConfig.h和FreeRTOS.h中一些主要的可配置的宏定义,还有一些其他的参数就保持默认值。

3.2 "INCLUDE_"类的宏

  前缀为“INCLUDE”的宏,用作一些函数的条件编译的条件,控制是否编译这些函数的源代码,从而实现对FreeRTOS的功能裁剪。不编译应用程序中用不到的FreeRTOS API函数,可以使最终编译出的程序尽量小。
  在文件FeeRTOSConfig.h和FreeRTOS.h虫,都有有“INCLUDE_”类的宏定义。与"config_"
类的宏定义一样,文件FreeRTOS.h中的是默认的宏定义例如,文件FreeRTOS.h中有如下的定义:

#ifndef INCLUDE_vTaskDelete
	#define INCLUDE_vTaskDelete    0
#endif

  这表示如果没有定义宏INCLUDE_vTaskDelete,就将这个宏定义为0。文件FreeRTOS.h中的定义是默认定义,请勿直接修改文件FreeRTOS.h里的内容。
  文件FeeRTOSConfig.h是用户可修改的配置文件,在CubeMX里设置的“INCLUDE_”参数会在这个文件里生成例如,文件FeeRTOSConfig.h中部分“INCLUDE_”类的宏定义如下,其中就有宏定义INCLUDE_vTaskDelete,其值定义为1:

#define INCLUDE_vTaskPrioritySet             1
#define INCLUDE_uxTaskPriorityGet            1
#define INCLUDE_vTaskDelete                  1
#define INCLUDE_vTaskCleanUpResources        0
#define INCLUDE_vTaskSuspend                 1
#define INCLUDE_vTaskDelayUntil              1
#define INCLUDE_vTaskDelay                   1
#define INCLUDE_xTaskGetSchedulerState       1
#define INCLUDE_xTimerPendFunctionCall       1
#define INCLUDE_xQueueGetMutexHolder         1
#define INCLUDE_uxTaskGetStackHighWaterMark  1
#define INCLUDE_eTaskGetState                1

  前缀为“INCLUDE_”的宏一般用于函数代码的条件编译,例如,函数vTaskDelete()的源代码就有如下的条件编译,这表示当参数INCLUDE_vTaskDelete值为1时,才编译函数vTaskDelete():

#if (INCLUIDE_vTaskDelete == 1)
	void vTaskDelete(TaskHandle_t xTaskToDelete)
	{
		/* 省略了函数具体代码*/
	}
#endif 

  有些函数代码的编译条件还是多个参数的组合,例如,函数eTaskGetState()的编译条件如下:

#if((INCLUDE_eTaskGetstate==1)||(configUSE_TRACE_FACILITY == 1)||(INCLUDE_xTaskAbortDelay == 1))
	eTaskstate eTaskGetstate(TaskHandle_t xTask)
	{
		/*省略了函数具体代码*/
	}
#endif 

  在CubeMX的JFreeRTOS配置部分,Includeparameters页面用于设置“INCLUDE_”类宏的值,如下图所示。
在这里插入图片描述
  在上图所示的界面上,每个参数对应于一个"INCLUDE_"宏,一般也对应于一个函数。例如,参数vTaskPrioritySet对应于宏IINCLUDE_vTaskPrioritySet,用作函数vTaskPrioritySet()的编译条件参数vTaskDelete对应于宏INCLUDEv_vTaskDelete,用作函数vTaskDelete()的编编译条件。

五、往期回顾

STM32Cube高效开发教程<高级篇><FreeRTOS>(一)-----FreeRTOS基础

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

致虚守静~归根复命

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值