Спасибо всем кто помог, FreeRTOS реально очень крутая штука!
Для меня, как для нуба “не умеющего в код” настолько простое распараллеливание процессов очень удобный костыль.
Вопросы:
В стандартном примере “блинк+аналогрид” размер стека для обоих задач стоит 128, но с таким размером esp32 в порт шлет кучу ошибок и происходит бесконечный и быстрый бутлуп. Где то прочитал, что нужно просто увеличить. Увеличил до 2048 и все заработало.
Но почему так происходит? Это же стандартный пример (в котором уже были такие значения).
Как правильно подобрать значение размера стека? Просто увеличивать пока esp32 не будет бутлупится, или еще запас какой-то предусмотреть?
Где то на просторах прочитал, что delay() использовать ни в коем случае нельзя, а нужно использовать vTaskDelay(). Простой пример “блинк+аналогрид” работает и с vTaskDelay() и с delay(). Где подводные камни?
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.
а) delay() - чисто ардуиновская функция б) vTaskDelay() - функция FreeRTOS. Первая замораживает все, вторая замораживает только задачу, в которой была вызвана
Людям надо верить! (с). Я же написал - можно скока угодно!
Я с 2016 года зарабатывал репутацию участника форума, который не врёт… практически никогда.
И где результат? (вопрос - риторический)
Объясните, пожалуйста такое поведение программы:
После создания задачи для подключения 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
Адрес исполняемой инструкции в коде должен меняться. Если адрес застывает более чем на полсекунды (точно не помню время) на одном месте - система думает что код завис и делает резет.
to be honest (по честноку, так сказать) - я не знаю точно, как оно работает.
Но принцип именно такой - если прога более ХХХ мс стоит на месте - запускается ватчдог…
Хотя нет, наверно я все-таки фигню написал. В первом случае у ТС цикл совсем не пустой …