FreeRTOS系统配置

一、前言

在实际使用FreeRTOS 的时候我们时常需要根据自己需求来配置FreeRTOS,而且不同架构
的MCU在使用的时候配置也不同。FreeRTOS的系统配置文件为FreeRTOSConfig.h,在此配置文件中可以完成FreeRTOS的裁剪和配置,这是非常重要的一个文件,本章就来讲解这个文件,本章分为如下几部分:


1、FreeRTOSConfig.h文件

2、“INCLUDE_”开始的宏

3、“config”开始的宏

二、 FreeRTOSConfig.h文件

刚开始我们在移植FreeRTOS的时候,就注意到移植完成后会出现一个报错

报错的原因就是“缺少FreeRTOSConfig.h文件”!可见该文件的重要性,所以我在这里和大家分享一下我对该文件认识。

通过查阅资料,我了解到FreeRTOSConfig.h文件是十分重要的。

FreeRTOS的配置基本是通过在FreeRTOSConfig.h 中使用“#define”这样的语句来定义宏定义实现的!!!!

在FreeRTOS的官方demo中,每个工程都有一个FreeRTOSConfig.h文件,我们在使用的时候可以参考这个文件,甚至直接复制粘贴使用。

 三、“INCLUDE_”开始的宏

“INCLUDE_”开头的宏有什么用呢?

答:使能和除能FreeRTOS中相应的 API 函数!即用来配置FreeRTOS中可选API函数的!


举个例子来说明一下吧:

比如当宏INCLUDE_vTaskPrioritySet 设置为0的时候表示不能使用函数VTaskPrioritySet(),当设置为1的时候就表示可以使用函数VTaskPrioritySet();

以上描述的功能就是条件编译。

从截图中可以看出,只有当满足条件 INCLUDE_vTaskPrioritySet == 1时,函数vTaskPrioritySet()才可以被编译。FreeRTOS中的裁剪和配置就是用这种条件编译的方法来实现的,不止FreeRTOS这么干,其实很多的协议栈、RTOS系统和GUI库等都是使用条件编译的方法来完成配置和裁剪的。条件编译的好处就是节省空间,不需要的功能就不用编译,这样就可以根据实际需求来减少系统占用的ROM和RAM大小,根据自己所使用的MCU来调整系统消耗,降低成本。


接下来一起看一些“INCLUDE_”开始的宏,分析一下他们的作用。

还有很多,这里就不再逐个列举了。


四、”config“开始的宏

“config”开始的宏和“INCLUDE_”开始的宏一样,都是用来完成FreeRTOS的配置和裁剪的,接下来我们就看一下这些“config”开始的宏。

 1、configAPPLICATION_ALLCATED_HEAP

默认情况下FreeRTOS的堆内存是由编译器来分配的,将宏configAPPLICATION_ALLOCATED_HEAP定义为1的话堆内存可以由用户自行设置,堆内存在 heap_1.c、heap_2.c、heap_3.c、heap_4.c和 heap_5.c中有定义,具体在哪个文件取决于用户的选择哪种内存管理方式。比如选择heap_4.c,那么在heap_4.c中就有如图所示定义:

从图中可以看出,只有当宏configAPPLICATION_ALLOCATED_HEAP == 时,需要用户自行堆内存ucHeap,否则的话就是编译器来分配。

2、configASSERT

断言类似C标准库中的 assert()函数,调试代码的时候可以检查传入的参数是否合理,FreeRTOS内核中的关键点都会调用configASSERT(x),当x为0的时候说明有错误发生,使用断言的话会导致开销加大,一般在调试阶段使用。configASSERT()需要在FreeRTOSConfig.h文件中定义。

注意,vAssertCalled()函数需要用户自行去定义,可以是显示到LCD上的函数,也可以是通过串口打印出来的函数,如下的定义:

当参数x错误的时候就通过串口打印出发生错误的文件名和错误所在的行号,调试代码的可以使用断言,当调试完成以后尽量去掉断言,防止增加开销!

3、configCHECK_FOR STACK_ OVERFLOW

设置堆栈溢出检测,每个任务都有一个任务堆栈,如果使用函数xTaskCreate()创建一个任
务的话那么这个任务的堆栈是自动从FreeRTOS 的堆(uCHeap)中分配的,堆栈的大小是由函数xTaskCreate()的参数usStackDepth来决定的。如果使用函数xTaskCreateStatic()创建任务的话任务堆栈是由用户设置的,参数pxStackBuffer为任务堆栈,一般是一个数组。


