(ESP32学习6)双核CPU的调用

本来之前从来没有用过双核做东西,但是突然意识到他好像是双核的,所以找了一些资料更第一篇双核的调用,还是挺有趣的

博文会持续更FreeRTOS与双核相关内容,这一章先做一件最简单的事情:在两个核上创建简单任务让他们跑起来

先看代码再讲解

#include <soc/soc.h> 
#include <soc/rtc_cntl_reg.h>
void Task1code( void *pvParameters );
void Task2code( void *pvParameters );
//wifi在core0,其他在core1;1为大核
void setup() {
  WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0);//关闭低电压检测,避免无限重启
  xTaskCreatePinnedToCore(Task1, "Task1", 10000, NULL, 1, NULL,  0);  //最后一个参数至关重要,决定这个任务创建在哪个核上.PRO_CPU 为 0, APP_CPU 为 1,或者 tskNO_AFFINITY 允许任务在两者上运行.
  xTaskCreatePinnedToCore(Task2, "Task2", 10000, NULL, 1, NULL,  1);//
  //实现任务的函数名称(task1);任务的任何名称(“ task1”等);分配给任务的堆栈大小,以字为单位;任务输入参数(可以为NULL);任务的优先级(0是最低优先级);任务句柄(可以为NULL);任务将运行的内核ID(0或1)
  Serial.begin(115200);
}
 
void loop() {
 
}
void Task1(void *pvParameters) {
  //在这里可以添加一些代码,这样的话这个任务执行时会先执行一次这里的内容(当然后面进入while循环之后不会再执行这部分了)
  while(1)
  {
    vTaskDelay(1000);
    Serial.print("PRO_CPU正在运行:");
    Serial.println(xPortGetCoreID());
  }
}
 
void Task2(void *pvParameters) {
  while(1)
  {
    vTaskDelay(1000);
     Serial.print("APP_CPU正在运行:");
    Serial.println(xPortGetCoreID());
 
  }
}

先讲几个这里不得不知道的重点,其他的在后面的博文中会持续更

1.首先看上面的xTaskCreatePinnedToCore 这个函数

这个函数就是在创建任务,而传入的参数上面的代码注释里面已经有了,最最注意的是最后一个参数,他有几种选择,esp32 的 FreeRTOS 是设计运行在单核上. 但 ESP32 是双核的,包含 Protocol CPU (称为 CPU 0 或PRO_CPU)和 Application CPU (称为 CPU 1 或 APP_CPU). 这两个核实际上是相同的,并且共享相同的内存. 这允许任务在两个核之间交替运行,而这里最后一个参数是 xCoreID.此参数指定任务运行在那个核上. PRO_CPU 为 0, APP_CPU 为 1,或者 tskNO_AFFINITY 允许任务在两者上运行.

2.还有几个我在官方找到的应该注意的点

1.为了避免esp32 的FreeRTOS 调度器将在 Ready 状态下具有相同优先级的多个任务之间实施循环调度时跳过任务.我们最好是不要让自己的多个任务有相同的优先级

2.挂起调度器:在 ESP-IDF 中挂起调度器 FreeRTOS 只会影响调用核上的调度器.换句话说,在 PRO_CPU 上调用 vTaskSuspendAll() 不会阻止 APP_CPU 进行调度,反之亦然.使用临界区或信号量代替同时访问保护。他的意思应该就是两个核的任务调度各自独立,具有独立性。

3.滴答中断同步:PRO_CPU 和 APP_CPU 的滴答中断不同步. 不要期望使用 vTaskDelay() 或 vTaskDelayUntil() 作为在两个核之间同步任务执行的准确方法. 使用计数信号量,因为它们的上下文切换不会因抢占而与滴答中断相关联. 这个的意思我觉得应该是告诉我们,不要指望通过延时(这个延时会把CPU让出来让给目前合适的优先级的任务去运行)来让两个CPU长时间精确同步,简而言之,可能是这张情况,比如你分别在两个核创建了一个任务,都是每隔1000ms让LED灯翻转一次,那么开始的时候还能看到两个灯的同步闪烁,但是时间一积累就会发现由于滴答中断不同步而导致两个核运行节奏不一样,开始交替闪烁

4.vTaskDelete() 仍然是任务删除函数

5.浮点运算:ESP32 支持单精度浮点运算 (float) 的硬件加速.然而,硬件加速的使用导致 ESP-IDF FreeRTOS 中的一些行为限制.因此,如果没有这样做,使用 float 的任务将自动固定到核.此外, float 不能用于中断服务程序.

6.临界区和禁用中断:在 ESP-IDF FreeRTOS 中,临界区是使用互斥锁实现的.进入临界区涉及获取互斥锁,然后禁用调度器和调用核的中断.然而,另一个核不受影响.如果另一个核尝试使用相同的互斥锁,它将自旋直到调用核通过退出临界区释放互斥锁。这个是锁以及一些信号量之类的内容后面还会更用法,其目的就是资源分配,大家应该有死锁的基本概念,就是两个任务各自占有对方想要的资源但是两个任务一不愿意放手目前手中的资源,二想抢夺对方手里的资源好让自己运行下去而导致两个任务都停滞的情况,这些东西存在的目地基本就是避免这些情况的,合理高效分配内部资源用的

最后

好了后面会继续更一些双核以及FreeRTOS的资料,其实开始是想单独分一个专栏来写的,但是这样比较麻烦所以还是在ESP专栏里面,另外挺开心的我都有几个粉丝了。

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值