繁体   English   中英

如何在 ESP32 的第二个内核上初始化队列?

[英]How to initialize a Queue on a second core of an ESP32?

目前我正在开发一个演示程序,以更好地了解如何使用 FreeRTOS。 因此,我想尝试在我的第二个核心(core1)上初始化一个队列。 初始化后,我想以 1 秒的间隔向它添加一些东西,每当什么都没发生时,我想检查我的队列并关闭它的内容。 与该队列相关的所有内容都应该在第二个核心上运行。 原因是我以前在主核心上运行的 Web 服务器上工作。 我未来的队列应该在第二个核心上并行工作。

这是我当前的演示程序:

#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "freertos/timers.h"
#include "esp_system.h"

    xQueueHandle queue;



void taskqueuecreator()
{
 queue = xQueueCreate(15, sizeof(int));
 printf("Queue created on core %d!\n", xPortGetCoreID());

 vTaskDelete(NULL);

}

void addspitoqueue(){

    while(true){
        printf("added Item to Queue");
        xQueueSend(queue, 1, 1000 / portTICK_PERIOD_MS);
        vTaskDelay(1000 / portTICK_PERIOD_MS);
    }
}



void TimerStateMachine(int Methodnum){

    switch(Methodnum){
        case 1:
        printf("SPI communication with arm happens here %d \n",xPortGetCoreID());
        break;

        case 2:
        printf("something else is about to happen here");
        break;


        return;
    }



}

void queueloop(){
     int receivedint = 0; //1 = spi communication mit Arm
    while(true){
        printf("in queueloop");
        if(xQueueReceive(queue, &receivedint, 5000)){
        TimerStateMachine(receivedint);
        }
    }
}



void app_main(void)
{




xTaskCreatePinnedToCore(&taskqueuecreator, "create queue", 4*1024, NULL, 2, NULL, 1 );
printf("\n task done\n");
xTaskCreatePinnedToCore(&addspitoqueue, "create spitask", 4*1024, NULL, 2, NULL, 1);
printf("\n task done part 2\n");
xTaskCreatePinnedToCore(&queueloop, "queue loop", 4*1024, NULL, 2, NULL, 1);
printf("\n task done part 3\n");

}

执行它时,我收到以下错误消息,然后重置:

2019 年 7 月 29 日 12:21:46

rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT) configsip: 0, SPIWP:0xee clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00 mode:DIO,clock div: 2 加载:0x3fff0030,len:7028 加载:0x40078000,len:14308 加载:0x40080400,len:3716 0x40080400:_init at??:?

