簡體   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