- 前言
- 一、创建任务和删除函数
- 1.xTaskCreate()
- 2.xTaskCreateStatic()
- 3.xTaskCreateRestricted()
- 4.vTaskDelete()
- 二、任务函数和任务控制块TCB
- 1.任务函数模板
- 2.TCB
- 三、延时函数
- 1.vTaskDelay()
- 2.vTaskDelayUntil()
- 3.系统时钟节拍
- 四、任务挂起和恢复函数
- 1.vTaskSuspend()
- 2.vTaskResume()
- 3.xTaskResumeFromISR()
- 总结
提示:以下是本篇文章正文内容
一、创建任务和删除函数FreeRTOS最基本的功能就是任务管理:创建和删除任务
1.xTaskCreate()函数原型
static inline IRAM_ATTR BaseType_t xTaskCreate(
TaskFunction_t pvTaskCode, // 任务函数
const char * const pcName,//任务名称,没什么用
const uint32_t usStackDepth,//任务堆栈大小
void * const pvParameters,//传递给 任务函数的参数
UBaseType_t uxPriority,//任务优先级
TaskHandle_t * const pvCreatedTask//任务句柄
)
{
return xTaskCreatePinnedToCore( pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pvCreatedTask, tskNO_AFFINITY );
}
此函数用来创建一个任务,任务需要RAM来保存与任务有关的状态信息(任务控制块),任务也需要一定的RAM来作为任务堆栈。所需的RAM会自动从FreeRTOS的堆中分配。
2.xTaskCreateStatic()此函数和xTaskCreate()功能一样,但是需要的RAM需要用户来提供
3.xTaskCreateRestricted()此函数和xTaskCreate()功能一样,但是此函数要求所使用的MCU有MPU(内存保护单元)
4.vTaskDelete()函数原型
void vTaskDelete( TaskHandle_t xTaskToDelete ) PRIVILEGED_FUNCTION;
使用任务句柄删除指定的任务,若删除任务本身传入NULL即可
用于删除创建的任务
注: 1.从RTOS 实时内核管理中移除任务,要删除的任务将从就绪,封锁,挂起,事件列表中移除
2.任务被删除后就不复存在,也不会再进入运行态, 空闲任务负责释放内核分配给已删除任务的内存
3.只有内核为任务分配的内存空间才会在任务被删除后由空闲任务自动回收,任务自己占用的内存或资源需要由应用程序自己显式地释放
eg:创建三个任务,并在串口打印出来
#include
// 任务1
#define TASK1_TASK_PRIO 1 // 任务优先级
#define TASK1_STK_SIZE 1024 // 任务堆栈大小
TaskHandle_t Tasks1_TaskHandle; // 任务句柄
void task1(void *pvParameters); //任务函数
// 任务2
#define TASK2_TASK_PRIO 1 // 任务优先级
#define TASK2_STK_SIZE 1024 // 任务堆栈大小
TaskHandle_t Tasks2_TaskHandle; // 任务句柄
void task2(void *pvParameters); //任务函数
// 任务3
#define TASK3_TASK_PRIO 1 // 任务优先级
#define TASK3_STK_SIZE 1024 // 任务堆栈大小
TaskHandle_t Tasks3_TaskHandle; // 任务句柄
void task3(void *pvParameters); //任务函数
void setup()
{
Serial.begin(115200);
// 创建任务
xTaskCreate(task1, "task1_task",TASK1_STK_SIZE,NULL,TASK1_TASK_PRIO,NULL);
xTaskCreate(task2, "task2_task",TASK2_STK_SIZE,NULL,TASK2_TASK_PRIO,NULL);
xTaskCreate(task3, "task3_task",TASK3_STK_SIZE,NULL,TASK3_TASK_PRIO,NULL);
vTaskStartScheduler(); //启动调度
}
void loop()
{
}
void task1(void *pvParameters)
{
while(true)
{
Serial.println("task1 runing........");
vTaskDelay(100/portTICK_PERIOD_MS); //等待1s
}
}
void task2(void *pvParameters)
{
while(true)
{
Serial.println("task2 runing........");
vTaskDelay(100/portTICK_PERIOD_MS); //等待1s
}
}
void task3(void *pvParameters)
{
while(true)
{
Serial.println("task3 runing........");
vTaskDelay(100/portTICK_PERIOD_MS); //等待1s
}
}
结果
使用xTaskCreate()创建任务之后,该函数的第一个参数就是pxTaskCode,也就是我们定义任务函数的函数名,任务函数就是实现任务工作的函数,模板如下
void vATaskFunction(void *pvParameters)
{
for(;;)
{
--任务应用程序--
vTaskDelay();
}
vTaskDelete(NULL);
}
1.任务函数的本质也是函数,函数名根据情况而定,但是函数的返回类型必须是void类型,函数的参数也必须是viod指针类型
2.任务具体的执行过程是一个大循环,for(;;)或者while(true)都可以
3.在循环里面实现我们真正要做的事情的程序
4.调用vTaskDelay(),任务从运行态进入阻塞态,转而去执行其他任务,这里一定不用使用delay, 一般只要能让任务发送调度就可以,比如信号量,队列,任务调度器都可
5.任务函数一般不允许跳出循环
2.TCB每个任务都有一些属性要求存储,任务控制块就是实现的该功能的,在使用xTaskCreak()创建任务的时候,会自动的给每个任务分配一个TCB,
主要有一些属性
函数原型
void vTaskDelay( const TickType_t xTicksToDelay ) PRIVILEGED_FUNCTION;
在UCOSIII延时函数有三种模式:相对模式,周期模式和绝对模式, 在FreeRTOS中,vTaskDelay()就是相对延时函数,而vTaskDelayUnitl()就是绝对延时函数。
参数xTicksToDelay 是以心跳周期为单位,每个‘1’代表15ms,延时的时间一般大于0,否则直接使用**任务调度函数portYIELD()**进行任务调度(注:延时函数里面调用了任务调度的函数)
如果看过UCOS源码的都知道,调用了该延时函数,任务就相当于挂起,会被从就绪列表中删除,然后会被添加到时基列表,当延时时间到就会重新添加到就绪列表
实时操作系统的两大列表就是时基列表和就绪列表 有兴趣的大佬可以看这篇UCOS的介绍:UCOSiii源码阅读
2.vTaskDelayUntil()函数原型
void vTaskDelayUntil( TickType_t * const pxPreviousWakeTime, const TickType_t xTimeIncrement ) PRIVILEGED_FUNCTION;
延时的绝对时间,应用于按照一定频率运行的任务
该处使用的url网络请求的数据。
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?