• Система автоматизации с открытым исходным кодом на базе 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.

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