文档库 最新最全的文档下载
当前位置:文档库 › freertos资料整理

freertos资料整理

freertos资料整理
freertos资料整理

用了半天时间对FreeRTOS有了一个初步的认识,大概总结一下,其中混杂了系统实现和实际应用方面的问题。

现只是以应用为目的,实现方面待以后进一步研究。

1.FreeRTOS提供的功能包括:任务管理、时间管理、信号量、消息队列、内存管理。与平台有关的文件包含在portable文件夹中,主要是port.c, portmacro.h 两个文件。平台无关的文件主要是:list.c(基本链表结构), queue.c(包括消息队列,信号量的实现), croutine.c,tasks.c(任务管理,时间管理)。

命名协定

RTOS内核与范例程序源代码使用下面的协定:

变量

char类型的变量以c 为前缀

short类型的变量以s 为前缀

long类型的变量以l 为前缀

float类型的变量以f 为前缀

double类型的变量以d 为前缀

枚举变量以e 为前缀

其他类型(如结构体)以x 为前缀

指针有一个额外的前缀p , 例如short类型的指针前缀为ps

无符号类型的变量有一个额外的前缀u , 例如无符号short类型的变量前缀为us

函数

文件内部函数以prv为前缀

API函数以其返回值类型为前缀,按照前面对变量的定义

函数的名字以其所在的文件名开头。如vTaskDelete函数在Task.c文件中定义数据类型

数据类型并不直接在RTOS内核内部引用。相反,每个平台都有其自身的定义方式。例如,char类型定义为portCHAR,short类型定义为portSHORT等。范例程序源代码使用的就是这种符号,但这并不是必须的,你可以在你的程序中使用任何你喜欢的符号。

此外,有两种额外的类型要为每种平台定义。分别是:

portTickType

可配置为16位的无符号类型或32位的无符号类型。参考API文档中的定制部

分获取详细信息。

portBASE_TYPE

为特定体系定义的最有效率的数据类型。

如果portBASE_TYPE定义为char则必须要特别小心的保证用来作为函数返回值的signed char可以为负数,用于指示错误。

2. FreeRTOS内核支持优先级调度算法,每个任务可根据重要程度的不同被赋

予一定的优先级,CPU总是让处于就绪态的、优先级最高的任务先运行。FreeRT0S内核同时支持轮换调度算法,系统允许不同的任务使用相同的优先级,在没有更高优先级任务就绪的情况下,同一优先级的任务共享CPU的使用时间。

3.freertos既可以配置为可抢占内核也可以配置为不可抢占内核。当FreeRTOS 被设置为可剥夺型内核时,处于就绪态的高优先级任务能剥夺低优先级任务的CPU使用权,这样可保证系统满足实时性的要求;当FreeRTOS被设置为不可剥夺型内核时,处于就绪态的高优先级任务只有等当前运行任务主动释放CPU

的使用权后才能获得运行,这样可提高CPU的运行效率。

4.任务管理

系统为每个任务分配一个TCB结构

typedef struct tskTaskControlBlock

{

volatile portSTACK_TYPE *pxTopOfStack;//指向堆栈顶

xListItem xGenericListItem; //通过它将任务连入就绪链表或者延时链表或

者挂起链表中,xListItem包含其TCB指针

xListItem xEventListItem;//通过它把任务连入事件等待链表

unsigned portBASE_TYPE uxPriority;//优先级

portSTACK_TYPE *pxStack; //指向堆栈起始位置

signed portCHAR pcTaskName[ configMAX_TASK_NAME_LEN ]; 。。。。。。。。。。。。。。。。省略一些次要结构

} tskTCB;

系统的全局变量:

static xList pxReadyTasksLists[ configMAX_PRIORITIES ]; 就绪队列

static xList xDelayedTaskList1;

static xList xDelayedTaskList2; 两个延时任务队列

static xList * volatile pxDelayedTaskList;

static xList * volatile pxOverflowDelayedTaskList; 两个延时队列的指针,应该是可互换的。

static xList xPendingReadyList;

static volatile xList xTasksWaitingTermination; 等待结束队列

static volatile unsigned portBASE_TYPE uxTasksDeleted = ( unsigned portBASE_TYPE ) 0; 结束队列中的个数?????

static xList xSuspendedTaskList; 挂起队列

