今天我们来说说ESP32 for Arduino 的双核。
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!
全部0条评论
快来发表一下你的评论吧 !