FreeRTOS学习笔记——FreeRTOS内核配置说明

分享到:

FreeRTOS 是高度可配置的,所有的可配置项都在FreeRTOSConfig.h 文件中。每一个FreeRTOS Demo中都必须包含了一个配置好的FreeRTOSConfig.h文件,用户根据实际应用来裁剪定制FreeRTOS内核。这个配置文件是针对用户程序的,而非内核。
      下面列出上次已移植成功的工程中的FreeRTOSConfig.h配置文件定义(如表一所示),随后会说明里面的每一个参数定义。

#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H

#define configUSE_PREEMPTION 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 (5)
#define configMINIMAL_STACK_SIZE ((unsigned short)90)
#define configTOTAL_HEAP_SIZE ((size_t)(10 * 1024))
#define configMAX_TASK_NAME_LEN (10)
#define configUSE_TRACE_FACILITY 1
#define configUSE_16_BIT_TICKS 0
#define configIDLE_SHOULD_YIELD 1
#define configUSE_MUTEXES 1
#define configQUEUE_REGISTRY_SIZE 8
#define configCHECK_FOR_STACK_OVERFLOW 0
#define configUSE_RECURSIVE_MUTEXES 1
#define configUSE_MALLOC_FAILED_HOOK 0
#define configUSE_APPLICATION_TASK_TAG 0
#define configUSE_COUNTING_SEMAPHORES 1
#define configGENERATE_RUN_TIME_STATS 0
#define configUSE_TIME_SLICING 0

/* Co-routine definitions. */
#define configUSE_CO_ROUTINES 0
#define configMAX_CO_ROUTINE_PRIORITIES (2)

/* Software timer definitions. */
#define configUSE_TIMERS 1
#define configTIMER_TASK_PRIORITY (2)
#define configTIMER_QUEUE_LENGTH 10
#define configTIMER_TASK_STACK_DEPTH (configMINIMAL_STACK_SIZE * 2)

/* Set the following definitions to 1 to include the API function, or zero
to exclude the API function. */
#define INCLUDE_vTaskPrioritySet 1
#define INCLUDE_uxTaskPriorityGet 1
#define INCLUDE_vTaskDelete 1
#define INCLUDE_vTaskCleanUpResources 1
#define INCLUDE_vTaskSuspend 1
#define INCLUDE_vTaskDelayUntil 1
#define INCLUDE_vTaskDelay 1

/* Cortex-M specific definitions. */
#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

/* The lowest interrupt priority that can be used in a call to a "set priority"
function. */
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 0xf

/* The highest interrupt priority that can be used by any interrupt service
routine that makes calls to interrupt safe FreeRTOS API functions.  DO NOT CALL
INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER
PRIORITY THAN THIS! (higher priorities are lower numeric values. */
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5

/* Interrupt priorities used by the kernel port layer itself.  These are generic
to all Cortex-M ports, and do not rely on any particular library functions. */
#define configKERNEL_INTERRUPT_PRIORITY (configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS))
/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
#define configMAX_SYSCALL_INTERRUPT_PRIORITY (configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS))

/* Normal assert() semantics without relying on the provision of an assert.h
header file. */
#define configASSERT(x)           \
    if ((x) == 0)                 \
    {                             \
        taskDISABLE_INTERRUPTS(); \
        for (;;)                  \
            ;                     \
    }

/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS
standard names. */
#define vPortSVCHandler SVC_Handler
#define xPortPendSVHandler PendSV_Handler
#define xPortSysTickHandler SysTick_Handler

#endif /* FREERTOS_CONFIG_H */

2. 参数详解:
configUSE_PREEMPTION
设为 1则采用抢占式调度器, 设为 0则采用协作式调度器(时间片)。

 configUSE_IDLE_HOOK
