目录
介绍
这篇文章的目的是解释如何检查某个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的输出:
图1 – 获取每个任务的ESP32执行核心的程序输出
请注意这两个设置和主循环功能核心1。这里可以看出,新创建的任务已分配给核心0。
挺好