static volatile unsigned portBASE_TYPE uxCurrentNumberOfTasks;记录了当前系统任务的数目

static volatile portTickType xTickCount;是自启动以来系统运行的ticks数static unsigned portBASE_TYPE uxTopUsedPriority;记录当前系统中被使用的最高优先级,

static volatile unsigned portBASE_TYPE uxTopReadyPriority;记录当前系统中处于就绪状态的最高优先级。

static volatile signed portBASE_TYPE xSchedulerRunning ;表示当前调度器是否在运行,也即内核是否启动了

任务建立和删除,挂起和唤醒

5.时间管理

操作系统总是需要个时钟节拍的,这个需要硬件支持。freertos同样需要一个time tick产生器,通常是用处理器的硬件定时器来实现这个功能。(时间片轮转调度中和延时时间控制??)

它周期性的产生定时中断,所谓的时钟节拍管理的核心就是这个定时中断的服务程序。freertos的时钟节拍isr中除去保存现场,灰度现场这些事情外,核心的

工作就是调用vTaskIncrementTick()函数。vTaskIncrementTick()函数主要做两

件事情:维护系统时间(以tick为单位,多少个节拍);处理那些延时的任务,如果延时到期,则唤醒任务。

任务可用的延时函数:vTaskDelay();vTaskDelayUntil();

特别之处在于vTaskDelayUntil()是一个周期性任务可以利用它可以保证一个固

定的(确定的)常数执行频率,而vTaskDelay()无法保证。

6.任务间的通信(详见“FreeR TOS任务间通讯”)

1)当然可以用全局变量的形式通信,但是不安全。

2)队列(xQueueHandle)是FreeRTOS中通信所需的主要数据结构。

3)信号量(xSemaphoreHandle),有二进制信号量,计数信号量和互斥信号量,其都是以队列为基础结构建立。

二进制信号量可以用于中断和任务间的同步。也就是说希望任务随外部中断而执行。即外设给出“数据已就绪”信号,系统中断,任务收到此中断信号接收数据。互斥一般用于都共享资源或数据结构的保护。因为任务调度不能保证数据不被破坏。当一个任务需要访问资源,它必须先获得('take') 令牌;当访问结束后,它必须释放令牌- 允许其他任务能够访问这个资源。(对此还有待进一步实验研究)。

7.系统配置

freeRTOS 配置在:FREERTOS_CONFIG.H 里面,条目如下:

/* 是否配置成抢先先多任务内核,是1的时候,优先级高的任务优先执行。为0任务就没有优先级之说,用时间片轮流执行*/

#define configUSE_PREEMPTION 1

/* IDLE任务的HOOK函数,用于OS功能扩展,需要你自己编相应函数,名字是void vApplicationIdleHook( void ) */

#define configUSE_IDLE_HOOK 0

/* SYSTEM TICK的HOOK函数,用于OS功能扩展,需要你自己编相应函数,名字是void vApplicationTickHook(void ) */

#define configUSE_TICK_HOOK 0

/* 系统CPU频率,单位是Hz */

#define configCPU_CLOCK_HZ 58982400

/* 系统SYSTEM TICK每秒钟的发生次数,数值越大系统反应越快,但是CPU 用在任务切换的开销就越多*/

#define configTICK_RATE_HZ 250

/* 系统任务优先级数。5 说明任务有5级优先度。这个数目越大耗费RAM越多*/

#define configMAX_PRIORITIES 5

/* 系统最小堆栈尺寸,注意128不是128字节,而是128个入栈。比如ARM32位,128个入栈就是512字节*/

#define configMINIMAL_STACK_SIZE 128

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

#define configTOTAL_HEAP_SIZE 10240

/* 任务的PC名字最大长度,因为函数名编译完了就不见了,所以追踪时不知道哪个名字。16表示16个char */

#define configMAX_TASK_NAME_LEN 16

/* 是否设定成追踪,由PC端TraceCon.exe记录,也可以转到系统显示屏上*/

#define configUSE_TRACE_FACILITY 0

/* 就是SYSTEM TICK的长度,16是16位,如果是16位以下CPU,一般选1;如果是32位系统,一般选0 */

#define configUSE_16_BIT_TICKS 0

/* 简单理解以下就是和IDLE TASK同样优先级的任务执行情况。建议设成1,对系统影响不大*/

#define configIDLE_SHOULD_YIELD 1

/* 是否用MUTEXES。MUTEXES是任务间通讯的一种方式,特别是用于任务共享资源的应用,比如打印机,任务A用的时候就排斥别的任务应用,用完了别的任务才可以应用*/

#define configUSE_MUTEXES 0

/* 确定是否用递归式的MUTEXES */

#define configUSE_RECURSIVE_MUTEXES 0

/* 是否用计数式的SEMAPHORES,SEMAPHORES也是任务间通讯的一种方式*/

#define configUSE_COUNTING_SEMAPHORES 0

/* 是否应用可切换式的API。freeRTOS 同一功能API有多个,有全功能但是需求资源和时间较多的,此项使能后就可以用较简单的API,节省资源和时间,但是应用限制较多*/

#define configUSE_ALTERNATIVE_API 0

/* 此项用于DEBUG,来看是否有栈溢出,需要你自己编相应检查函数void vApplicationStackOverflowHook(xTaskHandle *pxTask, signed portCHAR

*pcTaskName ) */

#define configCHECK_FOR_STACK_OVERFLOW 0

/* 用于DEBUG,登记SEMAPHORESQ和QUEUE的最大个数,需要在任务用应用函数vQueueAddToRegistry()和vQueueUnregisterQueue() */

#define configQUEUE_REGISTRY_SIZE 10

/* 设定可以改变任务优先度*/

#define INCLUDE_vTaskPrioritySet 1

/* 设定可以查询任务优先度*/

#define INCLUDE_uxTaskPriorityGet 1

/* 设定可以删除任务*/

#define INCLUDE_vTaskDelete 1

/* 据说是可以回收删除任务后的资源(RAM等)*/

#define INCLUDE_vTaskCleanUpResources 0

/* 设置可以把任务挂起*/

#define INCLUDE_vTaskSuspend 1

/* 设置可以从中断恢复(比如系统睡眠,由中断唤醒*/

#define INCLUDE_vResumeFromISR 1

/* 设置任务延迟的绝对时间,比如现在4:30,延迟到5:00。时间都是绝对时间*/

#define INCLUDE_vTaskDelayUntil 1

/* 设置任务延时,比如延迟30分钟,相对的时间,现在什么时间,不需要知道*/

#define INCLUDE_vTaskDelay 1

/* 设置取得当前任务分配器的状态*/

#define INCLUDE_xTaskGetSchedulerState 1

/* 设置当前任务是由哪个任务开启的*/

#define INCLUDE_xTaskGetCurrentTaskHandle 1

/* 是否使能这一函数,还数的目的是返回任务执行后任务堆栈的最小未用数量,同样是为防止堆栈溢出*/

#define INCLUDE_uxTaskGetStackHighWaterMark 0

/* 是用用协程。协程公用堆栈,节省RAM,但是没有任务优先级高,也无法和任务通讯*/

#define configUSE_CO_ROUTINES 0

/* 所有协程的最大优先级数,协程优先级永远低于任务。就是系统先执行任务,所有任务执行完了才执行协程。*/

#define configMAX_CO_ROUTINE_PRIORITIES 1

/* 系统内核的中断优先级,中断优先级越低,越不会影响其他中断。一般设成最低*/

#define configKERNEL_INTERRUPT_PRIORITY [dependent of processor]

/* 系统SVC中断优先级,这两项都在在M3和PIC32上应用*/

#define configMAX_SYSCALL_INTERRUPT_PRIORITY [dependent on processor and application]

#endif /* FREERTOS_CONFIG_H */

配置FreeRTOS

FreeRTOS 是高度可配置的。所有的可配置项都在FreeRTOSConfig.h 文件中。每一个Demo 程序中都包含了一个配置好的FreeRTOSConfig.h 文件,可以以Demo程序中的FreeRTOSConfig.h 文件作为模板,在其基础上加以修改。

下面先给出一个典型的FreeRTOSConfig.h 文件,然后再逐项加以说明。

[cpp]view plaincopy

1.#ifndef FREERTOS_CONFIG_H

2.#define FREERTOS_CONFIG_H

3.

4./* Here is a good place to include header files that are required across

5.your application. */

6.#include "something.h"

7.

8.#define configUSE_PREEMPTION 1

9.#define configUSE_IDLE_HOOK 0