设为1则使能 idle hook,设为0则禁止idle hook。当RTOS调度器开始工作后,为了保证至少有一个任务在运行,空闲任务被自动创建,占用最低优先级(0优先级)。对于已经删除的RTOS任务,空闲任务可以释放分配给它们的堆栈内存。通过空闲任务回调函数(idle hook回调函数),可以直接在空闲任务中添加应用程序相关的功能。空闲任务回调函数汇智空闲任务执行时调用。

 configUSE_TICK_HOOK
设为1则使能 tick hook,设为0则禁止tick hook。

configCPU_CLOCK_HZ
设置为 MCU 内核的工作频率,以Hz为单位。配置FreeRTOS的时钟Tick时会用到。对不同的移植代码也可能不使用这个参数。

configTICK_RATE_HZ
FreeRTOS的时钟Tick的频率,也就是FreeRTOS用到的定时中断的产生频率。这个频率越高则定时的精度越高,但是由此带来的开销也越大。FreeRTOS 自带的Demo 程序中将TickRate 设为了1000Hz只是用来测试内核的性能的。实际的应用程序应该根据需要改为较小的数值。

当多个任务共用一个优先级时,内核调度器回来每次时钟中断到来后轮转切换任务(round robin),因此,更高的Tick Rate 会导致任务的时间片“time slice”变短。

 configMAX_PRIORITIES
程序中可以使用的最大优先级。FreeRTOS 会为每个优先级建立一个链表,因此没多一个优先级都会增加些RAM 的开销。所以,要根据程序中需要多少种不同的优先级来设置这个参数。

configMINIMAL_STACK_SIZE
任务堆栈的最小大小,FreeRTOS根据这个参数来给idle task 分配堆栈空间。这个值如果设置的比实际需要的空间小,会导致程序挂掉。因此,最好不要减小Demo 程序中给出的大小。


configTOTAL_HEAP_SIZE
RTOS内核总计可用的有效的RAM大小。仅在你使用官方下载包中附带的内存分配策略时,才有可能用到此值。每当创建任务、队列、互斥量、软件定时器或信号量时,RTOS内核会为此分配RAM,这里的RAM都属于configTOTAL_HEAP_SIZE指定的内存区。

configMAX_TASK_NAME_LEN
任务名称最大的长度,这个长度是以字节为单位的,并且包括最后的 NULL 结束字节。

 configUSE_TRACE_FACILITY
如果程序中需要用到TRACE功能,则需将这个宏设为1。否则设为0。开启TRACE功能后,会激活一些附加的结构体成员和函数,RAM占用量会增大许多,因此在设为1之前请三思。

configUSE_16_BIT_TICKS
将 configUSE_16_BIT_TICKS设为 1后portTickType 将被定义为无符号的16位整形类型,configUSE_16_BIT_TICKS 设为0 后portTickType 则被定义为无符号的32位整型。

 configIDLE_SHOULD_YIELD
这个参数控制那些优先级与idle 任务相同的任务的行为,并且只有当内核被配置为抢占式任务调度时才有实际作用。

内核对具有同样优先级的任务会采用时间片轮转调度算法。当任务的优先级高于idle任务时,各个任务分到的时间片是同样大小的。

但当任务的优先级与idle任务相同时情况就有些不同了。当configIDLE_SHOULD_YIELD 被配置为1时,当任何优先级与idle 任务相同的任务处于就绪态时,idle任务会立刻要求调度器进行任务切换。这会使idle任务占用最少的CPU时间,但同时会使得优先级与idle 任务相同的任务获得的时间片不是同样大小的。因为idle任务会占用某个任务的部分时间片。

configUSE_MUTEXES
设为 1 则程序中会包含mutex 相关的代码,设为 0 则忽略相关的代码。

configUSE_RECURSIVE_MUTEXES
设为 1 则程序中会包含recursive mutex 相关的代码,设为 0 则忽略相关的代码。

configUSE_COUNTING_SEMAPHORES
设为 1 则程序中会包含semaphore 相关的代码,设为 0 则忽略相关的代码。