堆栈溢出是导致应用程序不稳定的主要因素,FreeRTOS 提供了两种可选的机制来帮助检测和调试堆栈溢出,不管使用哪种机制都要设置宏 configCHECK_FOR_STACK_OVERFLOW.如果使能了堆栈检测功能的话,即宏configCHECK_FOR_STACK_OVERFLOW不为0,那么用户必须提供一个钩子函数(回调函数),当内核检测到堆栈溢出以后就会调用这个钩子函数,此钩子函数原型如下:

参数xTask是任务句柄,pcTaskName是任务名字,要注意的是堆栈溢出太严重的话可能会损毁这两个参数,如果发生这种情况的话可以直接查看变量 pxCurrentTCB来确定哪个任务发生了堆栈溢出。有些处理器可能在堆栈溢出的时候生成一个fault中断来提示这种错误,另外,堆栈溢出检测会增加上下文切换的开销,建议在调试的时候使用。


configCHECK_FOR_STACK_OVERFLOW == 1,使用堆栈一处检测方法1。

上下文切换的时候需要保存现场,现场是保存在堆栈中的,这个时候任务堆栈使用率很可能达到最大值,方法一就是不断的检测任务堆栈指针是否指向有效空间,如果指向了无效空间的话就会调用钩子函数。方法一的优点就是快。但是缺点就是不能检测所有的堆栈溢出。

configCHECK_FOR_STACK_OVERFLOW == 2,使用堆栈溢出检测方法2.

使用方法二的话,在创建任务的时候会向任务堆栈填充一个已知的标志值,方法二还会一直检测堆栈后面的几个bytes(标记值)是否被改写,如果被改写的话就会调用堆栈溢出钩子函数,所以方法二也会使用方法一中的机制!

方法二比方法一相对要慢一些,但是对于用户而言还是比较快的。方法二可以检测到几乎所有的堆栈溢出,但是也会存在某些情况检测不到的堆栈溢出。比如溢出值和标记值同时的时候。

4、configCPU_CLOCK_HZ

设置CPU的频率

5、configSUPPORT_ DYNAMIC_ALLOCATION

定义为1的话在创建FreeRTOS的内核对象的时候所需要的RAM就会从FreeRTOS的堆中动态的获取内存,如果定义为0的话所需的 RAM就需要用户自行提供,默认情况下宏configSUPPORT_ DYNAMIC_ALLOCATION为1。

6、configENABLE_BACKEARD_COMPATIBILITY

FreeRTOS.h中由一些列的#define宏定义

在V8.0.0之前的FreeRTOS中会使用到这些数据类型,这些宏保证了你的代码从V8.0.0之前的版本升级到最新版本的时候不需要做出修改,默认情况下宏configENABLE_BACKWARD_COMPATIBILITY为1。

7、configGENERATE_RUN_TIME_STATS

设置为1开启时间统计功能,相应的API函数会被编译,为0时关闭时间统计功能。如果宏configGENERATE_RUN_TIME_STATS为1的话还需要定义下表中的宏。

8、configIDLE_SHOULD_YIELD

此宏定义了与空闲任务(idle Task)处于同等优先级的其他用户任务的行为,当为0的时候空闲任务不会为其他处于优先级的任务让出CPU使用权。当为1的时候,空闲任务就会为处于同等优先级的用户让出CPU使用权,除非没有就绪的用户任务,这样花费在空闲任务上的时间就会很少,但是这种方法也带了副作用,如图

图中有三个任务:A、B、C,还有一个空闲任务I,用户任务和空闲任务处于一优先级,任务切换发生在T0 ~T7时刻。T0 ~ T7之间的时间为一个时间片,在T2时刻空闲任务I开始执行,I任务运行了一段时间后被A任务抢走了CPU使用权,A任务运行到T3时刻发生任务切换,B任务开始进行。可以看出其任务I和任务A一起使用了一个时间片,所以任务A运行的时间比其他任务少!

一般建议关闭这个功能,毕竟空闲任务用不了多少时间,并且现在的MCU性能都很强。

9、configKERNEL_INTERRUPT_PRIORITY、
configMAX_SYSCALL_INTERRUPT_PRIORITY、configMAX_API_CALL_INTERRUPT_PRIORITY

这三个宏和RTOS的中断配置有关。

10、 configMAX_CO_ROUTINE_PRIORITIES

设置可以分配给协程的最大优先级,也就是协程的优先级数。设置号以后协程的优先级可以从0到configMAX_CO_ROUTINE_PRIORITIES-1,其中О是最低的优先级,configMAX_CO_ROUTINE_PRIORITIES-1为最高的优先级。