10.#define configUSE_TICK_HOOK 0

11.#define configCPU_CLOCK_HZ 58982400

12.#define configTICK_RATE_HZ 250

13.#define configMAX_PRIORITIES 5

14.#define configMINIMAL_STACK_SIZE 128

15.#define configTOTAL_HEAP_SIZE 10240

16.#define configMAX_TASK_NAME_LEN 16

17.#define configUSE_TRACE_FACILITY 0

18.#define configUSE_16_BIT_TICKS 0

19.#define configIDLE_SHOULD_YIELD 1

20.#define configUSE_MUTEXES 0

21.#define configUSE_RECURSIVE_MUTEXES 0

22.#define configUSE_COUNTING_SEMAPHORES 0

23.#define configUSE_ALTERNATIVE_API 0

24.#define configCHECK_FOR_STACK_OVERFLOW 0

25.#define configQUEUE_REGISTRY_SIZE 10

26.#define configGENERATE_RUN_TIME_STATS 0

27.

28.#define configUSE_CO_ROUTINES 0

29.#define configMAX_CO_ROUTINE_PRIORITIES 1

30.

31.#define configUSE_TIMERS 1

32.#define configTIMER_TASK_PRIORITY 3

33.#define configTIMER_QUEUE_LENGTH 10

34.#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE

35.

36.#define configKERNEL_INTERRUPT_PRIORITY [dependent of processor]

37.#define configMAX_SYSCALL_INTERRUPT_PRIORITY [dependent on processor and

application]

38.

39.#define configASSERT( ( x ) ) if( ( x ) == 0 ) vCallAssert( __

FILE__, __LINE__ )

40.

41.#define INCLUDE_vTaskPrioritySet 1

42.#define INCLUDE_uxTaskPriorityGet 1

43.#define INCLUDE_vTaskDelete 1

44.#define INCLUDE_vTaskSuspend 1

45.#define INCLUDE_xResumeFromISR 1

46.#define INCLUDE_vTaskDelayUntil 1

47.#define INCLUDE_vTaskDelay 1

48.#define INCLUDE_xTaskGetSchedulerState 1

49.#define INCLUDE_xTaskGetCurrentTaskHandle 1

50.#define INCLUDE_uxTaskGetStackHighWaterMark 0

51.#define INCLUDE_xTaskGetIdleTaskHandle 0

52.#define INCLUDE_xTimerGetTimerDaemonTaskHandle 0

53.#define INCLUDE_pcTaskGetTaskName 0

54.

55.#endif /* FREERTOS_CONFIG_H */

可配置的参数

configUSE_PREEMPTION

设为1则采用抢占式调度器, 设为0则采用协作式调度器。

configUSE_IDLE_HOOK

设为1则使能idle hook,设为0则禁止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

设置堆空间(Heap)的大小。只有当程序中采用FreeRTOS 提供的内存分配算法时才会用到。

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

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

configKERNEL_INTERRUPT_PRIORITY 和

configMAX_SYSCALL_INTERRUPT_PRIORITY

Cortex-M3, PIC24, dsPIC, PIC32, SuperH 和RX600 的移植代码中会使用到configKERNEL_INTERRUPT_PRIORITY.

PIC32, RX600 和Cortex-M系列会使用到

configMAX_SYSCALL_INTERRUPT_PRIORITY

configKERNEL_INTERRUPT_PRIORITY应该被设为最低优先级。

对那些只定义了configKERNEL_INTERRUPT_PRIORITY 的系统:

configKERNEL_INTERRUPT_PRIORITY决定了FreeRTOS内核使用的优先级。

所有调用API函数的中断的优先级都应设为这个值,不调用API函数的中断可以设为更高的优先级。

对那些定义了configKERNEL_INTERRUPT_PRIORITY 和

configMAX_SYSCALL_INTERRUPT_PRIORITY的系统:

configKERNEL_INTERRUPT_PRIORITY决定了FreeRTOS内核使用的优先级。configMAX_SYSCALL_INTERRUPT_PRIORITY决定了可以调用API函数的中断的最高优先级。高于这个值的中断处理函数不能调用任何API 函数。

configASSERT

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

以INCLUDE 开头参数

以'INCLUDE' 开头的宏允许我们将部分不需要的API 函数排除在编译生成的代码之外。这可以使内核代码占用更少的ROM 和RAM。

