FreeRTOS任务的创建(动态方法和静态方法)

这篇具有很好参考价值的文章主要介绍了FreeRTOS任务的创建(动态方法和静态方法)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


前言

本篇文章将介绍FreeRTOS任务的创建(动态方法和静态方法),了解什么是任务和任务的具体创建方法。

一、FreeRTOS任务基本概念

任务(Task):FreeRTOS 中的任务是程序执行的基本单位。任务以优先级的方式管理,高优先级的任务比低优先级的任务更容易被执行。每个任务都具有不同的堆栈和一组标志,用于控制任务的行为和与其他任务和内核进行通信。

二、动态创建任务

在FreeRTOS中的task.c中我们可以找到动态创建任务的函数原型:
FreeRTOS任务的创建(动态方法和静态方法)
创建一个任务:
使用 xTaskCreate 函数是在 FreeRTOS 中创建任务的一种方法,函数原型如下:

BaseType_t xTaskCreate(
    TaskFunction_t pvTaskCode,
    const char * const pcName,
    const configSTACK_DEPTH_TYPE usStackDepth,
    void * const pvParameters,
    UBaseType_t uxPriority,
    TaskHandle_t * const pxCreatedTask
);

1.TaskFunction_t pvTaskCode:任务函数的指针。这个参数是一个函数指针,指向一个任务的实际执行代码。任务函数的原型必须符合 TaskFunction_t 类型,即 void func(void *pvParameters),其中 pvParameters 是一个指向和任务相关的参数的指针。

2.const char * const pcName:任务的名称。这个参数是一个字符串常量,用于标识任务。

3.const configSTACK_DEPTH_TYPE usStackDepth:任务栈的大小。这个参数表示任务栈的深度、空间或者大小,以字节为单位。在创建任务时需要提供一个足够大的堆栈以确保任务可以运行。

4.void * const pvParameters:任务参数的指针。这个参数是任务的实际参数,它的类型可以是 void 指针或者其他任意类型的指针。在任务执行时,可以通过此参数来传递任务需要的参数。

5.UBaseType_t uxPriority:任务的优先级。这个参数用于指定任务的优先级,数值越大表示优先级越高。优先级的取值范围根据量化数值的位数而定,一般来说,取值范围是 0-31,在 FreeRTOS 中,0 号优先级最低,而 31 号优先级最高。

6.TaskHandle_t * const pxCreatedTask:用于返回创建的任务的句柄。创建任务成功后,系统将返回一个指向该任务的任务句柄。

示例代码:

TaskHandle_t xHandleTask1;//任务句柄

TaskHandle_t xHandleTask2;//任务句柄

//任务执行函数
void Task1(void * param)
{
	while (1)
	{
		printf("1");
	}
}

//任务执行函数
void Task2(void * param)
{
	while (1)
	{
		printf("2");
	}
}

xTaskCreate(Task1, "Task1", 100, NULL, 1, &xHandleTask1);//创建一个任务

xTaskCreate(Task2, "Task2", 100, NULL, 1, &xHandleTask2);//创建一个任务

在keil5中打开模拟仿真运行代码:
FreeRTOS任务的创建(动态方法和静态方法)
点击调试运行:
FreeRTOS任务的创建(动态方法和静态方法)
这里我将程序下载到板子上使用串口打印观察实验现象:
根据现象可以知道Task1和Task2任务轮流执行。
FreeRTOS任务的创建(动态方法和静态方法)

三、静态创建任务

使用 xTaskCreateStatic() 函数静态创建任务。该函数与 xTaskCreate() 类似,但它使用静态分配的任务控制块和堆栈空间,而不是在运行时动态分配。函数原型如下:

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
);

通过静态创建方式,可以使用编译器的内存分配器来分配任务所需的内存空间,从而避免了动态分配内存的开销和潜在的内存泄漏问题。静态创建方式还可以在一些对内存使用有限制的场合下有效地管理系统资源,提高系统的稳定性和性能。

看到这里很多人可能认为没有这个函数,这其实是FreeRTOS内部没有开启这个函数的使用。
FreeRTOS任务的创建(动态方法和静态方法)
进入task.c这个文件我们会看到只有当这个宏被设置的时候才能够使用这个静态创建任务的函数。
FreeRTOS任务的创建(动态方法和静态方法)
既然这样那么我们就来定义这个宏:
找到FreeRTOSConfig.h这个头文件在这里定义这个宏:
FreeRTOS任务的创建(动态方法和静态方法)
FreeRTOS任务的创建(动态方法和静态方法)
编译代码发现还是出错:
这里说的是没有vApplicationGetIdleTaskMemory这个函数:
FreeRTOS任务的创建(动态方法和静态方法)
使用静态创建函数创建 FreeRTOS 任务时,需要记住一点:必须实现 vApplicationGetIdleTaskMemory 函数来完成空闲任务的内存分配。这是因为在使用静态内存分配时,FreeRTOS 会自动创建一个空闲任务,该任务会在系统空闲时进行调度。空闲任务可以执行某些不需要 CPU 时间的操作,比如暂时挂起 CPU、等待时钟中断、等待消息等,以便释放 CPU 资源给其它任务使用。

空闲任务需要分配堆栈和任务控制块,而这些内存区域需要手动向 FreeRTOS 系统申请。在这种情况下,我们需要实现 vApplicationGetIdleTaskMemory 函数,该函数会在空闲任务创建之前被调用。在该函数中,我们需要声明一个静态的变量作为空闲任务控制块的内存池,并将该内存池的首地址和大小等信息传递给空闲任务创建函数,以完成空闲任务的内存分配。

vApplicationGetTimerTaskMemory函数的实现:

StackType_t xIdleTaskStack[100];
StaticTask_t xIdleTaskTCB;

void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer,
                                    StackType_t ** ppxIdleTaskStackBuffer,
                                    uint32_t * pulIdleTaskStackSize )
{
    *ppxIdleTaskTCBBuffer = &xIdleTaskTCB;
    *ppxIdleTaskStackBuffer = xIdleTaskStack;
    *pulIdleTaskStackSize = 100;
}

再次编译后会发现错误已经没有了。

示例代码:

StackType_t xTask3Stack[100];
StaticTask_t xTask3TCB;

//任务执行函数
void Task3(void * param)
{
	while (1)
	{
		printf("3");
	}
}

xTaskCreateStatic(Task3, "Task3", 100, NULL, 1, xTask3Stack, &xTask3TCB);//创建一个静态任务

四、静态创建任务和动态创建任务的区别

静态创建任务是在编译时为任务分配内存,这意味着任务在运行时之前已经预分配了足够的内存。这种方法不需要在运行时使用动态内存分配函数,因此更加可靠和节省内存。在静态方式下,任务可以使用xTaskCreateStatic()函数创建。

动态创建任务是在运行时通过动态内存分配函数分配任务内存。这种分配方式可以更灵活地适应不同大小和数量的任务,并且支持删除或重新创建任务。然而,在动态方式下,程序需要在运行时使用动态内存分配函数,这可能会导致内存泄漏和堆碎片等问题。在动态方式下,任务需要使用xTaskCreate()函数创建。

选择使用哪种方式创建任务取决于应用程序的设计和实际需要。如果应用程序中的任务数量和大小已知,则可以使用静态方式分配内存,并且无需动态内存分配。如果应用程序需要更多的灵活性,并且需要在运行时根据需要创建或删除任务,则应使用动态方式分配内存。

需要注意的是,静态方式创建任务需要事先知道任务所需的内存大小,以及将任务的堆栈和控制块明确地分配给该任务。如果任务使用的内存超出了分配的内存,则可能会发生严重错误,例如内存泄漏或严重的崩溃。在动态方式下,内存分配在运行时动态进行,因此可以更好地处理任务所需的内存。

五、任务的删除

有任务的创建那么肯定就有任务的删除,下面我们来看看怎么进行任务的删除。

在FreeRTOS中,任务可以使用vTaskDelete()函数进行删除,该函数会立即终止当前正在运行的任务,并释放该任务所使用的内存资源。

vTaskDelete函数原型:
只需要传入要删除的任务句柄即可将任务删除,在一个任务中想要将自己删除的话需要传入的是NULL。

void vTaskDelete( TaskHandle_t xTaskToDelete );
//任务执行函数
void Task1(void * param)
{
	static int i = 0;
	while (1)
	{
		i++;
		if(i == 100)
		{
			vTaskDelete(xHandleTask2);//删除任务2
		}
		if(i == 200)
		{
			vTaskDelete(NULL);//删除自己
		}
		printf("1");
	}
}

总结

本篇文章我们详细的介绍了FreeRTOS任务的创建和删除,并介绍了这两种方法创建任务的区别,希望大家好好理解并多加练习。文章来源地址https://www.toymoban.com/news/detail-484333.html