11、configMAX_PRIORITIES 

设置任务的优先级数量,设置好以后任务就可以使用从0到configMAX_PRIORITIES-1的优先级,其中0是最低优先级,configMAX_PRIORITIES-1是最高优先级。

注意和UCOS的区别,UCOS中0是最高优先级!

12、configMAX_TASK_NAME_LEN

设置任务名最大长度

13、 configMINIMAL_STACK_SIZE

设置空闲任务的最小任务堆栈大小,以字为单位,不是字节。比如在STM32上设置为100的话,那么真正的堆栈大小就是100*4 = 400 字节

14、configNUM_THREAD_LOCAL_STORAGE_POINTERS

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

15、configQUEUE_REGISTRY_SIZE

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

 16、configSUPPORT_STATIC_ALLOCATION

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

 17、config TICK_RATE_ HZ

设置FreeRTOS的系统时钟节拍频率,单位为HZ,此频率就是滴答定时器的中断频率,需要使用此宏来配置滴答定时器的中断,前面在讲delay.c文件的时候已经说过了。为了兼容ST最新的HAL库,我们将此宏设置为1000,周期就是1ms。

 18、configTIMER_QUEUE_LENGTH

此宏是配置FreeRTOS 软件定时器的,FreeRTOS的软件定时器API函数会通过命令队列向软件定时器任务发送消息,此宏用来设置这个软件定时器的命令队列长度。

19、 figTIMER_TASK_PRIORITY

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

20、config TIMER_TASK_STACK_DEPTH

设置定时器服务任务的任务堆栈大小

21、configTOTAL_HEAP_SIZE

设置系统节拍计数器变量数据类型,系统节拍计数器变量类型为TickType_t,当configUSE_16_BIT_TICKS为1的时候 TickType_t就是16位的,当configUSE_16_BIT_TICKS为0的话TickType_t就是32位的。

22、configUSE_16_BIT_TICKS

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

23、configUSE_APPLICATION_TASK_TAG

此宏设置为1的话,函数configUSE_APPLICATION_TASK_TAGF()和xTaskCallApplicationTaskHook()就会被编译。

24、 configUSE_CO_ROUTINES

此宏为Ⅰ的时候启用协程,协程可以节省开销,但是功能有限,现在的MCU性能已经非常强大了,建议关闭协程。 

25、configUSE_DAEMON_TASK_STARTUP_HOOK

当宏configUSE_TIMERS和 configUSE_DAEMON_TASK_STARTUP_HOOK都为1的时需要定义函数vApplicationDaemonTaskStartupHook(),函数原型如下:

26、configUSE_COUNTING_SEMAPHORES

设置为1的时候启用计数型信号量,相关的API函数会被编译。

27、configUSE_ IDLE_ HOOK

为1时使用空闲任务钩子函数,用户需要实现空闲任务钩子函数,函数的原型如下:

28、configUSE_MALLOC_FAILED_HOOK

 为1时使用内存分配失败钩子函数,用户需要实现内存分配失败钩子函数,函数原型如下

29、configUSE_MUTEXES

为1时使用互斥信号量,相关的API函数会被编译。

30、configUSE_PORT_OPTIMISED_TASK_SELECTION

FreeRTOS有两种方法来选择下一个要运行的任务,一个是通用的方法,另外一个是特殊的方法,也就是硬件方法,使用MCU自带的硬件指令来实现。

STM32有计算前导零的指令,所以我们可以使用特殊方法,即将宏configUSE_PORT_OPTIMISED_TASK_SELECTION定义为1。计算前导零的指令在UCOSII也用到了,也是用来查找下一个要运行的任务的。

 31、configUSE_PREEMPTION

为1时使用抢占式调度器,为0时使用协程。如果使用抢占式调度器的话内核会在每个时钟节拍中断中进行任务切换,当使用协程的话会在如下地方进行任务切换:
1、一个任务调用了函数taskYIELD()。
2、一个任务调用了可以使任务进入阻塞态的API函数

3、应用程序明确定义了在中断中执行上下文切换。

32、configUSE_QUEUE_SETS

为1时启用队列集功能。

33、configUSE_RECURSIVE_MUTEXES

为1时使用递归互斥信号量,相关的API函数会被编译

34、configUSE_STATS_FORMATTING_FUNCTIONS

宏configUSE_TRACE_FACILITY 和configUSE_ST,ATS_ FORMATTING_FUNCTIONS都为1 的时候函数vTaskList()和 vTaskGetRunTimeStats()会被编译。

35、configUSE_TASK_NOTIFICATIONS