比如,如果代码中需要用到vTaskDelete 函数则这样写:

#defineINCLUDE_vTaskDelete 1

如果不需要,则这样写:

#defineINCLUDE_vTaskDelete 0

一、任务创建

1. xTaskCreate

task. h

portBASE_TYPE xTaskCreate(

pdTASK_CODE pvTaskCode,

const portCHAR * const pcName,

unsigned portSHORT usStackDepth,

void *pvParameters,

unsigned portBASE_TYPE uxPriority,

xTaskHandle *pvCreatedTask

);

创建新的任务并添加到任务队列中,准备运行

Parameters:

返回: pdPASS 是如果任务成功创建并且添加到就绪列中,另外错误代码在projdefs. H文件定义

2. vTaskDelete

task. h

void vTaskDelete( xTaskHandle pxTask );

INCLUDE_vTaskDelete必须定义为1,这个函数才能可用。查看配置部分获得更多信息。

从RTOS实时内核管理中移除任务。要删除的任务将从就绪,封锁,挂起,事件列表中移除。

注意:空闲任务负责释放内核分配给已删除任务的内存。因此,如果应用程序调用了vTaskDelete (),微控制器执行时间,空闲任务不假死是很重要的。内存分配给任务的代码不会自动释放,应该在任务删除之前。

参数:

vTaskDelay() 有关,而vTaskDelayUntil() 指定是一个绝对时间(任务希望开

启) vTaskDelay()中断任务从调用这个函数开始到指定时间。很难使用vTaskDelay()自身来产生一个固定的执行频率,因为:随着调用vTaskDelay()一个任务开启的时间和任务下一次调用vTaskDelay()的时间,这两者之间可能不是固定的【任务可能采取不同方式,可能通过调用,可能来自中断,或者优先取得每次任务执行的时间】。而vTaskDelay()指定的时间与调用这个函数相关,vTaskDelayUntil() 指定的是绝对时间(任务希望开启的)。

应该注意:vTaskDelayUntil() 如果指定的苏醒时间使用完,将立即返回。因此,一个使用vTaskDelayUntil() 来周期性的执行的任务,如果执行周期因为任何原因(例如任务是临时为悬挂状态)暂停而导致任务错过一个或多个执行周期,那么需要重新计算苏醒时间。通过检查像pxPreviousWakeTime可变的参数来组织当前时间片计数。然而在大多数使用中并不是必须的。产量 portTICK_RATE_MS 用来计算时间片频率的实时时间- 按照一个时间片周期。

参数:

Returns:

pxTask的优先级

6. vTaskPrioritySet

task. h

void vTaskPrioritySet( xTaskHandle pxTask, unsigned portBASE_TYPE uxNewPriority );

设置INCLUDE_vTaskPrioritySet为1,才能使用此函数。参考配置获得更多信息。设置任务的优先级。如果设置的优先级高于当前执行任务的优先级,则上下文切换将在此函数返回之前发生。

参数:

唤醒挂起的任务。必须是调用 vTaskSuspend () 后挂起的任务,才有可能通过调用 vTaskResume ()重新运行。

Parameters:

Returns:

xTaskCallApplicationTaskHook

task. H

#define traceTASK_SWITCHED_OUT() xTaskCallApplicationTaskHook( pxCurrentTCB, 0 )

portBASE_TYPE xTaskCallApplicationTaskHook( xTaskHandle xTask, void *pvParamete r );

configUSE_APPLICATION_TASK_TAG必须设置为1,这个函数才能使用。参考配置获得更多信息。

每个任务可以分配一个标签值。正常情况下,这个值仅用于应用程序,内核并不存储。然而,可以使用标签赋值给钩子(或回调)函数给任务——钩子函数将通过调用xTaskCallApplicationTaskHook()执行。每个任务定义自己的返回值,或者仅仅定义一个返回值。尽管可以使用第一个函数参数来调用任务中的钩子函数,最常见的使用是任务钩子函数——描述钩子宏,像每个如下的例子。任务钩子函数必须使用pdTASK_HOOK_CODE 类型,传递void *参数,和返回portBASE_TYPE类型的值。Void *参数用来传递给钩子函数的任何信息。

参数:

三、内核控制

11. vTaskStartScheduler

相关文档