Выполнение void loop() без подключения к wifi и mqtt

Спасибо всем кто помог, FreeRTOS реально очень крутая штука!
Для меня, как для нуба “не умеющего в код” настолько простое распараллеливание процессов очень удобный костыль.
Вопросы:

  1. В стандартном примере “блинк+аналогрид” размер стека для обоих задач стоит 128, но с таким размером esp32 в порт шлет кучу ошибок и происходит бесконечный и быстрый бутлуп. Где то прочитал, что нужно просто увеличить. Увеличил до 2048 и все заработало.
    Но почему так происходит? Это же стандартный пример (в котором уже были такие значения).
    Как правильно подобрать значение размера стека? Просто увеличивать пока esp32 не будет бутлупится, или еще запас какой-то предусмотреть?
  2. Где то на просторах прочитал, что delay() использовать ни в коем случае нельзя, а нужно использовать vTaskDelay(). Простой пример “блинк+аналогрид” работает и с vTaskDelay() и с delay(). Где подводные камни?

https://www.freertos.org/FAQMem.html#StackSize

While it is not easy to determine how much stack to allocate a task, the RTOS does provide functionality that allows a task’s stack size to be tuned taking a pragmatic trial and error approach; the uxTaskGetStackHighWaterMark() API function can be used to see how much stack has actually been used, allowing the stack size to be reduced if more was allocated than necessary, and the stack overflow detection features can be used to determine if a stack is too small. In addition, the stack usages of all the RTOS tasks can be viewed at once using the uxTaskGetSystemState() API function, or one of the numerous FreeRTOS aware IDE plug-ins.

Потому что минимальный размер стека 1024

а) delay() - чисто ардуиновская функция б) vTaskDelay() - функция FreeRTOS. Первая замораживает все, вторая замораживает только задачу, в которой была вызвана

1 лайк

Сам не задумывался о делеях, но есть повод найти разницу:

esp32-hal-misc.c

void delay(uint32_t ms)
{
    vTaskDelay(ms / portTICK_PERIOD_MS);
}

delay сразу в ms пересчитывает, а так - пофиг.

2 лайка

:wink: Людям надо верить! (с). Я же написал - можно скока угодно!
Я с 2016 года зарабатывал репутацию участника форума, который не врёт… практически никогда.
И где результат? (вопрос - риторический)

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

1 лайк

Это да … тока соберёшься разбогатеть, так то трусы порвутся, то сахар закончится :frowning:

2 лайка

Счастливый человек! Радостно вбегает на поле, по колено в траве, совершенно не ведая, сколько там граблей на квадратный метр.

Я Вам одну умную вещь скажу, тока Вы ведь всё равно проигнорируете: «Говорить «абракадабра», не имея волшебной палочки – абсолютно бесполезно» :frowning:

priority inheritance … брр

не, ну один раз то было, помнишь про 3000 литров самогона? )))

поэтому сахар и трусы надо брать упаковками…тогда можно хоть как-то планировать бюджет…ну или в сакле как у меня жить…

Объясните, пожалуйста такое поведение программы:
После создания задачи для подключения mqtt, esp32 ребутится с ошибкой сторожевого таймера. Если в задачу добавить delay(1000), то все работает нормально (пока).
Объясните, почему так происходит?
Я правильно понимаю, это происходит из-за очень быстрого выполнения этой задачи и она каким-то образом зависает.

Если создать задачу, с пустым блоком for (;;), то происходит то же самое, пока не добавишь delay().

Код:

void TaskMQTT(void* pvParameters) 
{
  (void)pvParameters;
  client.setServer(mqttServer, mqttPort);
  for (;;)  
  {
    while (!client.connected()) {
      Serial.println("Connecting to MQTT...");

      if (client.connect("ESP32Client", mqttUser, mqttPassword)) {

        Serial.println("connected");

      } else {
        Serial.print("failed with state ");
        Serial.print(client.state());
        vTaskDelay(2000 / portTICK_PERIOD_MS);  // wait
      }
    }
  }
}

Ошибка:

E (7600) task_wdt: Task watchdog got triggered. The following tasks did not reset the watchdog in time:

E (7600) task_wdt: - IDLE (CPU 0)

E (7600) task_wdt: Tasks currently running:

E (7600) task_wdt: CPU 0: WIFI

E (7600) task_wdt: CPU 1: MQTT

E (7600) task_wdt: Aborting.

abort() was called at PC 0x400deb8d on core 0
Backtrace: 0x40083695:0x3ffbec0c |<-CORRUPTED




ELF file SHA256: acda321488d3e2a6

Rebooting...
ets Jun  8 2016 00:22:57
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:1

load:0x3fff0030,len:1344

load:0x40078000,len:13836

load:0x40080400,len:3608

entry 0x400805f0

потому что так работает сторожевой таймер ЕСП

Адрес исполняемой инструкции в коде должен меняться. Если адрес застывает более чем на полсекунды (точно не помню время) на одном месте - система думает что код завис и делает резет.

А так вообще бывает ???

Kaka:   B Кака

Ну если глубже копнуть, то адрес то меняется - запись точно происходит

to be honest (по честноку, так сказать) - я не знаю точно, как оно работает.
Но принцип именно такой - если прога более ХХХ мс стоит на месте - запускается ватчдог…

Хотя нет, наверно я все-таки фигню написал. В первом случае у ТС цикл совсем не пустой …

Если XXX мс не происходит сброса подсчета этих самых мс, то стартует ватчдог

это-то понятно. Но вот кто этот сброс делает? В явном виде его в коде нет.

В AVR надо вставлять команду в критических местах - Ñèñòåìà êîìàíä ìèêðîêîíòðîëëåðà avr Êîìàíäà WDR