Почему я получаю эту ошибку: причина исключения отладки: сработала точка наблюдения стека канарейки (задача 1) в ESP32 с помощью программы FreeRTOS?

Я получаю эту ошибку при запуске программы FreeRTOS на моем ESP32 с помощью arduino ide. Я не понимаю, почему это происходит, потому что эта же программа работает на arduino Uno без ошибок:

Guru Meditation Error: Core  0 panic'ed (Unhandled debug exception). 
Debug exception reason: Stack canary watchpoint triggered (task1) 
Core  0 register dump:
PC      : 0x40088a4f  PS      : 0x00060636  A0      : 0x800d3155  A1      : 0x3ffb9130  
A2      : 0x3ffb8eb4  A3      : 0xffffffff  A4      : 0x00060620  A5      : 0x00060623  
A6      : 0x00060623  A7      : 0x00000001  A8      : 0x00000001  A9      : 0x00000000  
A10     : 0x00060623  A11     : 0x00000000  A12     : 0x00000000  A13     : 0x00000000  
A14     : 0x007bee88  A15     : 0x003fffff  SAR     : 0x00000000  EXCCAUSE: 0x00000001  
EXCVADDR: 0x00000000  LBEG    : 0x00000000  LEND    : 0x00000000  LCOUNT  : 0x00000000

Это код, который я использую:

//#include <Arduino_FreeRTOS.h>
//Перегрузка происходит, если xTaskGetTickCount – lastTickCount (первый параметр для vTaskDelayUntil) >= период в тиках

void task1(void *pvParameters);
void task2(void *pvParameters);
void task3(void *pvParameters);

void setup() {
  
  Serial.begin(115200);

  //Создаем задачи
//xTaskCreate(Функция задачи, Имя задачи, , Параметр задачи, Приоритет задачи, );
  Serial.println("111111");   
  xTaskCreate(task1, "task1", 512, NULL, 1, NULL);
  Serial.println("222222");
  xTaskCreate(task2, "task2", 512, NULL, 2, NULL);
  xTaskCreate(task3, "task3", 512, NULL, 3, NULL);
  //vTaskStartScheduler();

}

void loop() {}

void task1(void *pvParameters) {

  (void) pvParameters;
  TickType_t waketime, period = 1000 / portTICK_PERIOD_MS;

  waketime = xTaskGetTickCount();

  while(1){

    Serial.println('M'); // Это происходит почти сразу, поэтому нам нужно добавить искусственную задержку, а для имитации выполнения задачи в течение нескольких мс, это служит только уведомлением о том, что задача запущена
    vTaskDelay(10);
    if(xTaskGetTickCount() - waketime >= period) 
      Serial.println("Overload in task 1");

    vTaskDelayUntil(&waketime, period);
  
  }

}

void task2(void *pvParameters) {

  (void) pvParameters;
  TickType_t waketime, period = 1000 / portTICK_PERIOD_MS;

  waketime = xTaskGetTickCount();

  while(1) {

    Serial.println('E'); // Это происходит почти сразу, поэтому нам нужно добавить искусственную задержку, а для имитации выполнения задачи в течение нескольких мс, это служит только уведомлением о том, что задача запущена
    vTaskDelay(10);
    if(xTaskGetTickCount() - waketime >= period) Serial.println("Overload in task 2");
    vTaskDelayUntil(&waketime, period);
  
  }

}

void task3(void *pvParameters) {

  (void) pvParameters;
  TickType_t waketime, period = 1000 / portTICK_PERIOD_MS;

  waketime = xTaskGetTickCount();

  while(1) {

    Serial.println('S'); // Это происходит почти сразу, поэтому нам нужно добавить искусственную задержку, а для имитации выполнения задачи в течение нескольких мс, это служит только уведомлением о том, что задача запущена
    vTaskDelay(10);
    if(xTaskGetTickCount() - waketime >= period) Serial.println("Overload in task 3");
    vTaskDelayUntil(&waketime, period);
  
  }

}

Я попытался увеличить память стека задач в xtaskcreate, и возникла та же ошибка, хотя, когда я увеличил ее до 1024, в последовательном мониторе ничего не отображается. Эта же программа безупречно работает на arduino uno и raspberry pi pico. Я также пытался изменить период задач и время их выполнения, что является задержкой, и это все еще не работает

, 👍0


1 ответ


Лучший ответ:

0

хотя, когда я увеличил его до 1024, в последовательном мониторе ничего не отображается.

Если вы ничего не сделаете с вашим кодом, кроме использования 4096 для размера стека, он будет печатать что-то последовательное.

rst:0x1 (POWERON_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:1
load:0x3fff0030,len:1344
load:0x40078000,len:13864
load:0x40080400,len:3608
entry 0x400805f0
111111
222222M

E
S
S
E
M
S
ME

Я не скажу вам, что это правильно, но кажется совершенно очевидным, что вы не предоставили ему достаточно стека для работы.

С моими текущими настройками

Serial.println(configMINIMAL_STACK_SIZE);

выводит 828. Я не знаю, как именно интерпретировать это число. Но если бы я не нашел иного, я мог бы по умолчанию считать это требованием запуска задачи, которая не использует собственный стек (без локальных переменных, без вызова). Памяти esp32 кажутся достаточно большими, поэтому независимо от того, как вы их используете, не имеет смысла использовать такой минимум для нескольких задач. Я выбрал 4096 несколько произвольно. Я не утверждаю, что это хорошая ценность.

,