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基础

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/372033.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MinIO:开源对象存储解决方案的领先者

MinIO:开源对象存储解决方案的领先者 MinIO 是一款开源的对象存储系统,致力于提供高性能、可伸缩、安全的数据存储解决方案。 官方解释:MinIO 是一个基于Apache License v2。0开源协议的对象存储服务。它兼容亚马逊S3云存储服务接口,非常适…

什么是T0策略?有没有可以持仓自动做T的策略软件?

​​行情低迷,持仓被套,不想被动等待?长期持股,想要增厚持仓收益?有没有可以自动做T的工具或者策略?日内T0交易,做到降低持仓成本,优化收益预期。 什么是T0策略? 可以提…

SpringBoot之内容协商

现象演示 假设有一个需求是根据终端的不同,返回不同形式的数据,比如 PC 端需要以 HTML 格式返回数据,APP、小程序端需要以 JSON 格式返回数据。这时我们是 coding 几个相似的接口?还是在一个接口里面做复杂判断处理?两…

7.8作业

一、思维导图 二、 1】按值修改 2】按值查找,返回当前节点的地址 (先不考虑重复,如果有重复,返回第一个) 3】反转 4】销毁链表 //按值修改 int value_change(linklistptr H,datatype e,int value) {if(HNULL||empty(H…

二次元转向SLG,B站游戏的破圈之困

文 | 螳螂观察 作者 | 夏至 2023年是B站游戏的滑铁卢,尽管这年B站的游戏营收还有40多亿,但相比去年大幅下降了20%,整整少了10亿,这是过去5年来的最大跌幅,也是陈睿接管B站游戏业务一年以来,在鼻子上碰的第…

【Java系列】深入解析 Lambda表达式

简化这个代码 这个就是Lambda表达式,可以简化匿名内部类的写法 package lambda;public class demo2 {public static void main(String[] args) {//第二个参数是一个接口,所以我们在调用方法的时候,需要传递这个接口的实现类对象--接口多态// 但是这个实现类,我只要用一次,所以我…

SRS流媒体服务器概述

SRS/5.0(Bee) is a simple, high efficiency and realtime video server, supports RTMP, WebRTC, HLS, HTTP-FLV, SRT, MPEG-DASH and GB28181. 翻译:SRS/5.0(Bee)是一款简洁、高效、实时的视频服务器,支持RTMP、WebRTC、HLS、HTTP-FLV、SRT、MPEG-DAS…

广州银行多份招股书数据货不对板:内控风险难平,IPO曲折前行

作者|芋圆 来源|贝多财经 6月29日,广州银行第五次更新了招股说明书。 作为制造业大省的头部城商行,广州银行的发展一直备受关注。拆解可知,广州银行2023年在盈利能力、内控、资本充足性、资产质量等方面的表现,凸显了该行接下来…

鸿蒙开发HarmonyOS NEXT (三) 熟悉ArkTs (上)

一、自定义组件 1、自定义组件 自定义组件,最基础的结构如下: Component struct Header {build() {} } 提取头部标题部分的代码,写成自定义组件。 1、新建ArkTs文件,把Header内容写好。 2、在需要用到的地方,导入…

SpringBoot 启动流程六

SpringBoot启动流程六 这句话是创建一个上下文对象 就是最终返回的那个上下文 我们这个creatApplicationContext方法 是调用的这个方法 传入一个类型 我们通过打断点的方式 就可以看到context里面的东西 加载容器对象 当我们把依赖改成starter-web时 这个容器对象会进行…

Java对象通用比对工具

目录 背景 思路 实现 背景 前段时间的任务中,遇到了需要识别两个对象不同属性的场景,如果使用传统的一个个属性比对equals方法,会存在大量的重复工作,而且为对象新增了属性后,比对方法也需要同步修改,不方…

百度、谷歌、必应收录个人博客网站

主要是给各个搜索引擎提交你的sitemap文件,让别人能搜到你博客的内容。 主题使用的Butterfly。 生成sitemap 安装自动生成sitemap插件。 npm install hexo-generator-sitemap --save npm install hexo-generator-baidu-sitemap --save在站点配置文件_config.yml…

自动化测试报告pytest-html样式美化

最近我将 pytest-html 样式优化了 一版 先看优化前: 优化后: 优化内容包括: 删除部分多余字段新增echart图表部分字体大小、行间距、颜色做了美化调整运行环境信息移至报告最后部分字段做了汉化处理(没全部翻译是因为&#xf…

力扣爆刷第161天之TOP100五连刷71-75(搜索二叉树、二维矩阵、路径总和)

力扣爆刷第161天之TOP100五连刷71-75(搜索二叉树、二维矩阵、路径总和) 文章目录 力扣爆刷第161天之TOP100五连刷71-75(搜索二叉树、二维矩阵、路径总和)一、98. 验证二叉搜索树二、394. 字符串解码三、34. 在排序数组中查找元素的…

分享20个python学习要点

1 类型 在python中&#xff0c;一切都是对象&#xff0c;每个对象都有一个类型。 检查对象类型的常用方式。 <type> type(<el>) 或 <el>.__class__&#xff1a; 这两行代码都是获取对象的类型。type(<el>)会返回<el>的类型&#xff0c;而&l…

如何将资源前端通过 Docker 部署到远程服务器

作为一个程序员&#xff0c;在开发过程中&#xff0c;经常会遇到项目部署的问题&#xff0c;在现在本就不稳定的大环境下&#xff0c;前端开发也需要掌握部署技能&#xff0c;来提高自己的生存力&#xff0c;今天就详细说一下如何把一个前端资源放到远程服务器上面通过docker部…

C++入门(C语言过渡)

文章目录 前言一、C关键字二、命名空间三、C输入&输出四、缺省参数五、函数重载六、引用七、inline八、nullptr总结 前言 C是一种通用的、高级的、静态类型的编程语言&#xff0c;它在20世纪80年代由丹尼斯里奇创建的C语言基础上发展而来。以下是C发展的一些重要里程碑。 1…

kafka 生产者

生产者 生产者负责创建消息&#xff0c;然后将其投递到Kafka中。 负载均衡 轮询策略。随机策略。按照 key 进行hash。 Kafka 的默认分区策略&#xff1a;如果指定了 key&#xff0c;key 相同的消息会发送到同一个分区&#xff08;分区有序&#xff09;&#xff1b;如果没有…

const 修饰不同内容区分

1.修饰局部变量 const int a 1;int const a 1; 这两种是一样的 注意&#xff1a; const int b; 该情况下编译器会报错&#xff1a;常量变量"b”需要初始值设定项 将一个变量没有赋初始值直接const修饰后&#xff0c;在以后时无法更改内容的。 2.修饰常量字符串 a.…

【密码学基础】基于LWE(Learning with Errors)的全同态加密方案

学习资源&#xff1a; 全同态加密I&#xff1a;理论与基础&#xff08;上海交通大学 郁昱老师&#xff09; 全同态加密II&#xff1a;全同态加密的理论与构造&#xff08;Xiang Xie老师&#xff09; 现在第二代&#xff08;如BGV和BFV&#xff09;和第三代全同态加密方案都是基…