ESP32学习笔记:双核

描述

今天我们来说说ESP32 for Arduino 的双核。

ESP32的双核

ESP32上是有两个核心的,配备了2个 Xtensa 32 位 LX6 微处理器:核心0和核心1,默认是运行在核心1的,我们可以在代码中创建一个任务在核心0上面运行,进行并行的多任务处理。

我们看一下官方的芯片资源框图,这里是有两个Core的:

微处理器

我们可以通过一个函数来识别代码在哪个内核中运行

xPortGetCoreID()

这个函数会返回运行的Core ID号。

我们通过以下代码测试一下

void setup() {
  Serial.begin(115200);
  Serial.print("setup() running on core ");
  Serial.println(xPortGetCoreID());
}

void loop() {
  Serial.print("loop() running on core ");
  Serial.println(xPortGetCoreID());
}

我们看一下打印的情况

微处理器

Arduino for ESP32是运行在FreeRTOS实时操作系统上的,我们的loop()函数就是内核1的一个任务,我们在创建任务的时候,可以指定运行在哪个核心。下面的需要一点FreeRTOS的基础,如果没接触的可以先自行了解一下,这里推荐野火的《FreeRTOS内核实现与应用开发实战指南》这本书,讲的非常棒!

新建任务

创建任务句柄

我们这里创建一个Task1

TaskHandle_t Task1;

创建任务

设置任务的执行函数,优先级,堆栈大小,运行在哪个内核等参数

xTaskCreatePinnedToCore(
      Task1code, /* Function to implement the task */
      "Task1", /* Name of the task */
      10000,  /* Stack size in words */
      NULL,  /* Task input parameter */
      0,  /* Priority of the task */
      &Task1,  /* Task handle. */
      0); /* Core where the task should run */

具体的任务函数

这里是一个无限循环,任务1的代码在这里实现,然后每隔一段时间片,就去执行当前更高优先级的任务。

Void Task1code( void * parameter) {
  for(;;) {
    Code for task 1 
    (...)
  }
}

任务删除

vTaskDelete(Task1);

多任务案例

下面的代码,我们以不同的时间让LED灯闪烁,然后Task1运行在core0,Task运行在core1。

/*
 *      Created on: 20220316      
 *      Author:     公众号:跳动的字节
 *      Function    12 ESP32的双核
 *      Version:    V1.0
 *
 *                        ,%%%%%%%%,
 *                      ,%%/%%%%/%%
 *                     ,%%%c''''J/%%%
 *           %.        %%%%/ o  o %%%
 *           `%%.      %%%%       |%%%
 *            `%%      `%%%%(__Y__)%%'
 *            //        ;%%%%`-/%%%'
 *            ((      /   `%%%%%%%'
 *                  .'           |
 *                 /          | |
 *               /          ) | |
 *                          /_ | |__
 *                (____________))))))) 攻城狮
 *
 */
 
TaskHandle_t Task1;
TaskHandle_t Task2;

// LED pins
const int led1 = 2;
const int led2 = 4;

void setup() {
  Serial.begin(115200); 
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);

  //create a task that will be executed in the Task1code() function, with priority 1 and executed on core 0
  xTaskCreatePinnedToCore(
                    Task1code,   /* Task function. */
                    "Task1",     /* name of task. */
                    10000,       /* Stack size of task */
                    NULL,        /* parameter of the task */
                    1,           /* priority of the task */
                    &Task1,      /* Task handle to keep track of created task */
                    0);          /* pin task to core 0 */                  
  delay(500); 

  //create a task that will be executed in the Task2code() function, with priority 1 and executed on core 1
  xTaskCreatePinnedToCore(
                    Task2code,   /* Task function. */
                    "Task2",     /* name of task. */
                    10000,       /* Stack size of task */
                    NULL,        /* parameter of the task */
                    1,           /* priority of the task */
                    &Task2,      /* Task handle to keep track of created task */
                    1);          /* pin task to core 1 */
    delay(500); 
}

//Task1code: blinks an LED every 1000 ms
void Task1code( void * pvParameters ){
  Serial.print("Task1 running on core ");
  Serial.println(xPortGetCoreID());

  for(;;){
    digitalWrite(led1, HIGH);
    delay(1000);
    digitalWrite(led1, LOW);
    delay(1000);
  } 
}

//Task2code: blinks an LED every 500 ms
void Task2code( void * pvParameters ){
  Serial.print("Task2 running on core ");
  Serial.println(xPortGetCoreID());

  for(;;){
    digitalWrite(led2, HIGH);
    delay(500);
    digitalWrite(led2, LOW);
    delay(500);
  }
}

void loop() {
  
}

实际效果

串口打印:

微处理器

硬件连接非常简单,IO2与IO4各接一个LED灯即可,我们看看效果:

微处理器

led1每1秒闪烁一次,led2每500ms闪烁一次,这样就是真正的两个内核同时运行两个不同的任务。

到这里,12篇基础教程已经讲完了,大家对ESP32也有所了解了,接下来我们讲进阶教程,开始玩起WiFi和蓝牙以及各种传感器以及屏幕等,有了WiFi,我们就可以与外界进行通信,能做一些超级好玩的项目。

感谢大家,关于ESP32的学习,希望大家Enjoy!

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分