Watchdog и несколько задач

Тема в разделе "ESP8266, ESP32", создана пользователем ostrov, 3 сен 2022.

  1. ostrov

    ostrov Гуру

    Запускаю всего лишь еще одну задачу кроме loop(). В каждой задаче выполняется сброс каждую итерацию, внутри задач функции не зависают, лупы крутятся сотни и тысячи раз в секунду. Таймаут вачдога две минуты, по истечении этого времени случается ребут с мотивацией, что время истекло, вачдог не был сброшен. Код простой, примерно такой.

    Код (C++):
    void loop() {  // ядро 1
      scan_msg();
      checkConn();  // проверка связи
      esp_task_wdt_reset();
    }

    void mqt(void* pvParameters) {  // ядро 0
      while (1) {
        checkConnM();  // проверка связи
        clientM.loop();
        esp_task_wdt_reset();
      }
    }
    Сброс такой:

    То есть на таске mqt сторож не сбрасывается. Почему?

    ps: Задачу добавлять в дог пробовал "esp_task_wdt_add(NULL);", не помогает.
     
  2. parovoZZ

    parovoZZ Гуру

    а
    Код (C++):
    esp_task_wdt_reset();
    что делает?
     
  3. ostrov

    ostrov Гуру

    Сбрасывает счетчик. Но почему-то только в первом потоке, а во втором нет.
     
  4. parovoZZ

    parovoZZ Гуру

    так каким образом? Если это задача, то разве её можно так запустить на выполнение? Она ж просто так не встанет в очередь диспетчера.

    судя по логу, там ничего не сбрасывается.
     
  5. ostrov

    ostrov Гуру

    Потому я и задал этот вопрос. Почему не сбрасывается, если сбрасываю? И как сбрасывать чтобы сбрасывало?
     
  6. ИгорьК

    ИгорьК Гуру

    esp_task_wdt_reset(); - это библиотечная функция?

    Я бы сделал второй поток какой-нибудь другой для проверки - мигание лампочкой, например, чтобы понять лучше в чем дело.
     
  7. parovoZZ

    parovoZZ Гуру

    так судя по названию, это задача. Чтобы задача выполнилась, её надо прописать в планировщике, а затем вызвать диспетчером. FreeRtos?
     
  8. ostrov

    ostrov Гуру

    Работаю оба потока нормально, ничего не виснет, если не включать вачдог. В одном потоке хорошо работает и с ватчдогом тоже. Если потока два, то во втором не сбрасывается, несмотря на команду сброса. По идее, на каждую задачу надо свой вачдог запускать, но запускается автоматом на обе. Запускать на каждую тоже пробовал по феншую, но результат тот же. В итоге пока или поток оставлять один или собаку не юзать. Пока перепробовал все варианты, что пришли на ум, возможно истина где-то рядом, но еще не нашел.
     
  9. ostrov

    ostrov Гуру

    Ничего не понял. Задача выполняется, все прописано. FreeRtos да.
     
  10. parovoZZ

    parovoZZ Гуру

    это API SDK ESP
    https://docs.espressif.com/projects/esp8266-rtos-sdk/en/latest/api-reference/system/wdts.html

    Я бы тогда создал ещё одну задачу, которая бы собирала состояние всей программы и уже она бы сбрасывала вачдог.
     
  11. ostrov

    ostrov Гуру

    Проблема в том, что одного сброса на все задачи мало. Да и по одному сбросу на все задачи тоже не хватает.
     
  12. parovoZZ

    parovoZZ Гуру

    как-то так примерно и делается. Потому как если одна из задач зависнет, то она и будет сбрасывать вачдог постоянно. В итоге имеем не рабочий вачдог и не рабочую задачу.
     
  13. ostrov

    ostrov Гуру

    Похоже проблема в работе радиомодулей. Они по умолчанию на 0 ядре запускаются, вот без них все работает как должно, с ними так как описано выше.
     
    ИгорьК нравится это.
  14. Vortigont

    Vortigont Нуб

    Код (C++):
    void mqt(void* pvParameters) {  // ядро 0
      while (1) {
        checkConnM();  // проверка связи
        clientM.loop();
        esp_task_wdt_reset();
      }
    }
    вы душите своим таском 0е ядро, не давая rtos выдать квант времени idle таску (он работает с самым низким приоритетом). Контроллер вам сбрасывает не ваш вочдог, а вочдог другой таски когда она не получает долго квант времени на работу (в данном случае IDLE0). Ваша таска некорректна с точки зрения ртос, она никогда не простаивает и всегда крутит пустой цикл. Таски в ртос делают так что бы выполнив какую-то работу они засыпали ожидая события от РТОС. Не надо вручную сбрасывать вочдог, этим вы пытаетесь лечить симптомы, а не проблему и лечите не в том месте.
    Замените esp_task_wdt_reset(); на delay(5); если код под ардуино или на vTaskDelay(
    5/portTICK_PERIOD_MS) если пришете под IDF.
    Но вообще это корявый способ использовать таски, лучше воткните свой mqtt в ардуиновский loop(), там уже все нужное сделали.