FreeRTOS任务

合集下载

freertos任务创建流程

freertos任务创建流程

freertos任务创建流程FreeRTOS是一个开源的实时操作系统内核,它提供了一种简单而强大的方式来管理多个任务并让它们在单片机上并行运行。

在本篇文章中,我们将会详细介绍如何创建一个FreeRTOS任务。

1. 创建任务函数首先,我们需要创建一个函数来作为我们的任务。

这个函数应该包含我们想要执行的代码,并且应该无限循环以便在任务完成后继续运行。

例如:```void taskFunction(void *pvParameters){while(1){//执行任务代码}}```2. 创建任务句柄接下来,我们需要创建一个变量来保存我们的任务句柄。

这个句柄将用于管理和控制我们的任务。

例如:```TaskHandle_t xTaskHandle;```3. 创建任务现在,我们可以使用FreeRTOS API中的xTaskCreate()函数来创建我们的任务。

这个函数需要四个参数:任务函数、任务名称、堆栈大小和传递给任务函数的参数。

例如:```xTaskCreate(taskFunction, "Task Name", 128, NULL, 1,&xTaskHandle);在这个例子中,我们将使用名为“Task Name”的名称创建一个堆栈大小为128字节的新任务,并将其优先级设置为1。

最后一个参数是指向保存新创建任务句柄的变量的指针。

4. 启动调度器最后,我们需要启动FreeRTOS调度器以开始运行我们的任务。

这可以通过调用vTaskStartScheduler()函数来完成。

例如:```vTaskStartScheduler();```现在,我们的任务已经创建并开始运行了。

完整的FreeRTOS任务创建流程如下:```void taskFunction(void *pvParameters)while(1){//执行任务代码}}TaskHandle_t xTaskHandle;xTaskCreate(taskFunction, "Task Name", 128, NULL, 1,&xTaskHandle);vTaskStartScheduler();```总结以上就是创建FreeRTOS任务的完整流程。

freertos基础概念

freertos基础概念

freertos基础概念FreeRTOS(Real-time Operating System)是一款开源的实时操作系统内核,它提供了一系列基础概念和功能,使得嵌入式系统的开发变得更加便捷和可靠。

本文将详细介绍FreeRTOS的基础概念,帮助读者更好地了解和使用这个强大的实时操作系统。

一、任务(Task)任务是FreeRTOS中最基本的执行单元,每个任务都是一个独立的、独立调度的执行流。

任务是由用户定义的函数组成,通过创建任务并指定任务函数,可以将一个普通的函数转化为一个可以被FreeRTOS调度的任务。

任务函数可以包含任意的C语言代码,通过任务切换(Task Switching)机制,FreeRTOS能够在不同的任务间切换执行,实现多任务并发执行。

二、调度器(Scheduler)调度器是FreeRTOS核心的组成部分,它负责管理和调度所有的任务。

调度器按照优先级和时间片(Time Slice)来决定任务的执行顺序,优先级高的任务将被优先调度,时间片机制保证了任务之间的公平执行。

调度器的运行是非抢占式的,即任务只有在主动让出CPU时才会被切换,这保证了任务执行的稳定性和可预测性。

三、信号量(Semaphore)信号量是一种用于任务间同步和互斥的机制。

FreeRTOS提供了两种类型的信号量:二值信号量(Binary Semaphore)和计数信号量(Counting Semaphore)。

二值信号量用于实现互斥锁,用于任务之间的互斥访问共享资源;计数信号量用于实现任务间的同步,用于等待和唤醒任务。

信号量能够有效地避免竞态条件和资源争用,提高系统的并发性和响应能力。

四、消息队列(Message Queue)消息队列是一种用于任务间通信的机制,允许任务通过发送和接收消息来实现信息的传递。

消息队列可以实现任务的异步通信和解耦,用于解决任务之间的数据交换和协作问题。

FreeRTOS提供了灵活且高效的消息队列机制,能够提供稳定和可靠的通信服务。

freertos的流程,任务调度的基本步骤

freertos的流程,任务调度的基本步骤

freertos的流程,任务调度的基本步骤FreeRTOS的流程主要包括任务创建、任务调度和任务删除三个阶段。

任务创建的基本步骤如下:1. 创建任务:通过调用xT askCreate()函数创建一个任务,需要指定任务函数、任务名称、任务栈大小和任务优先级等参数。

2. 启动调度器:通过调用vTaskStartScheduler()函数启动任务调度器。

任务调度的基本步骤如下:1. 任务就绪队列:调度器会根据任务的优先级将就绪状态的任务加入到就绪列表中,按优先级从高到低排列。

2. 调度算法:调度器使用抢占式优先级调度算法,高优先级的任务总是会抢占低优先级的任务。

3. 任务切换:当一个任务被抢占时,调度器会保存当前任务的上下文,并加载下一个任务的上下文,完成任务切换。

4. 任务执行:被选中的任务会在其任务函数中执行,直到任务主动挂起或者因某种原因被抢占。

任务删除的基本步骤如下:1. 删除任务:通过调用vTaskDelete()函数删除当前任务。

2. 清理资源:任务删除后,可以在任务函数中清理使用的资源,如释放内存、关闭文件等操作。

以上是FreeRTOS任务调度的基本步骤,这些步骤是FreeRTOS实现多任务调度的基础。

freertos task退出方式

freertos task退出方式

freertos task退出方式FreeRTOS 中的任务(Task)可以通过多种方式退出。

以下是一些常见的FreeRTOS 任务退出方式:1. 自行返回:任务函数可以正常返回,这会导致任务退出。

例如:```cvoid vTaskFunction(void *pvParameters) {// 任务执行的代码// 任务完成后,正常返回,导致任务退出vTaskDelete(NULL);}```在这个例子中,`vTaskDelete(NULL)` 会删除当前任务。

2. 调用`vTaskDelete`:任务可以在执行的任何时候调用`vTaskDelete` 函数,以删除自身。

例如:```cvoid vTaskFunction(void *pvParameters) {// 任务执行的代码// 任务完成后调用vTaskDelete 删除任务vTaskDelete(NULL);}```3. 使用`configUSE_TASK_DELETE_NOTIFICATION`:如果FreeRTOS 配置中启用了`configUSE_TASK_DELETE_NOTIFICATION`,任务可以等待其他任务删除通知而退出。

这个功能允许一个任务等待另一个任务完成后再退出。

```cvoid vTaskFunction(void *pvParameters) {// 任务执行的代码// 任务等待删除通知ulTaskNotifyTake(pdTRUE, portMAX_DELAY);// 任务完成后调用vTaskDelete 删除任务vTaskDelete(NULL);}```在另一个任务中,可以使用`vTaskNotifyGive` 来发送删除通知:```cvTaskNotifyGive(xTaskHandle);```这些方式可以根据任务的需求和应用场景选择。

在任务完成其工作后,通常应该谨慎地使用合适的方式来退出任务,以确保系统稳定性。

FreeRTOS任务栈大小确定及其溢出检测

FreeRTOS任务栈大小确定及其溢出检测

FreeRTOS任务栈⼤⼩确定及其溢出检测以下转载⾃FreeRTOS 的任务栈设置不管是裸机编程还是 RTOS 编程,栈的分配⼤⼩都⾮常重要。

局部变量,函数调⽤时的现场保护和返回地址,函数的形参,进⼊中断函数前和中断嵌套等都需要栈空间,栈空间定义⼩了会造成系统崩溃。

裸机的情况下,⽤户可以在这⾥配置栈⼤⼩:为什么是堆中的?因为我们采⽤的就是动态创建任务的⽅式。

如果静态创建,就和我们⾃⼰开辟的空间有关,通常静态创建任务⽤数组作为容器,但是通常静态创建的⽅式我们都不使⽤。

FreeRTOS 的系统栈设置上⾯跟⼤家讲解了什么是任务栈,这⾥的系统栈⼜是什么呢?裸机的情况下,凡是⽤到栈空间的地⽅都是在这⾥配置的栈空间:在 RTOS 下,上⾯两个截图中设置的栈⼤⼩有了⼀个新的名字叫系统栈空间,⽽任务栈是不使⽤这⾥的空间的。

任务栈不使⽤这⾥的栈空间,哪⾥使⽤这⾥的栈空间呢?答案就在中断函数和中断嵌套。

由于 Cortex-M3 和 M4 内核具有双堆栈指针,MSP 主堆栈指针和 PSP 进程堆栈指针,或者叫 PSP任务堆栈指针也是可以的。

在 FreeRTOS 操作系统中,主堆栈指针 MSP 是给系统栈空间使⽤的,进程堆栈指针 PSP 是给任务栈使⽤的。

也就是说,在 FreeRTOS 任务中,所有栈空间的使⽤都是通过PSP 指针进⾏指向的。

⼀旦进⼊了中断函数以及可能发⽣的中断嵌套都是⽤的 MSP 指针。

这个知识点要记住它,当前可以不知道这是为什么,但是⼀定要记住。

实际应⽤中系统栈空间分配多⼤,主要是看可能发⽣的中断嵌套层数,下⾯我们就按照最坏执⾏情况进⾏考虑,所有的寄存器都需要⼊栈,此时分为两种情况:64 字节对于 Cortex-M3 内核和未使⽤ FPU(浮点运算单元)功能的 Cortex-M4 内核在发⽣中断时需要将 16 个通⽤寄存器全部⼊栈,每个寄存器占⽤ 4 个字节,也就是 16*4 = 64 字节的空间。

freertos任务划分规则

freertos任务划分规则

freertos任务划分规则FreeRTOS是一种流行的实时操作系统(RTOS),它广泛应用于嵌入式系统领域。

在使用FreeRTOS开发嵌入式应用程序时,任务的划分是至关重要的。

本文将介绍一些常用的任务划分规则,以帮助开发者更好地设计和管理任务。

1. 任务的功能划分任务的划分应该根据功能模块来进行。

将不同功能的代码封装成不同的任务,有助于提高代码的可维护性和可重用性。

比如,可以将与传感器交互的代码封装成一个任务,将数据处理的代码封装成另一个任务,将与用户交互的代码封装成第三个任务,以此类推。

2. 任务的优先级划分任务的优先级决定了任务的调度顺序。

一般情况下,优先级越高的任务会被更早地调度执行。

在划分任务的优先级时,可以根据任务的紧急程度、对系统资源的需求等因素来进行。

比如,与硬件交互的任务可能需要更高的优先级,以确保实时性。

3. 任务的执行时间划分任务的执行时间也是划分任务的一个重要考虑因素。

根据任务的执行时间,可以将长时间执行的任务划分为若干个子任务,以提高系统的响应速度和实时性。

此外,还可以利用FreeRTOS提供的延时函数,合理安排任务的执行时间,避免长时间占用CPU资源。

4. 任务的通信与同步在多任务系统中,任务之间的通信和同步是必不可少的。

FreeRTOS 提供了多种任务通信和同步的机制,比如消息队列、信号量、互斥锁等。

在划分任务时,可以根据任务之间的依赖关系和数据交互的需求,选择合适的通信和同步机制,确保任务之间的协作顺利进行。

5. 任务的周期性划分对于周期性任务,可以根据任务的周期来划分。

比如,定时采集传感器数据的任务可以设置为一个周期性任务,每隔一定时间执行一次。

这样可以有效地利用系统资源,提高系统的实时性。

6. 任务的资源需求划分不同的任务可能对系统资源的需求不同。

在划分任务时,需要考虑任务对CPU、内存、IO等资源的需求,合理分配系统资源,以避免资源争用和系统崩溃等问题。

可以根据任务的资源需求设置任务的堆栈大小、优先级等参数。

freertos任务管理

freertos是一个轻量级的rtos,它目前实现了一个微内核,并且port到arm7, avr, pic18, coldfire等众多处理器上;目前已经在rtos的市场上占有不少的份额。

它当然不是一个与vxworks之类的rtos竞争的操作系统,它的目标在于低性能小RAM的处理器上。

整个系统只有3个文件,外加上port的和处理器相关的两个文件,实现是很简洁的。

与ucosii不同,它是free的,ucosii不是free的,虽然它的代码是公开的。

FreeRTOS提供的功能包括:任务管理、时间管理、信号量、消息队列、内存管理。

FreeRTOS内核支持优先级调度算法,每个任务可根据重要程度的不同被赋予一定的优先级,CPU总是让处于就绪态的、优先级最高的任务先运行。

FreeRT0S内核同时支持轮换调度算法,系统允许不同的任务使用相同的优先级,在没有更高优先级任务就绪的情况下,同一优先级的任务共享CPU的使用时间。

这一点是和ucosii不同的。

另外一点不同是freertos既可以配置为可抢占内核也可以配置为不可抢占内核。

当FreeRTOS 被设置为可剥夺型内核时,处于就绪态的高优先级任务能剥夺低优先级任务的CPU使用权,这样可保证系统满足实时性的要求;当FreeRTOS被设置为不可剥夺型内核时,处于就绪态的高优先级任务只有等当前运行任务主动释放CPU的使用权后才能获得运行,这样可提高CPU的运行效率。

这篇文章是以freertos v5.0版本的代码为例子分析下它的任务管理方面的实现。

时间关系可能没有太多时间写的很详细了。

1.链表管理freertos里面的任务管理,queue,semaphore管理等都借助于双向链表,它定义了个通用的数据结构/*定义链表节点??*/Struct xLIST_ITEM{portTickType xItemValue; //链表节点的数据项,通常用在任务延时,表示一个任务延时的节拍数volatile struct xLIST_ITEM * pxNext; //通过这两个成员变量将所有节点volatile struct xLIST_ITEM * pxPrevious;//链接成双向链表void * pvOwner; //指向该item的所有者,通常是任务控制块void * pvContainer; //指向此链表结点所在的链表};/*定义一个链表??*//*一个优先级一个链表??*/这个数据结构定义了一个通用的链表节点;下面的数据结构定义了一个双向链表typedef struct xLIST{volatile unsigned portBASE_TYPE uxNumberOfItems;//表示该链表中节点的数目volatile xListItem * pxIndex;//用于遍历链表,指向上次访问的节点volatile xMiniListItem xListEnd;//链表尾结点 /*指向链表中的最后一个节点?*/ } xList;而下面这个数据结构用在xList中,只是为了标记一个链表的尾,是一个markerstruct xMINI_LIST_ITEM{portTickType xItemValue;volatile struct xLIST_ITEM *pxNext;volatile struct xLIST_ITEM *pxPrevious;};typedef struct xMINI_LIST_ITEM xMiniListItem;对于链表的操作也定义了一系列的函数和宏,在list.c文件中。

FreeRTOS记录(二、FreeRTOS任务API认识和源码简析)

FreeRTOS记录(二、FreeRTOS任务API认识和源码简析)•FreeRTOS 任务API▪创建任务▪删除任务▪挂起任务▪恢复任务▪任务优先级▪延时任务•FreeRTOS 任务源码简析▪任务状态▪任务控制块▪任务创建流程分析▪任务删除流程分析▪任务挂起▪任务恢复if((thread_def->buffer != NULL) && (thread_def->controlblock != NULL)) {handle = xTaskCreateStatic((TaskFunction_t)thread_def->pthread,(const portCHAR *)thread_def->name,thread_def->stacksize, argument, makeFreeRtosPriority(thread_def->tpriority),thread_def->buffer, thread_def->controlblock);}else {if (xTaskCreate((TaskFunction_t)thread_def->pthread,(const portCHAR *)thread_def->name,thread_def->stacksize, argument, makeFreeRtosPriority(thread_def->tpriority),&handle) != pdPASS) {return NULL;}}#elif( configSUPPORT_STATIC_ALLOCATION == 1 )handle = xTaskCreateStatic((TaskFunction_t)thread_def->pthread,(const portCHAR *)thread_def->name,thread_def->stacksize, argument, makeFreeRtosPriority(thread_def->tpriority),thread_def->buffer, thread_def->controlblock);#elseif (xTaskCreate((TaskFunction_t)thread_def->pthread,(const portCHAR *)thread_def->name,thread_def->stacksize, argument, makeFreeRtosPriority(thread_def->tpriority),&handle) != pdPASS) {return NULL;}#endifreturn handle;}由上可以得知,CubeMX生成的osThreadCreate 会根据我们在Config Parameters中的Memory Allocation内存分配中选择的配置结果自动的选择xTaskCreate还是xTaskCreateStatic 。

06嵌入式实时操作系统FreeRTOS任务函数


阻塞任务,直到指定的时钟节拍后解除阻塞 任务以指定的时钟节拍周期性执行 获取某个任务的优先级 设定某个任务的优先级 获取系统任务状态 获取某个任务信息 获取当前任务句柄 获取空闲任务句柄 获取某个任务剩余堆栈历史最小值 获取某个任务的状态 获取某个任务的任务名 根据任务名查找某个任务句柄 获取系统时钟节拍值 中断内获取系统时钟节拍值 获取调度器状态 获取任务数量 以列表形式输出所有任务的信息 获取所有任务的运行时间 设置任务标签 获取任务标签
FreeRTOS任务函数
任务管理是FreeRTOS的核心功能,除内核函数中的 任务创建、挂起、恢复、删除和任务切换等之外, 还有用于让出CPU使用权的阻塞式延时,任务优先 级查询、设置,获取任务状态信息,以及获取任务 运行时间信息等辅助函数。
FreeRTOS任务函数
vTaskDelay() vTaskDelayUntil() uxTaskPriorityGet() vTaskPrioritySet() uxTaskGetSystemState() vTaskGetInfo() xTaskGetCurrentTaskHandle() xTaskGetIdleTaskHandle() uxTaskGetStackHighWaterMark() eTaskGetState() pcTaskGetName() xTaskGetHandle() xTaskGetTickCount() xTaskGetTickCountFromISR() xTaskGetSchedulerState() uxTaskGetNumberOfTasks() vTaskList() vTaskGetRunTimeStats() vTaskSetApplicationTaskTag() xTaskGetApplicationTaskTag()

freertos 任务调度策略

freertos 任务调度策略FreeRTOS任务调度策略FreeRTOS是一款开源的实时操作系统(RTOS),用于嵌入式系统应用。

它提供了一种灵活且可配置的任务调度策略,以满足各种需求。

任务调度策略是FreeRTOS用于管理和分配任务时间片的方法,它决定了各个任务之间的调度方式。

1. 先来先服务(First-Come, First-Served)调度策略:这是最简单的任务调度策略,任务按照它们被创建的顺序进行调度。

当一个任务的时间片用完后,会让出处理器给下一个任务。

这种策略适用于任务的优先级相同且对任务完成顺序没有特别要求的情况。

2. 优先级调度策略:FreeRTOS支持基于优先级的任务调度,每个任务都被赋予一个优先级,优先级越高的任务越容易获得处理器的时间片。

当有多个任务准备好运行时,FreeRTOS会选择优先级最高的任务来运行。

这种策略适用于任务之间有不同的紧急程度或重要性的情况。

3. 循环调度策略:在循环调度策略中,任务按照一定的顺序进行调度,每个任务都有一个时间片。

当一个任务的时间片用完后,它会排到队列的末尾等待下一轮调度。

这种策略适用于需要依次完成一系列任务的场景。

4. 抢占式调度策略:在抢占式调度策略中,任务可以被中断,即使它没有执行完。

任务的优先级决定了它可以被抢占的条件。

当一个高优先级任务准备好运行时,它会抢占正在执行的低优先级任务,并开始执行。

这种策略适用于需要实时性能和任务响应能力的场景。

5. 时间片轮转调度策略:时间片轮转是一种公平的调度策略,每个任务都被分配一个固定的时间片。

当一个任务的时间片用完后,它被放回就绪队列的末尾,让其他任务有机会运行。

这种策略适用于需要公平分配处理器时间的场景。

6. 最短剩余时间优先(Shortest Remaining Time Next, SRTN)调度策略:SRTN策略中,任务的优先级根据其剩余执行时间决定。

当一个任务运行时,FreeRTOS会检查其他就绪任务的剩余执行时间,并选择剩余时间最短的任务来进行抢占。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

标签:freertos转:FreeRTOS任务管理分析转自:/bluehackerfreertos是一个轻量级的rtos,它目前实现了一个微内核,并且port到arm7, avr, pic18, coldfire等众多处理器上;目前已经在rtos的市场上占有不少的份额。

它当然不是一个与vxworks之类的rtos竞争的操作系统,它的目标在于低性能小RAM的处理器上。

整个系统只有3个文件,外加上port的和处理器相关的两个文件,实现是很简洁的。

与ucosii不同,它是free的,ucosii不是free的,虽然它的代码是公开的。

FreeRTOS提供的功能包括:任务管理、时间管理、信号量、消息队列、内存管理。

FreeRTOS内核支持优先级调度算法,每个任务可根据重要程度的不同被赋予一定的优先级,CPU总是让处于就绪态的、优先级最高的任务先运行。

FreeRT0S内核同时支持轮换调度算法,系统允许不同的任务使用相同的优先级,在没有更高优先级任务就绪的情况下,同一优先级的任务共享CPU的使用时间。

这一点是和ucosii不同的。

另外一点不同是freertos既可以配置为可抢占内核也可以配置为不可抢占内核。

当FreeRTOS被设置为可剥夺型内核时,处于就绪态的高优先级任务能剥夺低优先级任务的CPU使用权,这样可保证系统满足实时性的要求;当FreeRTOS被设置为不可剥夺型内核时,处于就绪态的高优先级任务只有等当前运行任务主动释放CPU的使用权后才能获得运行,这样可提高CPU的运行效率。

这篇文章是以freertos v5.0版本的代码为例子分析下它的任务管理方面的实现。

时间关系可能没有太多时间写的很详细了。

1.链表管理freertos里面的任务管理,queue,semaphore管理等都借助于双向链表,它定义了个通用的数据结构struct xLIST_ITEM{portTickType xItemValue; //链表节点的数据项,通常用在任务延时,表示 //一个任务延时的节拍数volatile struct xLIST_ITEM * pxNext; //通过这两个成员变量将所有节点volatile struct xLIST_ITEM * pxPrevious;//链接成双向链表void * pvOwner; //指向该item的所有者,通常是任务控制块void * pvContainer; //指向此链表结点所在的链表};这个数据结构定义了一个通用的链表节点;下面的数据结构定义了一个双向链表typedef struct xLIST{volatile unsigned portBASE_TYPE uxNumberOfItems;//表示该链表中节点的数目volatile xListItem * pxIndex;//用于遍历链表,指向上次访问的节点volatile xMiniListItem xListEnd;//链表尾结点} xList;而下面这个数据结构用在xList中,只是为了标记一个链表的尾,是一个markerstruct xMINI_LIST_ITEM{portTickType xItemValue;volatile struct xLIST_ITEM *pxNext;volatile struct xLIST_ITEM *pxPrevious;};typedef struct xMINI_LIST_ITEM xMiniListItem;对于链表的操作也定义了一系列的函数和宏,在list.c文件中。

如初始化个链表,吧一个节点插入链表等。

初始化链表:void vListInitialise( xList *pxList ){/* The list structure contains a list item which is used to mark theend of the list. To initialise the list the list end is insertedas the only list entry. */pxList->pxIndex = ( xListItem * ) &( pxList->xListEnd );/* The list end value is the highest possible value in the list toensure it remains at the end of the list. */pxList->xListEnd.xItemValue = portMAX_DELAY;/* The list end next and previous pointers point to itself so we knowwhen the list is empty. */pxList->xListEnd.pxNext = ( xListItem * ) &( pxList->xListEnd );pxList->xListEnd.pxPrevious = ( xListItem * ) &( pxList->xListEnd );pxList->uxNumberOfItems = 0;}把一个节点插入到链表尾部:void vListInsertEnd( xList *pxList, xListItem *pxNewListItem ){volatile xListItem * pxIndex;/* Insert a new list item into pxList, but rather than sort the list,makes the new list item the last item to be removed by a call topvListGetOwnerOfNextEntry. This means it has to be the item pointed to bythe pxIndex member. */pxIndex = pxList->pxIndex;pxNewListItem->pxNext = pxIndex->pxNext;pxNewListItem->pxPrevious = pxList->pxIndex;pxIndex->pxNext->pxPrevious = ( volatile xListItem * ) pxNewListItem;pxIndex->pxNext = ( volatile xListItem * ) pxNewListItem;pxList->pxIndex = ( volatile xListItem * ) pxNewListItem;/* Remember which list the item is in. */pxNewListItem->pvContainer = ( void * ) pxList;( pxList->uxNumberOfItems )++;}这些就不多说了。

2.任务控制块typedef struct tskTaskControlBlock{volatile portSTACK_TYPE *pxTopOfStack;//指向堆栈顶xListItem xGenericListItem; //通过它将任务连入就绪链表或者延时链表或者挂起链表中 xListItem xEventListItem;//通过它把任务连入事件等待链表unsigned portBASE_TYPE uxPriority;//优先级portSTACK_TYPE *pxStack; //指向堆栈起始位置signed portCHAR pcTaskName[ configMAX_TASK_NAME_LEN ];#if ( portCRITICAL_NESTING_IN_TCB == 1 )unsigned portBASE_TYPE uxCriticalNesting;#endif#if ( configUSE_TRACE_FACILITY == 1 )unsigned portBASE_TYPE uxTCBNumber;//用于trace,debug时候提供方便#endif#if ( configUSE_MUTEXES == 1 )unsigned portBASE_TYPE uxBasePriority;//当用mutex发生优先级反转时用#endif#if ( configUSE_APPLICATION_TASK_TAG == 1 )pdTASK_HOOK_CODE pxTaskTag;#endif} tskTCB;其中uxBasePriority用于解决优先级反转,freertos采用优先级继承的办法解决这个问题,在继承时,将任务原先的优先级保存在这个成员中,将来再从这里恢复任务的优先级。

3.系统全局变量freertos将任务根据他们的状态分成几个链表。

所有就绪状态的任务根据任务优先级加到对应的就绪链表中。

系统为每个优先级定义了一个xList。

如下:static xList pxReadyTasksLists[ configMAX_PRIORITIES ]; /*< Prioritised ready tasks. */此外,所有延时的任务加入到两个延时链表之一。

static xList xDelayedTaskList1;static xList xDelayedTaskList2;还定义了两个指向延时链表的指针:static xList * volatile pxDelayedTaskList;static xList * volatile pxOverflowDelayedTaskList;freertos弄出两个延时链表是因为它的延时任务管理的需要。

freertos根据任务延时时间的长短按序将任务插入这两个链表之一。

在插入前先把任务将要延时的xTicksToDelay数加上系统当前tick数,这样得到了一个任务延时due time(到期时间)的绝对数值。

但是有可能这个相加操作会导致溢出,如果溢出则加入到pxOverflowDelayedTaskList指向的那个链表,否则加入pxDelayedTaskList 指向的链表。

freertos还定义了个pending链表:static xList xPendingReadyList;这个链表用在调度器被lock(就是禁止调度了)的时期,如果一个任务从非就绪状态变为就绪状态,它不直接加到就绪链表中,而是加到这个pending链表中。

相关文档
最新文档