configUSE_ALTERNATIVE_API
设为 1 则程序中会包含一些关于队列操作的额外API函数,设为 0 则忽略相关的代码。这些额外提供的API运行速度更快,但是临界区(关中断)的长度也更长。有利也有弊,是否要采用需要用户自己考虑了。

configCHECK_FOR_STACK_OVERFLOW
控制是否检测堆栈溢出。

configQUEUE_REGISTRY_SIZE
队列注册表有两个作用,但是这两个作用都依赖于调试器的支持:
1. 给队列一个名字,方便调试时辨认是哪个队列。
2. 包含调试器需要的特定信息用来定位队列和信号量。
如果你的调试器没有上述功能,那么这个注册表就毫无用处,还占用的宝贵的RAM空间。

configGENERATE_RUN_TIME_STATS
设置是否产生运行时的统计信息,这些信息只对调试有用,会保存在RAM 中,占用RAM空间。因此,最终程序建议配置成不产生运行时统计信息。

configUSE_CO_ROUTINES
设置为1则包含co-routines 功能,如果包含了co-routines功能,则编译时需包含croutine.c 文件

configMAX_CO_ROUTINE_PRIORITIES
co-routines 可以使用的优先级的数量。

 configUSE_TIMERS
设置为1则包含软件定时器功能。

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

configTIMER_QUEUE_LENGTH
设置软件定时器任务中用到的命令队列的长度。

configTIMER_TASK_STACK_DEPTH
设置软件定时器任务需要的任务堆栈大小。

以INCLUDE 开头参数
以 &#39;INCLUDE&#39; 开头的宏允许我们将部分不需要的API 函数排除在编译生成的代码之外。这可以使内核代码占用更少的ROM 和RAM。
比如,如果代码中需要用到 vTaskDelete 函数则这样写:
#defineINCLUDE_vTaskDelete 1
如果不需要,则这样写:
#defineINCLUDE_vTaskDelete 0

 configASSERT
宏configASSERT()的作用类似C语言标准库中的宏assert(),configASSERT() 可以帮助调试,但是定义了configASSERT()后会增加程序代码,也会使程序变慢。

中断挂接
在Cortex-M硬件下,FreeRTOS使用SysTick作为系统节拍时钟,使用SVC和PendSVC进行上下文切换。异常中断服务代码位于port.c文件中,FreeRTOS的作者已经为各种架构的CPU写好了这些代码,可以直接拿来用,同时还已将异常中断入口地址与启动文件中中断向量相挂接了。

/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS standard names. */
#define vPortSVCHandler SVC_Handler
#define xPortPendSVHandler PendSV_Handler
#define xPortSysTickHandler SysTick_Handler

 

 

更多恩智浦(NXP)及恩智浦技术教程请关注:
NXP中文官方:http://www.nxp.com/zh-Hans/
NXP中文技术论坛:http://www.nxpic.org/


 

继续阅读
freeRTOS任务创建

任务创建是RTOS学习中很重要的一步,因为你的应用就是基于大量的任务来实现的,那么在freeRTOS下如何来创建任务呢,首先打开任意一个移植好的例程或者我们移植的demo,找到task.h和tasks.c这两个文件里面定义声明了许多与任务相关的类型和函数。

freeRTOS在恩智浦KV46MCU上的移植

经过前面对freeRTOS源码目录结构和例程的分析,接下来我们就动手来移植freeRTOS最新版源码包到NXP的kinetis系列KV46MCU上,并实现一个简单的例子,按一个按键,点亮LED灯。

看官网一步步给你分析学习freeRTOS

今天我们来分析下以NXP的kinetis K60塔式系统为硬件平台的例程。

freeRTOS源码目录结构分析

所以今天我们就来看看最新版V9.0.0rc2的源码目录结构,分析源码目录结构是学习一切操作系统的基础,在后续的更新中将会以恩智浦的kinetis 塔式系统为硬件平台来移植freeRTOS。