FreeRTOS(ESP32)学习日记005-使用ESP32双核

本文介绍了ESP32的双核处理器架构,特别是其主核和应用核的区别,以及如何在FreeRTOS环境中创建和调度任务。通过实例代码展示了如何使用xPortGetCoreID监控任务在不同核心上的运行情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

005如何使用ESP32双核

以下为作者本人关于esp32的FreeRtos学习笔记,供自己学习参考。
平台:Ubuntu 20.04 LTS + Arduino IDE

window平台上的代码完全一致,因为我自己电脑上的win11系统arduino编译速度过于缓慢(无法忍受(* ̄︿ ̄)),遂转到ubuntu。

今天的任务比较轻松,故笔记比较简陋,但是看懂应该不成问题(๑•̀ㅂ•́)و✧

首先来看一段废话(bushi)稍微了解一下它的双核

ESP32是一款功能强大的微控制器,其最大的特点之一是采用了双核处理器架构。这种架构使得ESP32能够同时执行多个任务,从而提高了系统的整体性能和效率。

  • 一、双核架构概述
    ESP32的双核处理器基于Tensilica LX6微处理器架构,由两个独立的32位核心组成:主核(Pro-CPU)和应用核(App-CPU)。

  • 二、主核(Pro-CPU)
    主核是ESP32的高性能核心,基于RISC-V指令集架构。它具有较高的时钟频率和强大的计算能力,适合执行复杂和计算密集型的任务。在操作系统中,主核通常负责运行主线程、管理内存和处理器资源,以及执行那些需要高性能的任务。

  • 三、应用核(App-CPU)
    应用核是ESP32的低功耗核心,同样基于RISC-V指令集架构。相比于主核,应用核的时钟频率较低,但功耗也相应地减少,使其非常适合执行轻量级和实时性要求较高的任务。应用核常用于运行应用程序的次要线程、处理中断和实时事件,以及执行一些低功耗模式下的任务。

  • 四、核心间的通信与协作
    ESP32的两个核心之间通过共享内存和中断机制进行通信和协作。它们可以共同访问同一块内存空间,从而方便数据在两个核心之间的传输和共享。此外,ESP32的中断控制器允许一个核心向另一个核心发送中断信号,以便及时通知和响应特定的事件或任务。

  • 五、操作系统的调度与任务分配
    ESP32通常搭载FreeRTOS等实时操作系统,操作系统的调度器负责在两个核心之间进行任务的分配和调度。它会根据任务的重要性和优先级,将任务分配给最适合执行的核心。这种灵活的调度机制使得ESP32能够同时处理多个任务,提高系统的整体性能和效率。

  • 六、总结
    ESP32的双核处理器架构为其在物联网、智能家居、智能城市等领域中的广泛应用提供了强大的支持。无论是需要高性能的计算任务,还是要求实时响应的轻量级任务,ESP32都能够通过其双核处理器实现高效的处理和执行。通过合理利用主核和应用核的特点和优势,以及操作系统的任务调度机制,开发者可以充分发挥ESP32双核处理器的潜力,创造出更多创新的应用。


/*

程序: 多核多任务
API

xPortGetCoreID() 获取当前任务运行的核心

xTaskCreate() 由系统选择运行核心,优先选择0

xTaskCreatePinnedToCore() 指派任何给指定核心

*/

void taskA(void *ptParam) {

	while (1) {

		Serial.println(xPortGetCoreID());

		}

}

  

void setup() {

	// put your setup code here, to run once:

	Serial.begin(115200);

	xTaskCreatePinnedToCore(taskA, "Task A", 1024 * 4, NULL, 1, NULL,0);

  

}

  

void loop() {

  

	Serial.println(xPortGetCoreID());

  

}

这段代码是一个简单的FreeRTOS任务示例,它使用Arduino平台。下面是对代码的详细解读和笔记:

taskA函数

功能: 这是一个FreeRTOS任务,它的功能是不断地通过串行端口打印当前运行的核心ID。

void taskA(void *ptParam) {      
	while (1) {
		Serial.println(xPortGetCoreID());      
		}
}

细节分析:

  • void taskA(void *ptParam): 这是FreeRTOS任务的函数定义,ptParam是一个指向传递给任务的参数的指针,但在这个例子中,参数没有被使用。
  • while (1): 这是一个无限循环,确保任务不断地运行。
  • Serial.println(xPortGetCoreID()): 这行代码打印当前运行的核心ID。xPortGetCoreID()是FreeRTOS的API,用于获取当前执行代码的核心ID。

setup函数

功能: setup函数在Arduino程序中仅执行一次,用于初始化设置。

void setup() {      
	// put your setup code here, to run once:
	Serial.begin(115200);
	xTaskCreatePinnedToCore(taskA, "Task A", 1024 * 4, NULL, 1, NULL, 0);  
}

细节分析:

  • Serial.begin(115200): 初始化串行通信,设置波特率为115200。
  • xTaskCreatePinnedToCore(taskA, "Task A", 1024 * 4, NULL, 1, NULL, 0): 创建一个新的FreeRTOS任务,并将其绑定到特定的核心上。
    • taskA: 要执行的任务函数。
    • "Task A": 任务的名称。
    • 1024 * 4: 任务堆栈的大小,这里是4KB。
    • NULL: 任务传递给任务的参数,这里没有传递参数。
    • 1: 任务的优先级。
    • NULL: 任务句柄,如果不需要后续管理任务,可以设置为NULL。
    • 0: 任务的绑定核心ID,0通常表示第一个核心。

loop函数

功能: 在Arduino中,loop函数在setup函数执行后反复执行,用于主循环代码。

void loop() 
{      
	Serial.println(xPortGetCoreID()); 
	}

细节分析:

  • Serial.println(xPortGetCoreID()): 在主循环中,代码同样打印当前运行的核心ID。这意味着,如果taskA任务也在相同的核心上执行,那么loop函数和taskA任务可能会交替执行,并交替打印核心ID。

总结

  • 代码展示了如何在Arduino平台上使用FreeRTOS创建并运行一个简单的任务。
  • 通过串行端口,可以观察到任务是在哪个核心上执行的。
  • 需要注意的是,xPortGetCoreID()返回的核心ID取决于FreeRTOS的配置和硬件平台,所以具体的ID值可能会有所不同。本例中使用ESP32S3的为双核,但是如果使用ESP32C系列就只有一个核心,不支持本节的操作。
  • 实际效果可能受到硬件和FreeRTOS配置的影响。

笔记参考B站大佬 孤独的二进制 的视频教程ESP32 FreeRTOS

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值