zoukankan      html  css  js  c++  java
  • FreeRTOS

    一、内核配置

    1、configUSE_PREEMPTION

    设置为1,使用抢先式内核;设置为0,为合作轮转内核。

    2、configCPU_CLOCK_HZ

    内部处理器执行的频率。这个值需要正确配置外围定时器。

    3、configTICK_RATE_HZ(1-1000)

    RTOS时间片中断的频率。

    时间片中断用来测量时间。因此更高时间片频率意味着时间测量可以有更高分辨率,同时意味着内核占用更多的CPU(效率很低)。

    多个任务共有同一优先级。通过切换任务,在每一个RTOS时间片内,内核将在同一优先级的任务间分配处理器时间。高时间片频率意味着将减少给予每个任务的时间份额。

    4、configMAX_PRIORITIES(4-32)

    应用程序任务中可用优先级的数目. 

    任何数量的任务,都可以分配同一优先级也可以单独分配优先级。参考configMAX_CO_ROUTINE_PRIORITIES。 内核分配的每个可用的优先级都消耗RAM,因此这个值不应该设置为高于实际应用程序中需要的。

    5、configMINIMAL_STACK_SIZE(64words-768words)

    空闲任务使用的堆栈大小。通常这个值不用少于 FreeRTOSConfig.h file中演示程序提供的。

    max value = configTOTAL_HEAP_SIZE / 4(when allocation is dynamic)

    max value = MCU RAM Size / 4 (when allocation is static)

    6、configMAX_TASK_NAME_LEN(12-255)

    当创建一个任务,能够给予描述任务名称的最大容许长度。这个长度指定符号数目,包括NULL终止字节。

    7、configUSE_16_BIT_TICKS

    时间片(内核开始执行后,时间片中断的次数)来测量时间。时间片计数器定义为可用的portTickType.类型。

    定义configUSE_16_BIT_TICKS为1,将使portTickType定义为16位无符号类型。定义为0,将是32位无符号类型。 使用16位类型,将使在16位或8位单片机大幅度提高性能。但是,这样限制了最大指定可用时间周期(65535时间片)。然而,假定时间片频率为250Hz,一个任务在16位上,最大延时或中断时间位262秒,而32位为17179869秒。

    8、configIDLE_SHOULD_YIELD

    这个参数控制任务与空闲任务优先级相同时的行为。仅仅有以下影响:

    1. 使用优先级调度
    2. 用户程序创建的任务,运行在空闲任务一样的优先级

    任务在时间片轮转中,使用同一优先级。假定没有更高优先级的任务,这样每一个任务,在空闲优先级下,将被分配相同数量的处理时间。如果,他们的优先级高于空闲任务的优先级,那么这种情况更是如此。 当任务处于空闲优先级下的行为,会有稍许不同。当configIDLE_SHOULD_YIELD设置为1时,当其他在空闲优先级的任务准备运行时,空闲任务将立刻让出CPU。当程序的任务调度可用时,要确保空闲任务能够执行的最少时间以上。这个行为,产生了不好的影响(根据应用程序的需要),如下描述:

    上述图表表明,四个在空闲优先级的任务执行模型。任务A, B,和C,是应用程序任务。任务 I是空闲任务。上下文切换在T0, T1....T6规律的周期间发生。当空闲任务执行时,任务A准备执行,但是空闲任务已经占去了当前时间片的部分时间。结果是,任务I 和任务A共同分享一个时间片。任务B 和任务C比任务A获得更多的执行时间。

    这些可以通过如下避免:

    1. 如果合适,可以使用空闲钩子代替在空闲优先级的分开任务。创建程序任务的优先级高于空闲优先级。
    2. 设置configIDLE_SHOULD_YIELD为1

    设置configIDLE_SHOULD_YIELD为1,将阻止空闲任务让出执行时间直到它的时间片用完。这就确保了所有在空闲优先级的任务分配了相同数量的执行时间。这是以分配给空闲任务更高比例的执行时间为代价。

    9、configUSE_MUTEXES

    设置为1,将使用互斥功能;设置为0,将不使用。

    10、configUSE_RECURSIVE_MUTEXES

    设置为1,将使用递归互斥功能;设置为0,将不使用。

    11、configUSE_COUNTING_SEMAPHORES

    设置为1,将使用计数器型信号量功能;设置为0,将不使用。

    12、configQUEUE_REGISTRY_SIZE(0-255)

    队列记录有两个功能,都这涉及到内核相关的调试:

    1. 允许一个队列相关的名称,可以在GUI调试中容易定义。
    2. 包含了调试器所需的信息,来定位每个记录的队列和信号量。

    队列记录除了进行内核相关的调试外,没有什么目的。 configQUEUE_REGISTRY_SIZE定义了可以记录的队列和信号量的最大数目。这些仅能够在使用内核相关调试时需要记录的。查看API中vQueueAddToRegistry() 和 vQueueUnregisterQueue()参考文档,获得更多信息。

    13、configUSE_APPLICATION_TASK_TAG

    为任务分配标签值,设置为1来使用vTaskSetApplicationTaskTag函数,分配的标签只对应用程序有用,内核不使用

    14、configENABLE_BACKWARD_COMPATIBILITY

    头文件FreeRTOS.h包含一系列#define宏定义,用来映射版本V8.0.0和V8.0.0之前版本的数据类型名字。这些宏可以确保RTOS内核升级到V8.0.0或以上版本时,之前的应用代码不用做任何修改。在FreeRTOSConfig.h文件中设置宏configENABLE_BACKWARD_COMPATIBILITY为0会去掉这些宏定义,并且需要用户确认升级之前的应用没有用到这些名字

    15、configUSE_PORT_OPTIMISED_TASK_SELECTION

    某些运行FreeRTOS的硬件有两种方法选择下一个要执行的任务:通用方法和特定于硬件的方法(以下简称“特殊方法”)。

    通用方法:

    • configUSE_PORT_OPTIMISED_TASK_SELECTION设置为0或者硬件不支持这种特殊方法。
    • 可以用于所有FreeRTOS支持的硬件。
    • 完全用C实现,效率略低于特殊方法。
    • 不强制要求限制最大可用优先级数目

    特殊方法:

    • 并非所有硬件都支持。
    • 必须将configUSE_PORT_OPTIMISED_TASK_SELECTION设置为1。
    • 依赖一个或多个特定架构的汇编指令(一般是类似计算前导零[CLZ]指令)。
    • 比通用方法更高效。
    • 一般强制限定最大可用优先级数目为32。

    16、configUSE_TICKLESS_IDLE

    设置configUSE_TICKLESS_IDLE为1使能低功耗tickless模式,为0保持系统节拍(tick)中断一直运行。

    通常情况下,FreeRTOS回调空闲任务钩子函数(需要设计者自己实现),在空闲任务钩子函数中设置微处理器进入低功耗模式来达到省电的目的。因为系统要响应系统节拍中断事件,因此使用这种方法会周期性的退出、再进入低功耗状态。如果系统节拍中断频率过快,则大部分电能和CPU时间会消耗在进入和退出低功耗状态上。

    FreeRTOS的tickless空闲模式会在空闲周期时停止周期性系统节拍中断。停止周期性系统节拍中断可以使微控制器长时间处于低功耗模式。移植层需要配置外部唤醒中断,当唤醒事件到来时,将微控制器从低功耗模式唤醒。微控制器唤醒后,会重新使能系统节拍中断。由于微控制器在进入低功耗后,系统节拍计数器是停止的,但我们又需要知道这段时间能折算成多少次系统节拍中断周期,这就需要有一个不受低功耗影响的外部时钟源,即微处理器处于低功耗模式时它也在计时的,这样在重启系统节拍中断时就可以根据这个外部计时器计算出一个调整值并写入RTOS 系统节拍计数器变量中。

    17、configUSE_TASK_NOTIFICATIONS

    设置宏configUSE_TASK_NOTIFICATIONS为1(或不定义宏configUSE_TASK_NOTIFICATIONS)将会开启任务通知功能,有关的API函数也会被编译。设置宏configUSE_TASK_NOTIFICATIONS为0则关闭任务通知功能,相关API函数也不会被编译。默认这个功能是开启的。开启后,每个任务多增加8字节RAM。
    这是个很有用的特性,一大亮点。

    每个RTOS任务具有一个32位的通知值,RTOS任务通知相当于直接向任务发送一个事件,接收到通知的任务可以解除任务的阻塞状态(因等待任务通知而进入阻塞状态)。相对于以前必须分别创建队列、二进制信号量、计数信号量或事件组的情况,使用任务通知显然更灵活。更好的是,相比于使用信号量解除任务阻塞,使用任务通知可以快45%(使用GCC编译器,-o2优化级别)。

    二、内存管理设置

    1、configSUPPORT_DYNAMIC_ALLOCATION 

    定义为 1的话在创建 FreeRTOS的内核对象时候 所需要的 RAM就会从 FreeRTOS的堆中 的堆中 动态的获取内存,定义为0的话需要用户自行提供。默认为1。详细信息,参见Static Vs Dynamic Memory Allocation

    2、configSUPPORT_STATIC_ALLOCATION

    设置为1,那么可以使用应用程序编写器提供的RAM创建RTOS对象。设置为0,则只能使用从FreeRTOS堆分配的RAM创建RTOS对象。默认(未定义时)为0 

    如果设置为1,则应用程序编写器还必须提供两个回调函数:vApplicationGetIdleTaskMemory()以提供内存供RTOS空闲任务使用;(如果configUSE_TIMERS设置为1)vApplicationGetTimerTaskMemory() 以提供内存供RTOS守护进程/定时器服务任务使用。

    3、configTOTAL_HEAP_SIZE(512Bytes-64KBytes)

    系统可用内存。一般设成除了操作系统和你的程序所用RAM外的最大RAM。 比如20KRAM你用了2K,系统用了3K,剩下15就是最大HEAP 尺寸。你可以先设小然后看编译结果往大里加。

    每当创建任务、队列、互斥量、软件定时器或信号量时,RTOS内核会为此分配RAM,这里的RAM都属于configTOTAL_HEAP_SIZE指定的内存区。

    4、HEAP_NUMBER选择

    可从heap_1、 heap_2、 heap_3、 heap_4、 heap_5中选择一种heap分配方案

    三、与钩子相关的功能定义

    1、configUSE_IDLE_HOOK

    设置为1, 使用空闲钩子,用户应用程序必须定义一个空闲任务钩子函数void vApplicationIdleHook(void);设置为0,不使用空闲钩子。

    当RTOS调度器开始工作后,为了保证至少有一个任务在运行,空闲任务被自动创建,占用最低优先级(0优先级)。对于已经删除的RTOS任务,空闲任务可以释放分配给它们的堆栈内存。因此,在应用中应该注意,使用vTaskDelete()函数时要确保空闲任务获得一定的处理器时间。除此之外,空闲任务没有其它特殊功能,因此可以任意的剥夺空闲任务的处理器时间。应用程序也可能和空闲任务共享同个优先级。

    2、configUSE_TICK_HOOK

    设置为1使用时间片钩子(Tick Hook),用户应用程序必须定义一个tick钩子函数void vApplicationTickHook(void);0忽略时间片钩子。

    时间片中断可以周期性的调用一个被称为钩子函数(回调函数)的应用程序。时间片钩子函数可以很方便的实现一个定时器功能。

    3、configUSE_MALLOC_FAILED_HOOK

    每当一个任务、队列、信号量被创建时,内核使用一个名为pvPortMalloc()的函数来从堆中分配内存。官方的下载包中包含5个简单内存分配策略,分别保存在源文件heap_1.c、heap_2.c、heap_3.c、heap_4.c、heap_5.c中。仅当使用这五个简单策略之一时,宏configUSE_MALLOC_FAILED_HOOK才有意义。

    如果定义并正确配置malloc()失败钩子函数,则这个函数会在pvPortMalloc()函数返回NULL时被调用。只有FreeRTOS在响应内存分配请求时发现堆内存不足才会返回NULL。

    如果宏configUSE_MALLOC_FAILED_HOOK设置为1,那么必须定义一个malloc()失败钩子函数void vApplicationMallocFailedHook( void),如果宏configUSE_MALLOC_FAILED_HOOK设置为0,malloc()失败钩子函数不会被调用,即便已经定义了这个函数。

    4、configUSE_DAEMON_TASK_STARTUP_HOOK

    定义守护进程HOOK函数,如果设置为1且configUSE_TIMERS设置为1,用户应用程序必须定义一个守护钩子函数void vApplicationDaemonTaskStartupHook(void);

    5、configCHECK_FOR_STACK_OVERFLOW

    每个任务维护自己的栈空间,任务创建时会自动分配任务需要的栈内存,分配内存大小由创建任务函数(xTaskCreate())的一个参数指定。堆栈溢出是设备运行不稳定的最常见原因,因此FreeeRTOS提供了两个可选机制用来辅助检测和改正堆栈溢出。配置宏configCHECK_FOR_STACK_OVERFLOW为不同的常量来使用不同堆栈溢出检测机制。

    注意,这个选项仅适用于内存映射未分段的微处理器架构。并且,在RTOS检测到堆栈溢出发生之前,一些处理器可能先产生故障(fault)或异常(exception)来反映堆栈使用的恶化。如果宏configCHECK_FOR_STACK_OVERFLOW没有设置成0,用户必须提供一个栈溢出钩子函数,这个钩子函数的函数名和参数必须如下所示:

    void vApplicationStackOverflowHook(TaskHandle_t xTask, signed char *pcTaskName );

    参数xTask和pcTaskName为堆栈溢出任务的句柄和名字。请注意,如果溢出非常严重,这两个参数信息也可能是错误的!在这种情况下,可以直接检查pxCurrentTCb变量。

    方法1:设置configCHECK_FOR_STACK_OVERFLOW为1:

    任务切换出去后,该任务的上下文环境被保存到自己的堆栈空间,这时很可能堆栈的使用量达到了最大(最深)值。在这个时候,RTOS内核会检测堆栈指针是否还指向有效的堆栈空间。如果堆栈指针指向了有效堆栈空间之外的地方,堆栈溢出钩子函数会被调用。

    这个方法速度很快,但是不能检测到所有堆栈溢出情况(比如,堆栈溢出没有发生在上下文切换时)。

    方法2:设置configCHECK_FOR_STACK_OVERFLOW为2(包括方法1):

    当堆栈首次创建时,在它的堆栈区中填充一些已知值(标记)。当任务切换时,RTOS内核会检测堆栈最后的16个字节,确保标记数据没有被覆盖。如果这16个字节有任何一个被改变,则调用堆栈溢出钩子函数。

    这个方法比第一种方法要慢,但也相当快了。它能有效捕捉堆栈溢出事件(即使堆栈溢出没有发生在上下文切换时),但是理论上它也不能百分百的捕捉到所有堆栈溢出(比如堆栈溢出的值和标记值相同,当然,这种情况发生的概率极小)。

    四、系统运行与收集任务统计相关的定义

    1、configGENERATE_RUN_TIME_STATS

    设置宏configGENERATE_RUN_TIME_STATS为1使能运行时间统计功能。一旦设置为1,则下面两个宏必须被定义:

      Ⅰ、portCONFIGURE_TIMER_FOR_RUN_TIME_STATS():用户程序需要提供一个基准时钟函数,函数完成初始化基准时钟功能,这个函数要被define到宏portCONFIGURE_TIMER_FOR_RUN_TIME_STATS()上。这是因为运行时间统计需要一个比系统节拍中断频率还要高分辨率的基准定时器,否则,统计可能不精确。基准定时器中断频率要比统计节拍中断快10~100倍。基准定时器中断频率越快,统计越精准,但能统计的运行时间也越短(比如,基准定时器10ms中断一次,8位无符号整形变量可以计到2.55秒,但如果是1秒中断一次,8位无符号整形变量可以统计到255秒)。
      Ⅱ、portGET_RUN_TIME_COUNTER_VALUE():用户程序需要提供一个返回基准时钟当前“时间”的函数,这个函数要被define到宏portGET_RUN_TIME_COUNTER_VALUE()上。

    举一个例子,假如我们配置了一个定时器,每500us中断一次。在定时器中断服务例程中简单的使长整形变量ulHighFrequencyTimerTicks自增。那么上面提到两个宏定义如下(可以在FreeRTOSConfig.h中添加):

    extern volatile unsigned longulHighFrequencyTimerTicks;
    #define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() ( ulHighFrequencyTimerTicks = 0UL )
    #define portGET_RUN_TIME_COUNTER_VALUE() ulHighFrequencyTimerTicks

    2、configUSE_TRACE_FACILITY

    设置成1表示启动可视化跟踪调试,会激活一些附加的结构体成员和函数。

    3、configUSE_STATS_FORMATTING_FUNCTIONS

    设置为1且宏configUSE_TRACE_FACILITY也设置为1,则会编译vTaskList()和vTaskGetRunTimeStats()函数。如果将这两个宏任意一个设置为0,上述两个函数不会被编译。

    五、协程定义

    1、configUSE_CO_ROUTINES

    设置成1表示使用协程,0表示不使用协程。如果使用协程,必须在工程中包含croutine.c文件。

    注:协程(Co-routines)主要用于资源发非常受限的嵌入式系统(RAM非常少),通常不会用于32位微处理器。

    在当前嵌入式硬件环境下,不建议使用协程,FreeRTOS的开发者早已经停止开发协程。

    2、configMAX_CO_ROUTINE_PRIORITIES(1-255)

    应用程序协程(Co-routines)的有效优先级数目,任何数目的协程都可以共享一个优先级。使用协程可以单独的分配给任务优先级。见configMAX_PRIORITIES。

    六、软件定时器定义

    1、configUSE_TIMERS

    设置成1使用软件定时器,为0不使用软件定时器功能。

    如果使能,将会给定时器任务分配4*configTIMER_TASK_STACK_DEPTH字节

    七、中断嵌套行为配置

    1、configLIBRARY_LOWEST_INTERRUPT_PRIORITY

    此宏定义是用来配置FreeRTOS用到的SysTick中断和PendSV中断的优先级。在NVIC分组设置为4的情况下,此宏定义的范围就是0-15,即专门配置抢占优先级。这里配置为了0x0f,即SysTick和PendSV都是配置为了最低优先级,实际项目中也建议大家配置最低优先级即可。

    2、configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY

    此宏定义比较重要,定义了受FreeRTOS管理的最高优先级中断。简单的说就是允许用户在这个中断服务程序里面调用FreeRTOS的API的最高优先级。设置NVIC的优先级分组为4的情况下。配置configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY为0x01表示用户可以在抢占式优先级为1到15的中断里面调用FreeRTOS的API函数,抢占式优先级为0的中断里面是不允许调用的。

    3、configKERNEL_INTERRUPT_PRIORITY

    宏定义configLIBRARY_LOWEST_INTERRUPT_PRIORITY的数值经过4bit偏移后得到一个8bit的优先级数值,即宏定义configKERNEL_INTERRUPT_PRIORITY的数值。这个8bit的数值才可以实际赋值给相应中断的优先级寄存器。

    也许初学者有疑问了,为什么前面NVIC配置的时候不是8bit的方式进行配置?这是因为ST的库函数NVIC_Init()已经为我们做好了。这里的宏定义数值是供PendSV和SysTick中断进行优先级配置的。比如:我们这里配置宏定义configLIBRARY_LOWEST_INTERRUPT_PRIORITY是0x0f,经过4bit偏移后就是0xf0,即SysTick和PendSV的中断优先级就是240。

    #define configKERNEL_INTERRUPT_PRIORITY   ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )

    4、configMAX_SYSCALL_INTERRUPT_PRIORITY

    宏定义configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY的数值经过4bit偏移后得到一个8bit的优先级数值,即宏定义configMAX_SYSCALL_INTERRUPT_PRIORITY的数值。这个数值是赋值给寄存器basepri使用的,8bit的数值才可以实际赋值给相应中断的优先级寄存器。这里的宏定义数值赋给寄存器basepri后就可以实现全局的开关中断操作了。

    比如:我们这里配置宏定义configLIBRARY_LOWEST_INTERRUPT_PRIORITY是0x01,经过4bit偏移后就是0x10,即16。调用了FreeRTOS的关中断后,所有优先级数值大于等于16的中断都会被关闭。优先级数值小于16的中断不会被关闭,对寄存器basepri寄存器赋值0,那么被关闭的中断会被打开。

    八、INCLUDE参数配置

    1、INCLUDE_vTaskPrioritySet 

    原型:void vTaskPrioritySet( TaskHandle_t xTask, UBaseType_t uxNewPriority )

    描述:函数vTaskPrioritySet用于实现FreeRTOS任务优先级的修改

    (1)第1个参数是任务句柄,用于区分不同的任务

    (2)第2个参数是给任务配置的新优先级

    注意事项:

    (1)使用此函数需要在FreeRTOSConfig.h配置文件中配置如下宏定义为1,#define INCLUDE_vTaskPrioritySet 1

    (2)如果第二个参数里面填的是NULL,即数值0的话,那么配置的就是当前正在执行的任务

    (3)如果被修改的任务的优先级,修改后高于正在执行的任务,将执行任务切换,切换到修改好的高优先级任务

    (4)第二个参数数值不可大于等于FreeRTOSConfig.h文件中的宏定义:#define configMAX_PRIORITIES 配置的数值

    2、INCLUDE_uxTaskPriorityGet

    原型:UBaseType_t uxTaskPriorityGet( TaskHandle_t xTask )

    描述:函数uxTaskPriorityGet用于获取FreeRTOS任务优先级

    (1)第1个参数是任务句柄,用于区分不同的任务

    (2)返回任务优先级

    注意事项:

    (1)使用此函数需要在FreeRTOSConfig.h配置文件中配置如下宏定义为1,#define INCLUDE_uxTaskPriorityGet 1

    (2)如果第二个参数里面填的是NULL,即数值0的话,那么配置的就是当前正在执行的任务

    3、INCLUDE_vTaskDelete

    原型:void vTaskDelete( TaskHandle_t xTask )

    描述:从RTOS内核管理器中删除一个任务。任务删除后将会从就绪、阻塞、暂停和事件列表中移除。

    (1)第1个参数是任务句柄,用于区分不同的任务

    注意事项:

     (1)被删除的任务,其在任务创建时由内核分配的存储空间,会由空闲任务释放。如果有应用程序调用xTaskDelete(),必须保证空闲任务获取一定的微控制器处理时间。任务代码自己分配的内存是不会自动释放的,因此删除任务前,应该将这些内存释放。

    (2)使用此函数需要在FreeRTOSConfig.h配置文件中配置如下宏定义为1,#define INCLUDE_vTaskDelete 1

    (3)如果参数里面填的是NULL,即数值0的话,那么删除的就是当前正在执行的任务

    4、INCLUDE_vTaskCleanUpResources

    原型:void vTaskCleanUpResources( 未知 )

    描述:未知

    注意事项:

    (1)使用此函数需要在FreeRTOSConfig.h配置文件中配置如下宏定义为1,#define INCLUDE_vTaskCleanUpResources 1

    5、INCLUDE_vTaskSuspend

    原型:void vTaskSuspend( TaskHandle_t xTaskToSuspend )

    描述:挂起指定任务,被挂起的任务绝不会得到处理器时间,不管该任务具有什么优先级

    (1)第1个参数是任务句柄,用于区分不同的任务

    注意事项:

    (1)使用此函数需要在FreeRTOSConfig.h配置文件中配置如下宏定义为1,#define INCLUDE_vTaskSuspend 1

    (2)调用vTaskSuspend函数是不会累计的:即使多次调用vTaskSuspend ()函数将一个任务挂起,也只需调用一次vTaskResume ()函数就能使挂起的任务解除挂起状态。

    (3)如果参数里面填的是NULL,即数值0的话,那么删除的就是当前正在执行的任务

    6、INCLUDE_vTaskDelayUntil

    原型:void vTaskDelayUntil( TickType_t * const pxPreviousWakeTime, const TickType_t xTimeIncrement )

    描述:任务绝对延时,该函数用在周期性任务以保证任务执行频率的稳定

    (1)第1个参数:上一次唤醒的时间计数器

    (2)第2个参数:间隔周期计数器

    注意事项:

    (1)使用此函数需要在FreeRTOSConfig.h配置文件中配置如下宏定义为1,#define INCLUDE_vTaskDelayUntil 1

    (2)任务体的执行时间必须小于延时时间,否则延时将不起作用

    (3)就算是低优先级任务在需要运行的时候被打断也会在下一次延时中补偿回来,所以延时时间相对绝对

    (4)绝对延时是指每隔指定的时间,执行一次调用vTaskDelayUntil()函数的任务,换句话说:延时时间是保证任务以固定频率执行,例如设置TimeIncrement为20ms,则1s内任务将被执行50次

    (5)当执行vTaskDelayUntil()后,除了第一次是间隔TimeIncrement时间执行vTaskDelayUntil()之后的代码外,之后的情况都比这个时间少,因为延时的时间是包括任务体执行的时间在内的

    7、INCLUDE_vTaskDelay

    原型:void vTaskDelay( const TickType_t xTicksToDelay )

    描述:任务相对延时

    (1)第一个参数指延时的时间片,例如系统频率200HZ,则一个时间片就是5ms,设置参数为100,那么延时时间就是500ms

    注意事项:

    (1)使用此函数需要在FreeRTOSConfig.h配置文件中配置如下宏定义为1,#define INCLUDE_vTaskDelay 1

    (2)相对延时是指每次延时都是从任务执行函数vTaskDelay()开始,延时指定的时间结束

    8、INCLUDE_xTaskGetSchedulerState

    原型:BaseType_t xTaskGetSchedulerState( void )

    描述:获取调度器当前状态

    (1)返回值是以下常量之一(定义在task.h):taskSCHEDULER_NOT_STARTED(未启动)、taskSCHEDULER_RUNNING(正常运行)、taskSCHEDULER_SUSPENDED(挂起)

    注意事项:

    (1)使用此函数需要在FreeRTOSConfig.h配置文件中配置如下宏定义为1,#define INCLUDE_xTaskGetSchedulerState 1或者onfigUSE_TIMERS必须定义为1

    9、INCLUDE_xTaskResumeFromISR

    原型:BaseType_t xTaskResumeFromISR( TaskHandle_t xTaskToResume )

    描述:用于在中断里面恢复一个挂起的任务

    (1)第一个参数是要恢复运行的任务句柄

    (2)如果恢复任务后需要上下文切换返回pdTRUE,否则返回pdFALSE

    注意事项:

    (1)使用此函数需要在FreeRTOSConfig.h配置文件中配置如下宏定义为1,#define INCLUDE_xTaskResumeFromISR 1

    (2)通过调用一次或多次vTaskSuspend()函数而挂起的任务,只需调用一次xTaskResumeFromISR()函数即可恢复运行

    (3) xTaskResumeFromISR()不可用于任务和中断间的同步,如果中断恰巧在任务被挂起之前到达,这就会导致一次中断丢失(任务还没有挂起,调用xTaskResumeFromISR()函数是没有意义的,只能等下一次中断)。这种情况下,可以使用信号量作为同步机制。

    10、INCLUDE_xQueueGetMutexHolder

    原型:void* xQueueGetMutexHolder( QueueHandle_t xSemaphore )

    描述:获取信号量的队列拥有者

    (1)第一个参数指定一个信号量

    (2)返回拥有此信号量的队列

    注意事项:

    (1)使用此函数需要在FreeRTOSConfig.h配置文件中配置如下宏定义为1,#define INCLUDE_xQueueGetMutexHolder 1

    (2)此函数由xSemaphoreGetMutexHolder()调用,不应该直接使用

    (3)此配置常量被用于xSemaphoreGetMutexHolder的默认值

    11、INCLUDE_xSemaphoreGetMutexHolder

    原型:TaskHandle_t xSemaphoreGetMutexHolder( SemaphoreHandle_t xMutex )

    描述:查询拥有互斥锁的任务句柄

    (1)第一个参数指定一个互斥锁

    (2)返回非NULL,任务持有互斥信号量的任务句柄,NULL,xMutex不是一个互斥信号量或者信号量没有被任务持有

    注意事项:

    (1)使用此函数需要在FreeRTOSConfig.h配置文件中配置如下宏定义为1,#define INCLUDE_xSemaphoreGetMutexHolder 1且配置configUSE_MUTEXES为1

    (2)此函数在RTOS中的定义为#define xSemaphoreGetMutexHolder( xSemaphore )  xQueueGetMutexHolder( ( xSemaphore ) ),其配置值由xQueueGetMutexHolder决定

    12、INCLUDE_pcTaskGetTaskName

    原型:char *pcTaskGetTaskName( TaskHandle_t xTaskToQuery )

    描述:获取任务的名字

    (1)第一个参数指定任务句柄

    (2)返回任务的名字

    注意事项:

    (1)使用此函数需要在FreeRTOSConfig.h配置文件中配置如下宏定义为1,#define INCLUDE_pcTaskGetTaskName 1

    (2)如果参数为NULL,则获取的当前调用任务的名字

    13、INCLUDE_uxTaskGetStackHighWaterMark

    原型:UBaseType_t uxTaskGetStackHighWaterMark( TaskHandle_t xTask )

    描述:每个任务都独立维护自己的栈空间, 栈空间总量在任务创建时进行设定。uxTaskGetStackHighWaterMark()主要用来查询指定任务的运行历史中, 其栈空间还差多少就要溢出。这个值被称为栈空间的”高水线(High Water Mark)

    (1)第一个参数:被查询任务的句柄
    (2)任务栈空间的实际使用量会随着任务执行和中断处理过程上下浮动。uxTaskGetStackHighWaterMark()返回从任务启动执行开始的运行历史中,栈空间具有的最小剩余量。这个值即是栈空间使用达到最深时的剩下的未使用的栈空间。这个值越是接近 0,则这个任务就越是离栈溢出不远了

    注意事项:

    (1)使用此函数需要在FreeRTOSConfig.h配置文件中配置如下宏定义为1,#define INCLUDE_uxTaskGetStackHighWaterMark 1

    14、INCLUDE_xTaskGetCurrentTaskHandle

    原型:TaskHandle_t xTaskGetCurrentTaskHandle( void )

    描述:获取当前执行任务的句柄

    (1)返回任务句柄

    注意事项:

    (1)使用此函数需要在FreeRTOSConfig.h配置文件中配置如下宏定义为1,#define INCLUDE_xTaskGetCurrentTaskHandle 1

    15、INCLUDE_eTaskGetState

    原型:eTaskState eTaskGetState( TaskHandle_t xTask )

    描述:获取任务运行状态

    (1)第一个参数:任务句柄

    (2)返回任务状态的枚举值

    注意事项:

    (1)使用此函数需要在FreeRTOSConfig.h配置文件中配置如下宏定义为1,#define INCLUDE_eTaskGetState 1

    (2)任务的枚举状态有:eRunning(运行)、eReady(就绪)、eBlocked(阻塞)、eSuspended(挂起)、eDeleted(删除)(任务的结构等待被清理状态)

    16、INCLUDE_xEventGroupSetBitFromISR

    原型:BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken )

    描述:用于设置指定的事件标志位为1

    (1)第1个参数是事件标志组句柄

    (2)第2个参数表示24个可设置的事件标志位,EventBits_t是定义的32位变量,低24位用于事件标志设置。变量uxBitsToSet的低24位的某个位设置为1,那么被设置的事件标志组的相应位就设置为1。变量uxBitsToSet设置为0的位对事件标志相应位没有影响。比如设置变量uxBitsToSet = 0x0003就表示将事件标志的位0和位1设置为1,其余位没有变化

    (3)返回值,如果消息成功发送给daemon任务(就是FreeRTOS的定时器任务)返回pdPASS,否则返回pdFAIL,另外daemon任务中的消息队列满了也会返回pdFAIL

    注意事项:

    (1)使用前一定要保证事件标志已经通过函数xEventGroupCreate创建了

    (2)在FreeRTOSConfig.h文件中使能如下三个宏定义:

      #define  INCLUDE_xEventGroupSetBitFromISR   1

      #define  configUSE_TIMERS                        1

      #define  INCLUDE_xTimerPendFunctionCall     1

    (3) 函数xEventGroupSetBitsFromISR是用于中断服务程序中调用的,故不可以在任务代码中调用此函数,任务代码中使用的是xEventGroupSetBits

    (4)函数xEventGroupSetBitsFromISR对事件标志组的操作是不确定性操作,因为不知道当前有多少个任务在等待此事件标志。而FreeRTOS不允许在中断服务程序和临界段中执行不确定性操作。为了不在中断服务程序中执行,就通过此函数给FreeRTOS的daemon任务(就是FreeRTOS的定时器任务)发送消息,在daemon任务中执行事件标志的置位操作。同时也为了不在临界段中执行此不确定操作,将临界段改成由调度锁来完成。这样不确定性操作在中断服务程序和临界段中执行的问题就都得到解决了

    (5)由于函数xEventGroupSetBitsFromISR对事件标志的置位操作是在daemon任务里面执行的,如果想让置位操作立即生效,即让等此事件标志的任务能够得到及时执行,需要设置daemon任务的优先级高于使用此事件标志组的所有其它任务

    17、INCLUDE_xTimerPendFunctionCall

    原型:BaseType_t xTimerPendFunctionCall( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, TickType_t xTicksToWait )

    描述:定时器守护任务回调函数,用于延时定时器守护任务的执行

    (1)第一个参数:定时器守护任务执行的功能函数,类型为PendedFunction_t

    (2)第二个参数:传递给回调函数的值,可以是任意类型

    (3)第三个参数:传递给回调函数的第二个值,为uint32_t 类型

    (4)第四个参数:当调用此函数的时候将会发送一个消息到定时器守护任务队列,xTicksToWait 指定了任务在队列满的情况下处于阻塞状态的时间

    (5)返回:

      pdPASS:消息成功发送到RTOS守护任务

      other:由于消息队列满导致消息发送失败。消息队列长度在FreeRTOSConfig.h配置文件中设置configTIMER_QUEUE_LENGTH

    注意事项:

    (1)使用此函数需要在FreeRTOSConfig.h配置文件中配置如下宏定义为1,#define INCLUDE_xTimerPendFunctionCall 1且configUSE_TIMERS也要置为1

    (2)定时器守护任务使用到一个命令队列,只要向队列发送信号就可以执行相应代码,所以可以实现“中断推迟处理”功能;只用到定时器守护任务这一个任务,节省资源,但建议回调函数执行时间短一些,否则影响其他定时器回调函数的执行周期

    18、INCLUDE_xTaskAbortDelay

    原型:BaseType_t xTaskAbortDelay( TaskHandle_t xTask )

    描述:终止任务的阻塞状态并且使之进入就绪状态

    (1)将要被移除阻塞状态的任务句柄

    (2)返回:

      pdPASS:任务从阻塞状态进入就绪状态

      pdFAIL:在调用此函数时任务并没有处于阻塞状态

    注意事项:

    (1)使用此函数需要在FreeRTOSConfig.h配置文件中配置如下宏定义为1,#define INCLUDE_xTaskAbortDelay 1

    19、INCLUDE_xTaskGetHandle

    原型:TaskHandle_t xTaskGetHandle( const char *pcNameToQuery )

    描述:通过任务名获取任务句柄

    (1)第一个参数:任务的名字(标准非空的c字符串)

    (2)如果存在与pcNameToQuery 指定的一样的任务名字则返回任务句柄,否则返回NULL

    注意事项:

    (1)使用此函数需要在FreeRTOSConfig.h配置文件中配置如下宏定义为1,#define INCLUDE_xTaskGetHandle 1

    (2)如果存在多个任务名字相同此函数功能将会无效

    (3)此函数花的时间相对较长,因此推荐使用一次后保存查找到的任务句柄以备之后重复使用此句柄

     参考链接:https://blog.csdn.net/zhzht19861011/article/details/50134883、http://blog.sina.com.cn/s/blog_98ee3a930102wfst.html、http://blog.sina.com.cn/s/articlelist_2565749395_12_1.html

  • 相关阅读:
    笔试题系列001
    算法系列001---dfs|多叉|解空间树理解
    leetcode--014 Gas station
    leetcode--012 single number I
    leetcode--011 copy list with random pointer
    leetcode--010 Linked List Cycle II
    leetcode--009 Linked List Cycle I
    leetcode--007 word break I
    leetcode-006 detect cycle
    alex鸡汤回信
  • 原文地址:https://www.cnblogs.com/yeshenmeng/p/9805080.html
Copyright © 2011-2022 走看看