• Уважаемые посетители сайта esp8266.ru!
    Мы отказались от размещения рекламы на страницах форума для большего комфорта пользователей.
    Вы можете оказать посильную поддержку администрации форума. Данные средства пойдут на оплату услуг облачных провайдеров для сайта esp8266.ru
  • Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Вопрос FreeRTOS : мигание светодиодиком

kotyara12

New member
Доброго дня!

Пытаюсь сделать "мигалку светодиодиками" в виде задачи FreeRTOS. То есть так, чтобы можно было выдать на светодиод что-то вроде "серия из 3 коротких вспышек - пауза".
Соорудил задачу, к ней прикрутил очередь для переключения режимов из других задач.
Светодиодов может быть несколько - соответственно на каждый светодиод своя задача и своя очередь.

Код сделал "по учебнику":

Код:
  while(1) {
      // Получаем событие из очереди
      if (xQueueReceive(_hHandles->ledQueue, &msgQueue, 0) == pdPASS) {
        ... здесь переключаем режимы работы светодиода, например:
            _hHandles->ledInstance->blinkOn(msgQueue.msgValue1, msgQueue.msgValue2, msgQueue.msgValue3);
        ....
        };
      };

      // Обработка серий вспышек светодиода
      _hHandles->ledInstance->ledLoop();
    };
Собственно обработчик ledLoop(), тоже ничего необычного:
Код:
void espLed::ledLoop()
{
  if (_blinkEnabled) {
    if (_ledState) {
      if (millis() >= _blinkTimeout) {
        _blinkCount++;
        _ledOff();

        if (_blinkCount >= _blinkQuantity) {
          _blinkTimeout = millis() + _blinkPause;
          _blinkCount = 0;
        }
        else {
          _blinkTimeout = millis() + _blinkFlash;
        };
      };
    }
    else {
      if (millis() >= _blinkTimeout) {
        _ledOn();
        _blinkTimeout = millis() + _blinkFlash;
      };
    };
  };
}
То есть большую часть времени ledLoop() просто ничего не делает.

Проблема:
На ядре 1 задача худо-бедно работает. Но я хотел все легкие "сервисные" задачи перевести на ядро 0, чтобы отдать ядро 1 целиком под прикладные задачи.
При назначении задачи на ядро 0 ESP32 начинает спонтанно перезагружаться:

Код:
E (5150) task_wdt: Task watchdog got triggered. The following tasks did not reset the watchdog in time:
E (5150) task_wdt:  - IDLE0 (CPU 0)
E (5150) task_wdt: Tasks currently running:
E (5150) task_wdt: CPU 0: ledSystem
E (5150) task_wdt: CPU 1: loopTask
E (5150) task_wdt: Aborting.
abort() was called at PC 0x400e1de7 on core 0

Backtrace: 0x4008d358:0x3ffbe160 0x4008d589:0x3ffbe180 0x400e1de7:0x3ffbe1a0 0x40081f2d:0x3ffbe1c0 0x4008a5f2:0x3ffb8c10 0x40089b70:0x3ffb8c30 0x400d28f9:0x3ffb8c70 0x40088f51:0x3ffb8ca0

Rebooting...
Причем видно, что в списке задач сейчас якобы всего 1 светодиод, а на самом деле я их запустил 3.

Если добавить vTaskDelay(1) в основной цикл задачи, то еще как-то худо-бедно работает.
Задержку в ожидании событий очереди делать нельзя - перестанут обрабатываться мигания.
Таймеры внутрь ledLoop() пихать тоже не сподручно - во первых очередь обрабатываться будет с задержками, а во вторых ledLoop() можно использовать и без FreeRTOS, например на ESP8266.

Что я делаю не так?
 
Сверху Снизу