条目 0x40080680 I (27) boot: ESP-IDF v4.3.1-dirty 2nd stage bootloader I (27) boot: 编译时间 10:17:24 I (27) boot: 芯片版本: 3 I (30) boot_comm: 芯片版本: 3,分钟。 bootloader 芯片版本:0 I (38) boot.esp32: SPI Speed: 40MHz I (42) boot.esp32: SPI Mode: DIO I (47) boot.esp32: SPI Flash Size: 8MB I (51) boot: 启用 RNG早期熵源... I(57)引导:分区表:I(60)引导:## Label 使用类型 ST 偏移长度 I(68)引导:0 nvs WiFi 数据
01 02 00009000 00006000 I (75) 启动:1 phy_init RF 数据
01 01 0000f000 00001000 I (82) boot: 2 factory factory app
00 00 00010000 00100000 I (90) boot: 分区表结束 I (94) boot_comm: 芯片修订版: 3, min. (应用芯片修订:0 I (101) esp_image: 段 0: paddr=00010020 vaddr=3f400020 size=06964h (26980) map I (120) esp_image: 段 1: paddr=0001004600 vaddr=0001004600 IDDr=3dr=3 (124) esp_image: segment 2: paddr=00019270 vaddr=40080000 size=06da8h ( 28072) load I (138) esp_image: segment 3: paddr=00020020 vaddr=400d0020 size=135bch ( 79292) map I (167) esp_image: segment 4: paddr=000335e4 vaddr=40086da8 size=03fb0h (16304) load I (174) esp_image: segment 5: paddr=0003759c vaddr=50000000 size=00010h (16) load I (180) boot: 从偏移量 0x10000 的分区加载应用程序我(180)启动:禁用RNG早期熵源......我(196)cpu_start:Pro cpu up。 I (196) cpu_start: Starting app cpu, entry point is 0x40080ffc 0x40080ffc: call_start_cpu1 at C:/Users/Student/esp/esp-idf/components/esp_system/port/cpu_start.c:141

I (183) cpu_start: App cpu up。 i (210) cpu_start: Pro cpu 启动用户代码 i (210) cpu_start: cpu freq: 160000000 i (210) cpu_start: 应用信息: i (215) cpu_start: 项目名称: main i (220) cpu_start: App版本: 1 I (224) cpu_start: 编译时间: Jan 3 2022 15:11:19 I (230) cpu_start: ELF file SHA256: 65b119d32e9f73f6... I (236) cpu_start: ESP-IDF: v4.3.1-dirty I (242) heap_init:正在初始化。 可用于动态分配的 RAM: I (249) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM I (255) heap_init: At 3FFB31A8 len 0002CE58 (179 KiB): DRAM I (261) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM I (267) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM I (274) heap_init: At 4008AD58 len 000152A8 (84 KiB): IRAM I (281) spi_flash: 检测到的芯片:通用I (285) spi_flash: flash io: dio I (290) cpu_start: 在 PRO CPU 上启动调度程序。 I (0) cpu_start:在 APP CPU 上启动调度程序。

任务完成

在核心 1 上创建队列!

任务完成第二部分

大师冥想错误:核心 1 恐慌(负载禁止)。 异常未处理。

Core 1 register dump: PC: 0x4000c344 PS: 0x00060633 A0: 0x80085685 A1: 0x3ffb95e0 A2: 0x3ffaffa8 A3: 0x00000000 A4: 0x00000004 A5: 0x3ffaffa8 A6: 0x00000001 A7: 0x00000000 A8: 0x40000000 A9: 0x3ffb92a0 A10: 0x3ffb92c0 A11: 0x00000001 A12: 0x3ffb9524 A13:0x3ffaef6c A14:0x00000000 A15:0x00000001 SAR:0x00000008 EXCCAUSE:0x0000001c EXCVADDR:0x00000000 LBEG:0x400014fd LEND:0x4000150d LCOUNT:0xffff

Backtrace:0x4000c341:0x3ffb95e0 0x40085682:0x3ffb95f0 0x40085b0e:0x3ffb9610 0x400d40d0:0x3ffb9650 0x40087b39:0x3ffb9670 0x40085682: prvCopyDataToQueue at C:/Users/Student/esp/esp-idf/components/freertos/queue.c:2114

0x40085b0e: xQueueGenericSend 在 C:/Users/Student/esp/esp-idf/components/freertos/queue.c:804

0x400d40d0:在 C:\Users\Student\Projekte\sample_project\build/../main/main.c:30 处添加spitoqueue(鉴别器 1)

0x40087b39: vPortTaskWrapper 在 C:/Users/Student/esp/esp-idf/components/freertos/port/xtensa/port.c:168

ELF 文件 SHA256:65b119d32e9f73f6

正在重新启动...

我假设(但我不是 100% 确定)这是由这条线引起的

xQueueHandle 队列;

在核心 0 和这部分执行

while(true){ printf("added Item to Queue"); xQueueSend(queue, 1, 1000 / portTICK_PERIOD_MS); vTaskDelay(1000 / portTICK_PERIOD_MS); }

在核心 1 上执行。

如果是这样,任何人都可能知道如何解决该问题? 如果没有,有人知道出了什么问题吗?

提前致谢!

您无需假设问题出在哪里; 答案在您发布的回溯中。 异常发生在代码中的特定 function 调用期间:

0x400d40d0: addspitoqueue at C:\Users\Student\Projekte\sample_project\build/../main/main.c:30

您的 function addspitoqueue()是:

void addspitoqueue(){

    while(true){
        printf("added Item to Queue");
        xQueueSend(queue, 1, 1000 / portTICK_PERIOD_MS);
        vTaskDelay(1000 / portTICK_PERIOD_MS);
    }
}

具体来说,这条线导致了问题:

        xQueueSend(queue, 1, 1000 / portTICK_PERIOD_MS);

看一下xQueueSend()的定义:

 BaseType_t xQueueSend(
                            QueueHandle_t xQueue,
                            const void * pvItemToQueue,
                            TickType_t xTicksToWait
                         );

这意味着将指向 object 的指针放入队列中 - 而不是值。 它会将 object 复制到从您传递的地址开始的队列中 - 在这种情况下, 1 ,这肯定会导致崩溃。

您需要将值存储在int中(因为您将队列定义为sizeof(int)对象的队列),然后将指针传递给您存储它的位置。

例如:

static int value_to_queue;

void addspitoqueue(){

    while(true){
        printf("added Item to Queue");
        value_to_queue = 1;
        xQueueSend(queue, &value_to_queue, 1000 / portTICK_PERIOD_MS);
        vTaskDelay(1000 / portTICK_PERIOD_MS);
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM