freeRTOS移植完成之后,在准备使用之前,是要对freeRTOS做一些配置的,以此适配自己所用的硬件平台,以及根据自己的项目选择需要使用哪些功能或者关闭某些用不到的功能,这是很有必要的!
freeRTOS的大部分配置项都在文件 FreeRTOSConfig.h 和 FreeRTOS.h 中,这两个文件中有很多的宏定义,用于系统的配置和裁剪,是很重要的文件,学习freeRTOS是非常有必要去看看的!这两个文件如下图所示:
想要更加详细的了解相关的宏的作用和使用方法,可以参考freeRTOS官网给出的有关说明,链接如下:
https://www.freertos.org/a00110.html#configUSE_PREEMPTION
下面就这两个文件中的内容,总结了一些比较重要的配置,它们的介绍分别如下:
1、系统调度模式的选择
#define configUSE_PREEMPTION 1
这个宏就是用于配置系统的调度模式的,调度模式选择如下:
0 - 合作式调度,任务之间根据时间片轮流的进行执行;
1 - 抢占式调度,即优先级高的任务可以抢占低优先级任务的运行权,优先执行;
系统要求实时响应的话,该宏配置为 1 即可。
2、tickless 低功耗模式
#define configUSE_TICKLESS_IDLE 0
0 - 禁能 tickless 低功耗模式
1 - 使能 tickless 低功耗模式
3、系统主频的设置
#define configCPU_CLOCK_HZ ( 72000000 )
这个宏用于配置CPU的主频,单位是Hz。这个数值要根据所用的cpu的实际时钟大小进行设置。比如:
STM32F103的主频最高位72MHz,STM32F407的主频为168MHz,这个不要填错。
4、系统心跳的速率
#define configTICK_RATE_HZ (1000 )
心跳速率也称为系统滴答,即系统每秒钟滴答的次数。比如上面配置为1000,就是把1秒分成了1000份,每一份为 1 毫秒。
5、系统最大的优先级
#define configMAX_PRIORITIES ( 5 )
这个宏用于配置系统最大可用的优先级。比如上面设置为 5,所以系统可以用的优先级为 0 - 4,5是不能用的。如果优先级超过这个设定,系统会忽略不处理。
注意:FreeRTOS中优先级数值越大,优先级越高。而UCOS则相反。
6、最小堆栈的设置
#define configMINIMAL_STACK_SIZE ( 128 )
在系统中,这个宏用于配置一些任务的堆栈空间的大小,一般用于空闲、定时等一些系统任务中。
注意:这个配置的单位是字,而不是字节!在RAM中,一个字是4byte!!!
7、系统总堆栈大小
#define configTOTAL_HEAP_SIZE ( 30 * 1024 )
这个宏用于设定系统的可用堆栈的总量大小(单位为字)。
使用时需要根据MCU的RAM和项目开发的功能情况定义这个值。不能定义太小,太小内存容易溢出;也不能定义太大,如果芯片RAM容量不够大,会导致变量定义失败,或分配其他堆栈空间时申请不到空间。
8、任务名称最大长度
#define configMAX_TASK_NAME_LEN ( 25 )
这个宏用于定义任务名称允许的最大字符串长度。
注意:结束符“\0”也包括在内。
9、互斥信号量
#define configUSE_MUTEXES 1
互斥信号量是一种很重要的同步手段。一般用于资源共享的“加锁” 和任务优先级反转上。
它可以实现多任务间对共享资源的独占和保护。即在某个资源在某个时刻只允许一个任务使用,使用完之后才允许其他任务使用该共享资源。
比如:任务A是高优先级任务,B是低优先级任务;A、B任务都用同一个串口发送指令数据,(每次必须发送完整,不能被打断)。当任务B正在发送数据时,任务A要打断任务B,任务B就需要使用互斥信号占有该串口,等发送完数据之后,再释放该串口给任务A使用。
10、信号量计数功能
#define configUSE_COUNTING_SEMAPHORES 1
0 - 不使用信号量计数功能
1 - 使用信号量计数功能
11、使能任务间直接的消息传递
#define configUSE_TASK_NOTIFICATIONS 1
0 - 禁止任务间直接的消息传递
1 - 使能任务间直接的消息传递,包含信号量,事件标志组和消息邮箱。
12、版本兼容性选择
#define configENABLE_BACKWARD_COMPATIBILITY 1
0 - 新旧版本不兼容
1 - 新旧版本之间可兼容,即新版本兼容老版本
13、钩子函数配置
钩子函数这个功能涉及到的宏比较多,需要使用时建议参照官方的说明进行配置会比较好,根据自己的使用需求设置吧。
14、获取任务运行信息
#define configGENERATE_RUN_TIME_STATS 0
0 - 禁止获取任务运行状态参数
1 - 使能任务运行状态参数统计
15、软件定时器配置
15.1、开启软件定时器
#define configUSE_TIMERS 1
通过将这个宏设置为1来使能软件定时器功能。
15.2、配置软件定时器任务的优先级
#define configTIMER_TASK_PRIORITY ( 3 )
软件定时器的实现是基于系统心跳实现的,管理软件定时器本质也是由一个定时器任务进行的,所以也是需要设置定时器任务的优先级的。具体的优先级根据自己项目的实际情况设置吧!
15.3、软件定时器命令队列的长度
#define configTIMER_QUEUE_LENGTH 10
说白了,freeRTOS的软件定时器其实是通过消息队列实现的。具体的数值根据你使用到多个软件定时器而定吧!
15.4、软件定时器任务的栈空间
#define configTIMER_TASK_STACK_DEPTH 128
软件定时器任务的堆栈空间的大小,和创建任务一样,也要给软件定时器任务分配堆栈空间。
16、断言设置
#define configASSERT( ( x ) ) if( ( x ) == 0 ) vAssertCalled( __FILE__, __LINE__ )
freeRTOS中设置断言的方式有多种,我个人喜欢使用上面所示的这样方式。
关键字 LINE 表示源代码行号,关键字__FILE__表示源代码文件名,函数 vAssertCalled 里面调用串口打印之类的功能,将出现错误的源文件和代码行号打印出来,比较方便!
17、INCLUDE函数
函数 Include 配置主要是指用户可以根据需要使能或者禁止在工程中使用相应的函数,配置为 1,表示使能,即可以在工程中使用相应函数。配置为 0,表示禁止,即禁止在工程中使用相应函数。
18、系统中断优先级等级设置
#ifdef __NVIC_PRIO_BITS
/* __BVIC_PRIO_BITS will be specified when CMSIS is being used. */
#define configPRIO_BITS __NVIC_PRIO_BITS
#else
#define configPRIO_BITS 4 /* 15 priority levels */
#endif
根据所用的MCU的内核配置吧!
至此,简单说明了一些比较重要的系统配置,完毕!
对嵌入式技术感兴趣的朋友,欢迎关注微信公众号“嵌入式之入坑笔记”,一起学习交流啊!