ESPShell для Arduino :: Содержание

[ На русском ] ↔ [ English ]

ПРОСМОТР ИНФОРМАЦИИ О ПРОЦЕССАХ

Как и в других случаях, информация о задачах доступна с помощью команды "show":

КомандаОписание и примеры
show tasks

Выводит список запущенных процессов, их ID, приоритет, имя и состояние:

esp32#>show ta
%  # |  Task  ID  |        Name      | Prio |   State
%----+------------+------------------+------+-----------
%   1| 0x3fca300c |         ESPShell |   5  | Running
%   2| 0x3fca7264 |            IDLE0 |   0  | Ready
%   3| 0x3fca5f64 |              pin |   0  | Ready
%   4| 0x3fca783c |            IDLE1 |   0  | Ready
%   5| 0x3fcaace8 |         loopTask |   1  | Waiting
%   6| 0x3fca85f4 |          Tmr Svc |   1  | Waiting
%   7| 0x3fca1790 |             ipc1 |  24  | Suspended
%   8| 0x3fca11f8 |             ipc0 |  24  | Suspended
%   9| 0x3fca5484 |        esp_timer |  22  | Suspended
%----+------------+------------------+------+-----------
% Total: 9 tasks
esp32#>

УПРАВЛЕНИЕ ПРОЦЕССАМИ

Управление процессами реализовано с помощью четырех команд: suspend, resume, priority и kill. Под процессами имеются в виду задачи FreeRTOS: например, основная функция Arduino loop() обрабатывается отдельной задачей FreeRTOS с именем "loop", то есть "loop()" - это процесс (в списке задач он находится под именем "loopTask").

Доступ к задачам и управление ими осуществляется по их TASK_ID (шестнадцатеричное число, например "0x3fca370c") или по имени, за исключением основной задачи loop() Arduino: выполнение основного скетча можно контролировать, опустив параметр TASK_ID в команде. То есть, чтобы приостановить скетч, вместо "suspend 0x12345678" можно использовать команду "suspend" без аргументов.

ВАЖНО: Несколько процессов могут иметь полностью одинаковые имена. Такое происходит, например, когда запускается несколько фоновых команд, скажем, "pin":

  esp32#>pin 2 low delay 100 high delay 100 loop infinite &
  esp32#>pin 4 low delay 200 high delay 200 loop infinite &
В списке процессов будет два процесса с одинаковым именем "pin". В таком случае следует использовать TASK_ID, а не имя. Если же использовать имя задачи, то операция будет производится над первой задачей с таким именем в списке. Порядковый номер задачи в списке постоянно меняется, на него нельзя полагаться.

Хорошо, но где взять эти task id и имена?

Например, можно воспользоваться командой "show tasks":

esp32#>show tasks
%  # |  Task  ID  |        Name      | Prio |   State
%----+------------+------------------+------+-----------
%   1| 0x3fca783c |            IDLE1 |   0  | Ready
%   2| 0x3fca7264 |            IDLE0 |   0  | Ready
%   3| 0x3fca300c |         ESPShell |   0  | Running
%   4| 0x3fca5f64 |              pin |   0  | Ready
%   5| 0x3fcaace8 |         loopTask |   1  | Waiting
%   6| 0x3fca1790 |             ipc1 |  24  | Suspended
%   7| 0x3fca11f8 |             ipc0 |  24  | Suspended
%   8| 0x3fca5484 |        esp_timer |  22  | Suspended
%   9| 0x3fca85f4 |          Tmr Svc |   1  | Waiting
%----+------------+------------------+------+-----------
% Total: 9 tasks
esp32#>

Так же, каждая команда 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 не освобождает ресурсы, которые могли быть выделены задачей.

ПРИОРИТЕТЫ ПРОЦЕССОВ, УСТАНОВКА ПРИОРИТЕТА

В ESP32 процессами (задачами) управляет модифицированная FreeRTOS, которая является одним из компонентов ESP-IDF.

Задачи, находящиеся под управлением FreeRTOS, получают управление в соответствии с присвоенными им приоритетами. Приоритет может принимать значение от 0 до 24: чем больше число, тем выше приоритет.

С максимальным приоритетом запускаются системные задачи межпроцессорного взаимодействия — ipc0 и ipc1. Высокий приоритет присвоен компонентам Bluetooth и Wi-Fi. Минимальный приоритет имеют так называемые idle-процессы: IDLE0 и IDLE1.

По умолчанию ESPShell запускается с приоритетом 0, что соответствует уровню системных idle-процессов. Все вспомогательные задачи, создаваемые шеллом, также запускаются с этим приоритетом. Приоритет задач, инициируемых шеллом (например, фоновых команд), наследуется от него.

Приоритет можно изменить с помощью команды priority NUM [TASK_ID]. Если второй параметр (ID задачи) опущен, новое значение устанавливается для самого шелла. Если указан — приоритет будет изменён у соответствующей задачи.

Пример: посмотреть, какой приоритет установлен у шелла, поменять его на 5

esp32#>sh ta
%  # |  Task  ID  |        Name      | Prio |   State
%----+------------+------------------+------+-----------
%   1| 0x3fca5f64 |              pin |   0  | Ready
%   2| 0x3fca7264 |            IDLE0 |   0  | Ready
%   3| 0x3fca300c |         ESPShell |   0  | Running
%   4| 0x3fca783c |            IDLE1 |   0  | Ready
%   5| 0x3fcaace8 |         loopTask |   1  | Waiting
%   6| 0x3fca11f8 |             ipc0 |  24  | Suspended
%   7| 0x3fca5484 |        esp_timer |  22  | Suspended
%   8| 0x3fca85f4 |          Tmr Svc |   1  | Waiting
%   9| 0x3fca1790 |             ipc1 |  24  | Suspended
%----+------------+------------------+------+-----------
% Total: 9 tasks
esp32#>prio 5
esp32#>sh ta
%  # |  Task  ID  |        Name      | Prio |   State
%----+------------+------------------+------+-----------
%   1| 0x3fca300c |         ESPShell |   5  | Running
%   2| 0x3fca7264 |            IDLE0 |   0  | Ready
%   3| 0x3fca783c |            IDLE1 |   0  | Ready
%   4| 0x3fca5f64 |              pin |   0  | Ready
%   5| 0x3fcaace8 |         loopTask |   1  | Waiting
%   6| 0x3fca5484 |        esp_timer |  22  | Suspended
%   7| 0x3fca85f4 |          Tmr Svc |   1  | Waiting

Примечание о приоритетах задач:
Команда шелла pin 2 low high loop inf генерирует прямоугольный сигнал с частотой 150 кГц при запуске с приоритетом IDLE. Однако при повышении приоритета до 2 частота увеличивается до 560 кГц. Это происходит потому, что команда pin никогда не уступает управление процессору, не позволяя задачам с более низким приоритетом выполняться.