到了这里,关于FreeRTOS任务的创建(动态方法和静态方法)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • STM32 CubeMX (第一步Freertos任务管理:创建、删除、挂起、恢复)

    学习使用Freertos第一步 FreeRTOS 任务管理,您需要掌握以下几个关键函数: 1. xTaskCreate() :用于创建一个任务,需要指定任务函数、任务名称、任务栈大小和优先级等参数。 2. vTaskDelete() :用于删除一个任务,可以由任务自身或其他任务调用。 3. vTaskDelay() :用于使当前任务进

    2024年02月12日
    浏览(50)
  • 动态创建xxl-job任务

    1.需求背景:微信小程序秒杀模块有个订阅功能,当用户点击完订阅后,要在活动开始的前10分钟调用微信接口发送订阅消息给用户 2.思路:本地创建秒杀订阅表,当用户添加或者取消时对应表中数据的增删,添加数据时动态创建一条xxljob的定时任务,取消时删除它 xxl-job有两种创建任务

    2024年02月12日
    浏览(42)
  • STM32 实现简单定时任务调度器,动态创建任务,两种思路实现流水灯

    代码实现和硬件没关系,所以并不限于STM32,Arduino 之类的其他地方也能用,只要有一个能获取时间的函数就行,或者说,只要有一个会随着时间自动增加的变量就行,时间单位无所谓,所以确实想的话,拿到电脑上也能用。后面会用跑马灯程序来说明定时任务的玩法,可以直

    2024年02月10日
    浏览(38)
  • 理解和创建Windows和Linux下的动态和静态库区别

    在计算机编程的世界中,库是一个非常重要的改变。它的出现提供了一种共享和重用代码的可能性,复杂的程序因为动态库的出现而变得简洁和方便。然而,库并不是单一的:它们可以是动态的,也可以是静态的,每一种类型都有其使用场景。在本文中,我们将深入探讨动态

    2024年02月08日
    浏览(36)
  • 【看表情包学Linux】软硬链接 | 软连接数 | 创建软硬链接 | 动静态库 | 生成静态库 | 生成动态库

       🤣  爆笑 教程  👉 《看表情包学Linux》👈   猛戳订阅     🔥 💭 写在前面: 上一章我们讲解了 inode,为文件系统收了尾,这几章我们充分地讲解完了文件系统的知识点,现在我们开始开始学习软硬链接了。如果没有文件系统的铺垫,想直接理解软硬链接难免有些困

    2024年02月14日
    浏览(48)
  • Spring Boot集成Quartz实现定时任务的动态创建、启动、暂停、恢复、删除

    一、整个 Quartz 的代码流程基本基本如下: 首先需要创建我们的任务(Job),比如取消订单、定时发送短信邮件之类的,这是我们的任务主体,也是写业务逻辑的地方。 创建任务调度器(Scheduler),这是用来调度任务的,主要用于启动、停止、暂停、恢复等操作,也就是那几个api的

    2024年02月11日
    浏览(43)
  • FreeRTOS任务调度与任务切换 | FreeRTOS八

    目录 说明: 一、任务调度器 1.1、开启任务调度器函数 1.2、任务调度器实现步骤 1.3、xPortStartScheduler()函数 二、启动一个任务 2.1、prvStartFirstTask()函数 2.2、vPortSVCHandler()函数 三、任务切换 3.1、任务切换触发途径 3.2、PendSV中断触发任务切换步骤 关于内容: 1)以下内容多为概

    2023年04月15日
    浏览(35)
  • 设计模式 代理模式(静态代理 动态代理) 与 Spring Aop源码分析 具体是如何创建Aop代理的

    代理模式是一种结构型设计模式,它通过创建一个代理对象来控制对真实对象的访问。这种模式可以用于提供额外的功能操作,或者扩展目标对象的功能。 在代理模式中,代理对象与真实对象实现相同的接口,以便在任何地方都可以使用相同的接口来调用真实对象的方法。这

    2024年01月20日
    浏览(44)
  • 【Freertos基础入门】freertos任务的优先级

    本系列基于 stm32 系列单片机来使用freerots 任务管理是实时操作系统(RTOS)的核心功能之一,它允许开发者以并发的方式组织和管理多个任务。FreeRTOS 是一个流行的开源RTOS,它提供了强大的任务管理功能,让开发者能够轻松创建和控制任务。本文将介绍 FreeRTOS 的任务管理功能

    2024年02月13日
    浏览(35)
  • Netplan使用(高版本Ubuntu静态/动态IP设置方法)

    NetworkManager and netplan Ubuntu 18.04开始,Ubuntu和Debian移除了以前的 ifup/ifdown 命令和/etc/network/interfaces配置文件,转而使用 ip link set 或者 /etc/netplan/01-netcfg.yaml 模板和 sudo netplan apply 命令实现网络管理。 Netplan 是抽象网络配置描述器,用于配置 Linux 网络。 通过 netplan 命令,你只需用

    2024年01月16日
    浏览(46)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包