簡體   English   中英

ESP32 FreeRtos 隊列調用 [Guru Meditation Error: Core 0 panic'ed (LoadProhibited)]

[英]ESP32 FreeRtos Queue invokes [Guru Meditation Error: Core 0 panic'ed (LoadProhibited)]

在探索 ESP32 Wrover 模塊上的 FreeRtos 功能時,我遇到了一個非常奇怪的問題。 目前,我的程序中有兩個任務。 第一個任務將用於收集一些數據,第二個任務將專門用於將調試消息打印到串行監視器。 這些任務使用隊列來交換數據。 由於我想在系統中創建更多任務,因此數據收集器任務接收隊列作為參數結構的一部分。 這是我的問題:如果數據收集器任務只向隊列發送一條消息,程序就可以完美運行。 但是如果我試圖向隊列中添加另一條消息(如最后一段代碼所示),它會迫使 CPU 遇到“LoadProhibited”異常。 根據我在其他主題中的閱讀,這個問題通常是由於程序中某處訪問了 NULL 指針引起的。 但正如您在下面的代碼中看到的,我試圖通過在向隊列中添加任何內容之前檢查指針來添加一些保護。 我還嘗試提高任務的分配量 memory,並將這兩個任務固定到核心 1。我仍然得到相同的結果。 這是主要的:

static QueueHandle_t debugMsgQueue      = NULL;
static QueueHandle_t sensorDataBufQueue = NULL;

TaskHandle_t debugTaskHandle        = NULL;
TaskHandle_t sensorTaskHandle       = NULL;

uint32_t sensorTaskWatchdog;

ESP32Time rtc;

void StreamDebugger(void* pvParameters) {
char debugMsg[_debugDataLength];

while (1) {
    if (debugMsgQueue != NULL) {
        if (xQueueReceive(debugMsgQueue, (void*)debugMsg, portMAX_DELAY) == pdPASS) {
            Serial.print(debugMsg);
        }
    }
}
}

void setup(){

Serial.begin(115200);
EEPROM.begin(_eepromSize);

/*CREATING GLOBAL DATA BUFFERS*/
debugMsgQueue       = xQueueCreate(5, sizeof(char[_debugDataLength]));
sensorDataBufQueue  = xQueueCreate(2, sizeof(char*));

if (debugMsgQueue == NULL || sensorDataBufQueue == NULL) {
    Serial.print("\r\nCouldn't create dataBuffers. Aborting operation.");
}

BaseType_t xReturned;

/*DEBUG MESSAGE HANDLER TASK*/
xReturned = xTaskCreate(StreamDebugger, "DEBUG", 2048, NULL, 1, &debugTaskHandle);
if (xReturned != pdPASS) {
    Serial.print("\r\nCouldn't create DEBUGTASK. Aborting operation.");
}

/*MEASURMENT HANDLER TASK*/
const ReadSensorsParameters sensorTaskDescriptor{ &debugMsgQueue,&sensorDataBufQueue,&sensorTaskWatchdog,rtc};

xReturned = xTaskCreate(ReadSensors, "GETDATA", 4096, (void*)&sensorTaskDescriptor, 1, &sensorTaskHandle);
if (xReturned != pdPASS) {
    Serial.print("\r\nCouldn't create GETDATATASK. Aborting operation.");
}
}

void loop(){

}

這是傳感器數據收集器任務使用的結構:

typedef struct READSENTASKPARAMETERS {
QueueHandle_t* debugQueue;
QueueHandle_t* dataQueue;
uint32_t* watchdog;
ESP32Time &systemClock;
}ReadSensorsParameters;

這是數據收集器任務,有效的任務:

void ReadSensors(void* pvParameters) {
ReadSensorsParameters* handlers = (ReadSensorsParameters*) pvParameters;

char debugMsg[_debugDataLength];
char dataMsg[_msgDataMaxLength];

strcpy(debugMsg, "READSENSORTASK");
if (debugMsg != NULL && *handlers->debugQueue != NULL) {
    xQueueSend(*handlers->debugQueue, (void*)debugMsg, portMAX_DELAY);
}
vTaskDelete(NULL);
}

這是修改后的任務,由於某種原因根本不起作用:

void ReadSensors(void* pvParameters) {
ReadSensorsParameters* handlers = (ReadSensorsParameters*) pvParameters;

char debugMsg[_debugDataLength];
char dataMsg[_msgDataMaxLength];

strcpy(debugMsg, "READSENSORTASK");
if (debugMsg != NULL && *handlers->debugQueue != NULL) {
    xQueueSend(*handlers->debugQueue, (void*)debugMsg, portMAX_DELAY);
}
if (debugMsg != NULL && *handlers->debugQueue != NULL) {
    xQueueSend(*handlers->debugQueue, (void*)debugMsg, portMAX_DELAY);
}
vTaskDelete(NULL);
}

這是我收到的錯誤消息: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模式:DIO,時鍾div:1負載:0x3fff0018,len:4負載:0x3fff001c,len:1044負載:0x40078000,len:8896負載:0x40080400,len:5816條目0x400806ac READSENSORTASKGuru冥想錯誤:核心0恐慌(禁止加載)。 異常未處理。 核心 0 寄存器轉儲:PC:0x400d0e5c PS:0x00060d30 A0:0x800889dc A1:0x3ffb2f80
A2:0x00000000 A3:0x3f400fad A4:0x3ffc07b8 A5:0x3ffb8058
A6:0x00000000 A7:0x00000000 A8:0x800d0e5a A9:0x3ffb2f70
A10:0x3ffb2f8a A11:0x3f400fbc A12:0x000000ff A13:0x0000ff00
A14:0x00ff0000 A15:0xff000000 SAR:0x00000010 借口:0x0000001c
EXCVADDR:0x00000000 LBEG:0x4000142d LEND:0x4000143a LCOUNT:0xfffffff3

回溯:0x400d0e5c:0x3ffb2f80 0x400889d9:0x3ffb2fe0

有人有什么主意嗎?

解決了! 結果(經過幾個不眠之夜)

static const MyTaskParameters sensorTaskDescriptor{
    &debugMsgQueue,
    &sensorDataBufQueue,
    &sensorTaskWatchdog,
    rtc,
    &sensorTaskWatchdogSemaphore,
    &rtcSemaphore
};

必須聲明為 static 變量。 我認為發生的事情是,當創建 READSENSORTASK 時,它立即開始運行並能夠將數據放入 output 緩沖區。 在第一次上下文切換后,SETUP 任務被自動刪除,因此這個 sensorTaskDescriptor 變量也被刪除,這就是下一個消息放置調用 LoadProhibited 消息的原因。 對我來說仍然很奇怪的是,我試圖檢查所有指向指針的指針不是 NULL。我猜錯誤的調用是在 xQueueSend function 內部的某個地方。無論如何,我希望這個線程對某人有所幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM