0°

(十三)ESP32:获取任务执行核心

这篇文章的目的是解释如何检查某个FreeRTOS任务正在执行的ESP32的哪个核心。

介绍

这篇文章的目的是解释如何检查某个FreeRTOS任务正在执行的ESP32的哪个核心。

ESP32的一个特点是它有2个Tensilica LX6核心 [1],允许我们在两个CPU中运行任务。请注意,当我们使用xTaskCreate函数创建任务时,我们没有指定任何特定的核心来运行它。因此,FreeRTOS将在免费的核心上运行任务[2]。

正如我们将在后面的示例中看到的,我们可以使用xTaskCreatePinnedToCore 函数将任务关联到特定的核心 [3]。

现在,我们将解释如何检查任务正在运行的核心,特别是,我们将分析它的设置,主循环和启动的任务。为此,我们将使用xPortGetCoreID函数。

代码

像之前一样,setup函数中的第一个代码将用于打开串行连接,设置好波特率,以便我们打印有关正在运行任务的内核的信息。

之后,我们直接获取有关运行安装功能的核心的信息。如前所述,我们将使用xPortGetCoreID函数来获取此信息。请注意,此函数不接收任何参数[4],因此需要在任务内部使用它来获取有关正在运行的核心的信息:

Serial.begin(112500);
delay(1000);
 
Serial.print("Setup: Executing on core ");
Serial.println(xPortGetCoreID());

在此之后,我们将使用xTaskCreate函数启动一个新任务,这样我们就可以分析它将开始运行的核心。

我们稍后将分析用于实现此功能的代码。现在,我们将通过执行一个小延迟来完成设置功能。这样,无论分配给哪个核心,我们都将确保新创建的任务将运行。

请注意,此行为是预期的,因为ESP32为Arduino的延迟实现使用FreeRTOS的vTaskDelay 功能,这里可以看出。因此,这意味着任务将在延迟时间[5]期间被阻止,并且调度程序可以将CPU归因于其他免费任务。然而,这仅在新创建的任务被分配到执行设置功能的同一核心时才相关:

xTaskCreate(
                    genericTask,       /* Task function. */
                    "genericTask",     /* String with name of task. */
                    10000,             /* Stack size in words. */
                    NULL,              /* Parameter passed as input of the task */
                    2,                 /* Priority of the task. */
                    NULL);             /* Task handle. */
delay(2000);

在设置功能之后,我们将指定主循环。它只包含对xPortGetCoreID函数的调用,因此我们可以知道它正在运行的核心:

void loop() {
  Serial.print("Main Loop: Executing on core ");
  Serial.println(xPortGetCoreID());
  delay(1000);
}

最后,我们将指定我们在setup函数上启动的任务的代码。这也将非常简单并且对应于相同功能的执行,因此我们可以获得运行它的核心。

查看下面的完整源代码:

void setup() {
 
  Serial.begin(112500);
  delay(1000);
 
  Serial.print("Setup: Executing on core ");
  Serial.println(xPortGetCoreID());
 
  xTaskCreate(
                    genericTask,       /* Task function. */
                    "genericTask",     /* String with name of task. */
                    10000,             /* Stack size in words. */
                    NULL,              /* Parameter passed as input of the task */
                    2,                 /* Priority of the task. */
                    NULL);             /* Task handle. */
 delay(2000); 
 
}
 
void loop() {
  Serial.print("Main Loop: Executing on core ");
  Serial.println(xPortGetCoreID());
  delay(1000);
}
 
void genericTask( void * parameter ){
    Serial.print("Created task: Executing on core ");
    Serial.println(xPortGetCoreID());
    vTaskDelete(NULL);
}

测试结果

要测试结果,只需将程序上传到ESP32上面,然后打开串行监视器。你应该得到类似于图1的输出:

ESP32:获取任务执行核心

图1 – 获取每个任务的ESP32执行核心的程序输出

请注意这两个设置和主循环功能核心1。这里可以看出,新创建的任务已分配给核心0。

「点点赞赏,手留余香」

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