0°

(十)ESP32 :创建FreeRTOS任务

这篇文章的目的是解释如何使用FreeRTOS函数启动任务。

介绍

这篇文章的目的是解释如何使用FreeRTOS函数启动任务。由于这将介绍一些复杂的概念,我们将从一个非常简单的示例开始,我们将创建两个任务,打印一些“Hello World”消息,然后删除它们。

对于我们将在本教程中使用的大多数功能,您可以在此处库文件的.h文件。看这篇教程之前也可以看一下之前的教程有关于FreeRTOS的任务介绍。

setup和loop程序

我们将首先打开串口,既在setup初始化函数设置好波特率,以便能够获得我们的测试程序的输出。这是Arduino的基本串口功能。

Serial.begin(112500);
delay(1000);

然后,我们将通过调用xTaskCreate函数来创建任务 。该函数的参数如下:

TaskCode:在这个参数中,我们需要传递一个指向将实现任务的函数的指针。我们将创建两个函数,TaskOneTaskTwo,我们将定义后者,并将在此参数中传递。

TaskName:字符串中任务的名称。我们将使用“TaskOne”和“TaskTwo”。

StackDepth:任务堆栈的大小,指定为数字字节。尽管可以进行一些计算,但没有简单的方法来确定任务的大小。在这个简单的例子中,我们将传递一个足够大的值。

更新:在原始帖子中,提到StackDepth是用单词指定的,就像在FreeRTOS xTaskCreate 页面中记录的那样。尽管如此,IDF的版本与原始实现不同,堆栈深度实际上以字节为单位指定。

参数:指向任务功能可以接收的参数的指针。它需要是类型(void *)。在这种情况下,为了简化代码,我们不会使用它,所以我们在参数中传递NULL。

优先级:任务的优先级。我们将以相同的优先级创建两个任务。

TaskHandle:返回一个句柄,可以在调用函数时用于后面的任务引用(例如,删除任务或更改其优先级)。另外,对于这个简单的例子,我们不打算使用它,因此它将为NULL。

此函数在成功时返回 pdPASS或可在此处看到的错误代码 。现在,我们将假设创建的任务没有任何问题,因此我们不会进行任何错误检查。当然,对于真实案例场景应用程序,我们需要这样做来确认任务是否已创建。

因此,请检查完整的设置功能,已经通过调用创建了两个不同的任务:

void setup() {
 
  Serial.begin(112500);
  delay(1000);
 
  xTaskCreate(
                    taskOne,          /* Task function. */
                    "TaskOne",        /* String with name of task. */
                    10000,            /* Stack size in bytes. */
                    NULL,             /* Parameter passed as input of the task */
                    1,                /* Priority of the task. */
                    NULL);            /* Task handle. */
 
  xTaskCreate(
                    taskTwo,          /* Task function. */
                    "TaskTwo",        /* String with name of task. */
                    10000,            /* Stack size in bytes. */
                    NULL,             /* Parameter passed as input of the task */
                    1,                /* Priority of the task. */
                    NULL);            /* Task handle. */
 
}

在主循环中,我们不会做任何事情,因为我们的任务将实现所有功能。所以我们只是延时:

void loop() {
   delay(1000);
}

任务功能

现在,我们只需要指定任务的功能。请记住,我们要创建一个由TaskOne函数实现的任务,以及由TaskTwo函数实现的其他任务

请注意,任务是使用常规函数实现的,它们只需要遵循预定义的函数原型。因此,它们必须返回void ,并且必须接收类型为(void *)的参数作为输入。查看下面的示例:

void taskOne( void * parameter )

需要考虑的一件非常重要的事情是该功能不应该返回值。因此,它们 必须不包含return语句或在代码结束前执行。相反,它们应该被明确删除。

要从自己的代码中删除任务,我们只需要调用vTaskDelete函数。该函数接收要删除的任务的句柄作为输入(记住前面提到的我们不打算使用的xTaskCreate的参数)。然而,如果我们传递NULL作为输入,调用任务将被删除,这是我们想要的,因为我们将从任务自己的代码中调用它:

 vTaskDelete(NULL); 

除了这些特殊性之外,我们将以非常简单的方式实现这两个功能。基本上,我们将做一个简单的循环,我们将从每个任务打印一个“Hello World”,并且在循环的所有迭代之后,我们将打印一条消息,说明任务将结束。

本教程的完整代码,同时实现我们的任务:

当前内容已被隐藏,您需要登录才能查看

运行结果

要运行代码,只需使用Arduino IDE将程序上传到ESP32板。您可以得到类似于图1的结果,同时将“Hello World”消息打印到串行控制台。最后,还会打印两个终止消息。

ESP32 Arduino:创建一个FreeRTOS任务

图1 – 程序的输出。

请注意,这两个任务都是并行运行的,这是每个任务的打印混合的方式。当然,每个任务的执行时间由RTOS调度程序决定。

「点点赞赏,手留余香」

    还没有人赞赏,快来当第一个赞赏的人吧!
0 条回复 A 作者 M 管理员
    所有的伟大,都源于一个勇敢的开始!
欢迎您,新朋友,感谢参与互动!欢迎您 {{author}},您在本站有{{commentsCount}}条评论