kotyara12
New member
Доброго дня!
Пытаюсь сделать "мигалку светодиодиками" в виде задачи FreeRTOS. То есть так, чтобы можно было выдать на светодиод что-то вроде "серия из 3 коротких вспышек - пауза".
Соорудил задачу, к ней прикрутил очередь для переключения режимов из других задач.
Светодиодов может быть несколько - соответственно на каждый светодиод своя задача и своя очередь.
Код сделал "по учебнику":
Собственно обработчик ledLoop(), тоже ничего необычного:
То есть большую часть времени ledLoop() просто ничего не делает.
Проблема:
На ядре 1 задача худо-бедно работает. Но я хотел все легкие "сервисные" задачи перевести на ядро 0, чтобы отдать ядро 1 целиком под прикладные задачи.
При назначении задачи на ядро 0 ESP32 начинает спонтанно перезагружаться:
Причем видно, что в списке задач сейчас якобы всего 1 светодиод, а на самом деле я их запустил 3.
Если добавить vTaskDelay(1) в основной цикл задачи, то еще как-то худо-бедно работает.
Задержку в ожидании событий очереди делать нельзя - перестанут обрабатываться мигания.
Таймеры внутрь ledLoop() пихать тоже не сподручно - во первых очередь обрабатываться будет с задержками, а во вторых ledLoop() можно использовать и без FreeRTOS, например на ESP8266.
Что я делаю не так?
Пытаюсь сделать "мигалку светодиодиками" в виде задачи FreeRTOS. То есть так, чтобы можно было выдать на светодиод что-то вроде "серия из 3 коротких вспышек - пауза".
Соорудил задачу, к ней прикрутил очередь для переключения режимов из других задач.
Светодиодов может быть несколько - соответственно на каждый светодиод своя задача и своя очередь.
Код сделал "по учебнику":
Код:
while(1) {
// Получаем событие из очереди
if (xQueueReceive(_hHandles->ledQueue, &msgQueue, 0) == pdPASS) {
... здесь переключаем режимы работы светодиода, например:
_hHandles->ledInstance->blinkOn(msgQueue.msgValue1, msgQueue.msgValue2, msgQueue.msgValue3);
....
};
};
// Обработка серий вспышек светодиода
_hHandles->ledInstance->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;
};
};
};
}
Проблема:
На ядре 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...
Если добавить vTaskDelay(1) в основной цикл задачи, то еще как-то худо-бедно работает.
Задержку в ожидании событий очереди делать нельзя - перестанут обрабатываться мигания.
Таймеры внутрь ledLoop() пихать тоже не сподручно - во первых очередь обрабатываться будет с задержками, а во вторых ledLoop() можно использовать и без FreeRTOS, например на ESP8266.
Что я делаю не так?