Управление процессами реализовано с помощью трёх команд: suspend, resume и kill. Под процессами имеются в виду задачи FreeRTOS: например, основная функция Arduino loop() обрабатывается отдельной задачей FreeRTOS с именем "loop", то есть "loop()" - это процесс.
Доступ к задачам и управление ими осуществляется по их TASK_ID (шестнадцатеричное число, например "0x3fca370c"), за исключением основной задачи loop() Arduino: выполнение основного скетча можно контролировать, опустив параметр TASK_ID в команде. То есть, чтобы приостановить скетч, вместо "suspend 0x12345678" можно использовать команду "suspend" без аргументов.
Хорошо, но где взять эти task id?
Всё просто: каждая команда ESPShell, которая запускается как процесс, всегда выводит свой TASK_ID. Допустим, мы запускаем команду "pin 2 delay 1000" в фоновом режиме:
esp32#>pin 2 delay 1000 & % Background task started % Copy/paste "kill 0x3ffb91dc" to abort esp32#>Эта простая команда ничего не делает, кроме как ждёт 1000 мс. После запуска она выводит свой task id и команду, которую можно скопировать и выполнить: "kill 0x3ffb91dc".
Другим источником TASK_ID является команда "show counters"
Команда | Описание и примеры |
---|---|
suspend |
Приостанавливает выполнение скетча: приостанавливает loop() Arduino. Задачи, которые были запущены из loop() и setup(), не приостанавливаются этой командой. Приостановка задачи вместе со всеми её дочерними задачами - запланированная, но пока не реализованная возможность. Комбинация клавиш Ctrl+C является горячей клавишей для команды "suspend" |
suspend TASK_ID |
suspend TASK_ID Приостанавливает произвольную задачу, если известен её идентификатор. Команда требует один аргумент - идентификатор задачи (в шестнадцатеричном формате) |
resume |
Возобновляет выполнение скетча |
resume TASK_ID |
resume TASK_ID Возобновляет произвольную задачу, если известен её идентификатор. Команда требует один аргумент - идентификатор задачи (в шестнадцатеричном формате) |
Чтобы остановить задачу ESPShell (ESPShell использует задачи для запуска фоновых команд) или произвольную задачу FreeRTOS, можно воспользоваться командой "kill":
Команда | Описание и примеры |
---|---|
kill TASK_ID | "kill [-TERM | -15 | -KILL | -9] TASK_ID" Останавливает выполнение задачи с TASK_ID. Этот идентификатор либо выводится при запуске фоновой команды, либо может быть произвольным идентификатором FreeRTOS-задачи. Если в конце команды используется символ "&", то ESPShell выполняет такую команду в фоновом режиме, создавая новую задачу:
esp32#>pin 2 delay 999 & % Background task started % Copy/paste "kill 0x3fca370c" command to stop execution ← обратите внимание на TASK_ID esp32#> В простейшем случае, когда используется только один параметр (TASK_ID), команда отправляет уведомление задаче, которую нужно завершить, чтобы она могла завершиться корректно. Команда старается имитировать классическую команду "kill" из Linux и принимает дополнительный параметр - сигнал, который нужно отправить: -9 или -KILL означает принудительное завершение задачи. Уведомление не отправляется, вместо этого задача приостанавливается и удаляется с помощью FreeRTOS API vTaskDelete(). При этом ресурсы, занятые задачей, не освобождаются. Завершение задачи, которая удерживает мьютекс, может привести к зависаниям. Все задачи, создаваемые ESPShell, должны завершаться таким образом - без указания дополнительных параметров. Однако есть примеры команд ESPShell, которые можно завершить только с помощью "kill -9", эти особые случаи описаны в описании команды "pin". Опция -15, -TERM или её отсутствие означает "корректное завершение": задача не удаляется, а получает возможность завершиться самостоятельно и освободить все используемые ресурсы (если таковые имеются). Опция -9 или -KILL приводит к приостановке задачи с её последующим удалением через API FreeRTOS vTaskDelete(). Эта опция эквивалентна команде Linux "kill -9", но в отличие от неё, ESPShell не освобождает ресурсы, которые могли быть выделены задачей. |