为1的时候使用任务通知功能,相关的API函数会被编译,开启了此功能的话每个任务会多消耗8个字节。

36、configUSE_TICK_HOOK

为1时使能时间片钩子函数,用户需要实现时间片钩子函数,函数的原型如下:
 

37、 configUSE_TICKLESS_IDLE

为1时使能低功耗tickless模式。

38、 configUSE_TIMERS

为1时使用软件定时器,相关的API函数会被编译当宏configUSE_TIMERS为1的话,那么宏configTIMER_TASK_PRIORITYconfigTIMER_QUEUE_LENGTH和configTIMER_ TASK_STACK_DEPTH必须定义。

39、 configUSE_TIME_SLICING

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

40、 configUSE_TRACE_FACILITY

为1启用可视化跟踪调试,会增加一些结构体成员和API函数。

五、结语

以上就是我对FreeRTOS配置文件的介绍,还有一些其他的配置宏由于使用的比较少这里并没有列出来。希望我的分享对你学习FreeRTOS有所帮助!

学习交流,共赴前程icon-default.png?t=N7T8https://qm.qq.com/q/5UahSWIili 

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

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

相关文章

git修改历史(非最新)提交信息

二、修改最近第二次或更早之前的commit信息 当前有三次提交,从近到远分别为1、2、3 以修改第2次提交为例(从最新往前数) 1、使用命令git rebase -i HEAD~2 按i进入编辑模式,将对应的pick改为edit,然后ctrlc退出。最…

C++学习笔记(二十八):c++ 静态库及动态库的使用

静态库的使用 库的使用会很大程度减少我们的工作,本节对c中静态库和动态库的使用进行简单的介绍。静态链接库意味着这个库会被放到可执行文件中,在生成的exe中。动态链接库是在程序运行时链接的,可以在程序运行时调用加载库函数的方法来实现&…

【Linux运维】LVM和RAID学习及实践

LVM和RAID学习及实践 背景LVM简介新加硬盘的操作RAID-磁盘阵列应用场景RAID0RAID1其他结构RAID制作RAID 小结 背景 某台服务器的磁盘管理需要自己动手处理,找了一些资料也踩了一些坑,在这里记录一下,先介绍一下LVM和RAID这两个东西。在计算机…

通过反射修改MultipartFile类文件名

1、背景 项目上有这样一个需求&#xff0c;前端传文件过来&#xff0c;后端接收后按照特定格式对文件进行重命名。(修改文件名需求其实也可以在前端处理的) //接口类似于下面这个样子 PosMapping("/uploadFile") public R uploadFile(List<MultipartFile> fil…

Golang中for和for range语句的使用技巧、对比及常见的避坑

Update1 2024.1.0更新&#xff1a; Go 团队将修改 for 循环变量的语义&#xff0c;Go1.21 新版本即可体验&#xff01; 今天看见了这篇文章&#xff0c;Go的1.22版本将更新&#xff0c;大致理解未会默认进行v&#xff1a;v这个操作&#xff0c;因此此文所概述的许多坑&#xf…

鸿蒙(HarmonyOS)应用开发指南

1. 概述 1.1 简介 鸿蒙&#xff08;即 HarmonyOS &#xff0c;开发代号 Ark&#xff0c;正式名称为华为终端鸿蒙智能设备操作系统软件&#xff09;是华为公司自 2012 年以来开发的一款可支持鸿蒙原生应用和兼容 AOSP 应用的分布式操作系统。该系统利用“分布式”技术将手机、电…

imx6ull基于yocto工程的l汇编点亮ed

通过汇编点亮led 在裸机状态下通过汇编点亮led&#xff0c;即没有操作系统&#xff0c;(uboot kernel rootfs 都不需要实现&#xff09;。 led点亮原理 1.GPIO复用 根据原理图&#xff0c;找到led对应的引脚&#xff08;pin)&#xff0c;复用为GPIO&#xff08;只有GPIO才能…

Unity之角色控制器

PS:公司终于给我派任务了&#xff0c;最近几天都没学Unity&#x1f927;。 一、角色控制器的实现方式 目前小编知道的角色控制器实现方式有三种&#xff1a; 应用商店的角色控制系统Unity自己的角色控制器通过物理系统去做角色控制器 本篇介绍的是第二种Unity自己的角色控制…

springboot集成jsp

首先pom中引入依赖包 <!--引入servlet--> <dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId> </dependency> <!--引入jstl标签库--> <dependency><groupId>javax.servle…

脱机I/O方式和假脱机系统

