FreeRTOS学习记录(3)——任务创建与启动总结

对FreeRTOS的使用过程进行精简后会发现,它的整个过程其实非常简单,首先创建任务,其次登记任务,根据任务所登记的位置不断开始执行任务

下面进行详细的解释。

  • 创建任务,这个过程中会为任务分配一个任务堆栈,这里边主要存放一些任务的相关信息,如任务的优先级、任务所在的列表等等。如下图这个过程主要分为两部分,其一是填补满一个控制块中的各项内容,其二将控制块中的列表项放在就绪列表中,

  • 管理任务,这个过程主要是对于控制块中列表指针的处理,即不断将任务控制块中的列表项指针放在不同的列表中。这个就是任务调度的过程。

    • 创建任务

Freertos中实现任务创建的函数有两个:静态方法创建任务,动态函数创建任务,这两个函数的具体实现过程在前面的文章中已经有过详细的描述,这里仅仅从函数的使用层面来叙述一下函数的各个参数的用途,以及函数的返回值的说明。

1.1静态方法创建任务

首先描述静态方法创建任务,调用的函数如下


TaskHandle_t xTaskCreateStatic(   TaskFunction_t pxTaskCode,     //任务函数入口
                                  const char * const pcName,     //任务名
                                  const uint32_t ulStackDepth,   //任务栈深度
                                  void * const pvParameters,     //任务函数的参数
                                  UBaseType_t uxPriority,        //任务的优先级
                                  StackType_t * const puxStackBuffer,    //任务的栈地址
                                  StaticTask_t * const pxTaskBuffer )//任务的控制块地址

这个函数其本质是在对任务的控制块pxTaskBuffer中的各项元素进行赋值。下表为简化过的任务控制块结构

成员

解释

数据类型

结构

pxTopOfStack

栈顶指针

StackType_t *

xStateListItem;

任务节点

ListItem_t

  • listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE

/*检测列表项的完整性*/

  • configLIST_VOLATILE TickType_t xItemValue;

  • struct xLIST_ITEM * configLIST_VOLATILE pxNext;

/*指针,指向下一个列表项*/

  • struct xLIST_ITEM * configLIST_VOLATILE pxPrevious;

/*指针,指向前一个列表项*/

  • void * pvOwner;

/*记录列表项的拥有者,任务控制块中的,记录这个列表项是哪个任务的*/

  • void * configLIST_VOLATILE pvContainer;

/*说明该任务的这个列表现在挂在哪(是就绪列表or挂起列表)*/

  • listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE

/*检测列表项的完整性*/

pxStack

任务栈起始地址

StackType_t *

pcTaskName[configMAX_TASK_NAME_LEN]

任务名称

char数组

如上图,函数xTaskCreateStatic()需要任务函数、任务名、堆栈深度等七个参数,这个函数的实现过程为

  • 将任务的栈地址放入任务控制块的pxStack

  • 调用prvInitialiseNewTask()函数,并带入参数pxTaskCode, pcName, ulStackDepth, pvParameters, uxPriority, &xReturn, pxNewTCB, NULL。该函数会将控制块中的各项参数填满

  • 调用prvAddNewTaskToReadyList( ),参数为刚刚处理过的任务控制块。将新建的任务添加到就序列表中。

  • 任务创建完毕

1.2 动态方法创建任务

    • 任务调度

在Cortex-M3架构中,FreeRTOS为了任务启动和任务切换使用了三个异常:SVC、PendSV、SysTick:

SVC(系统服务调用,也称为系统调用)用于任务启动

PendSV(可挂起系统调用)用于完成任务切换

SysTick 用于产生系统节拍时钟,提供一个时间片。

这里需要注意一点,系统提供的定时器使用的是系统时钟,也就是说delay_ms(100)中的100是指100个时钟节拍。

如图中所示,某FreeRTOS系统有任务1至任务3共3个任务,其中任务一、任务二优先级为1,任务三优先级为2,那么,这些如下图所示就是这些任务在就绪任务列表中的存储方式

在调度过程中,系统在ListAready[1]中不断循环执行任务一二,这个时候如果任务一二都进入阻塞,系统会去遍历ListAready[2]、此时当数组在ListAready[2]中找到一个可执行任务任务3就会执行这个任务,这个时候如果任务三也阻塞了,系统就会继续遍历ListAready[3]...;而不论任务三有没有阻塞,此时如果任务一和任务二由阻塞状态转为就绪状态,那么在一个时间片结束后,系统就会去执行任务一二。

    • 主函数

  • 硬件初始化

  • 创建开始任务

  • 打开调度器

  • 执行初始任务

  1. 进入临界区

  1. 创建任务1、2、3、......、n

  1. 删除初始任务

  1. 离开临界区

  • 开始运行多任务系统

FreeRTOS中,任务重启可以通过删除任务并重新创建它来实现。要重启任务,可以使用vTaskDelete()函数删除任务,然后使用xTaskCreate()函数重新创建任务。删除任务会释放任务所占用的资源,并将任务从调度程序中移除。重新创建任务会重新初始化任务的上下文,并将其添加到调度程序中以便执行。这样就可以实现任务重启。\[1\]\[2\]任务重启在某些情况下是有意义的,比如需要完全重置任务的状态或在低功耗应用中关闭活动系统以降低功耗。通过重启任务,可以重新开始任务的执行,并在需要时重新配置任务的参数。这为应用程序提供了更大的灵活性和更低功耗的机会。\[2\]\[3\] #### 引用[.reference_title] - *1* [FreeRTOS任务创建、挂起、恢复与删除(备忘)](https://blog.csdn.net/VIFIN/article/details/125836305)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [FreeRTOS如何结束和重新启动调度程序](https://blog.csdn.net/foxclever/article/details/87469012)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值