提示&#xff1a;在写这个博客的时候小编更加的觉得计算机基础知识的重要性了&#xff0c;而且对计算机的整个发展历程和计算机的底层工作原理特别感兴趣 脱机I/O方式和假脱机系统 一、脱机I/O方式二、假脱机系统1、假脱机技术&#xff08;SPOOLing&#xff0c; simulataneaus …

[NSSCTF Round#16 Basic] CPR

打着玩玩&#xff0c;比赛很简单。 Crypto pr 一个RSA题&#xff0c;n1p*q,n2q*r给了两个c和p,r而且flag经过pad用单因子无法解出。分别用p,r解完再取crt from Crypto.Util.number import * import randomflagplaintext NSSCTF{****************} charset abcdefghijklmn…

Open CASCADE学习|基于visual studio 2022编译源码

目录 1、简介 2、下载 2.1下载visual studio 2022 community 2.2下载下载cmake工具 2.3下载源码 2.4下载第三方插件 3、安装 3.1安装visual studio 2022 community 3.2安装cmake 4、编译源码 5、测试 1、简介 Open CASCADE&#xff08;简称…

【b站咸虾米】新课uniapp零基础入门到项目打包(微信小程序/H5/vue/安卓apk)全掌握

课程地址&#xff1a;【新课uniapp零基础入门到项目打包&#xff08;微信小程序/H5/vue/安卓apk&#xff09;全掌握】 https://www.bilibili.com/video/BV1mT411K7nW/?p12&share_sourcecopy_web&vd_sourceb1cb921b73fe3808550eaf2224d1c155 三、vue语法 继续回到官…

python爬虫,验证码识别,携带cookies请求

古诗词网案例!!! 识别验证码类型: # 此处用到的图片验证码识别网址为:http://ttshitu.com/ 图鉴 import base64 import json import requests # 一、图片文字类型(默认 3 数英混合): # 1 : 纯数字 # 1001:纯数字2 # 2 : 纯英文 # 1002:纯英文2 # 3 : 数英混合 # 1003:…

GC6109——双通道5V低电压步进电机驱动芯片,低噪声、低振动,应用摄像机,机器人等产品中

GC6109是双通道5V低电压步进电机驱动器&#xff0c;具有低噪声、低振动的特点&#xff0c;特别适用于相机的变焦和对焦系统&#xff0c;万向节和其他精密、低噪声的STM控制系统。该芯片为每个通道集成了256微步驱动器。带SPl接口&#xff0c;用户可以方便地调整驱动器的参数。内…

【信号与系统】【北京航空航天大学】实验一、信号的MATLAB表示及信号运算

一、实验目的 1、初步掌握 MATLAB 仿真软件的使用&#xff1b; 2、学习使用 MATLAB 产生基本时域信号&#xff0c;并绘制信号波形&#xff1b; 3、学习利用 MATLAB 实现信号的基本运算&#xff1b; 4、利用 MATLAB 分析常用的连续时域信号。 二、实验内容 1、 生成连续信号 …

1、理解Transformer:革新自然语言处理的模型

目录 一、论文题目 二、背景与动机 三、卖点与创新 四、解决的问题 五、具体实现细节 0. Transformer 架构的主要组件 1. 注意力、自注意力&#xff08;Self-Attention&#xff09;到多头注意力&#xff08;Multi-Head Attention&#xff09; 注意力到底是做什么的&…

【问题探讨】基于非支配排序的蜣螂优化算法NSDBO求解微电网多目标优化调度研究

目录 主要内容 模型研究 结果一览 下载链接 主要内容 该模型以环境保护成本和运行成本为双目标构建了微电网优化调度模型&#xff0c;模型目标函数和约束条件复现文献《基于改进粒子群算法的微电网多目标优化调度》&#xff0c;程序的特点是采用非支配排序的蜣螂…

面试算法105:最大的岛屿

题目 海洋岛屿地图可以用由0、1组成的二维数组表示&#xff0c;水平或竖直方向相连的一组1表示一个岛屿&#xff0c;请计算最大的岛屿的面积&#xff08;即岛屿中1的数目&#xff09;。例如&#xff0c;在下图中有4个岛屿&#xff0c;其中最大的岛屿的面积为5。 分析 将岛屿…

如何将.NET 8.0的ASP.NET Core Web API部署成Windows服务

写在前面 前面写了一篇关于将.NET应用转换成Windows服务的方法&#xff0c;其实真正的目的是为了探索如何将Asp.Net Core Web Api 部署成Windows 服务。基于上一篇的基础&#xff0c;只需把创建 WebApplication 的代码放到 BackgroundService 的ExecuteAsync方法中即可。 其中…