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

- Process information display : "show tasks"
- Process Control
- Suspend, Resume and Kill
- Task priorities, changing

## ⇮PROCESS INFORMATION DISPLAY

As in other cases, task information is available using the "show" command:

Command | Description and examples
--- | ---
show tasks | Displays a list of running tasks, including their ID, priority, name, and state:
    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#>

## ⇮PROCESS CONTROL

Process control is implemented through three commands: suspend, resume, kill and priority. By "processes," we mean FreeRTOS tasks. For example, the main Arduino loop() runs as a dedicated FreeRTOS task named "loop" - so "loop()" is a process.

Access to tasks and their management is done by their TASK_ID (a hexadecimal number, for example "0x3fca370c") or by name, except for the main Arduino loop() task: the execution of the main sketch can be controlled by omitting the TASK_ID parameter in the command. That is, to suspend the sketch, instead of "suspend 0x12345678" you can use the command "suspend" without arguments.

IMPORTANT: Several processes may have exactly the same names. This happens, for example, when multiple background commands are started, such as "pin":

      esp32#>pin 2 low delay 100 high delay 100 loop infinite &
      esp32#>pin 4 low delay 200 high delay 200 loop infinite &

The process list will then contain two processes with the identical name "pin". In this case, you should use the TASK_ID instead of the name. If you use the task name, the operation will be performed on the first task with that name in the list. The task’s index in the list changes constantly and should not be relied upon.

Okay, but where can we get these task IDs and names?

For example, you can use the show tasks command:

    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#>

Command displays all tasks, including system tasks started by FreeRTOS and tasks started by ESP-IDF.

Also, every ESPShell command that is run as a background process displays its TASK_ID. Let's say we execute the command "pin 2 delay 1000" in the background:

    esp32#>pin 2 delay 1000 &
    % Background task started
    % Copy/paste "kill 0x3ffb91dc" to abort
    esp32#>

This command doesn't do much -just waits for 1000ms. Once started, it prints its task ID along with a convenient "kill" command that can be copied and executed: "kill 0x3ffb91dc".

Another source of TASK_IDs is the "show counters" command.

## ⇮SUSPEND, RESUME AND KILL

Command | Description and examples
--- | ---
suspend | Pauses sketch execution by suspending Arduino's loop(). Tasks that were started by loop() and setup() are not suspended by this command. Suspending a task along with all of its child tasks is a planned but not yet implemented feature. Ctrl+C is a hotkey for the "suspend" command.
suspend TASK_ID|TASK_NAME | suspend TASK_ID | TASK_NAME Suspends an arbitrary task by its name or ID. The command requires one argument -a hexadecimal task ID or a task name. Please note that there may be several tasks with the same name (but IDs are different).
resume | Resumes sketch execution.
resume TASK_ID | TASK_NAME | resume TASK_ID | TASK_NAME Resumes an arbitrary task by its TASK_ID or by its TASK_NAME. The command requires one argument -a hexadecimal task ID or a name.

To stop an ESPShell task (ESPShell uses tasks to run background commands) or any arbitrary FreeRTOS task, use the kill command:

Command | Description and examples
--- | ---
kill TASK_ID|TASK_NAME | kill [-TERM | -15 | -KILL | -9] TASK_ID Stops execution of the task with the given TASK_ID / TASK_NAME. If the "&" symbol is used at the end of a command, ESPShell executes it in the background by spawning a new task:
          esp32#>pin 2 delay 999 &
          % Background task started
          % Copy/paste "kill 0x3fca370c" command to stop execution  ← note the TASK_ID
          esp32#>
Please note that any background command like the "pin 2 low ..." command will have the same task name: "pin". In such cases, use the TASK_ID to distinguish between different "pin" commands. In the simplest case -when only the TASK_ID or TASK_NAME are provided - the command sends a notification to the task in an attempt to initiate a graceful shutdown. This command mimics the classic Linux `kill` command and accepts an optional signal parameter. -9 or -KILL means forcibly terminate the task: no notification is sent; the task is suspended and then deleted via the FreeRTOS API `vTaskDelete()`. However, resources used by the task are not freed. Force-killing a task holding a mutex may result in system lockups. All ESPShell-created tasks should normally be terminated this way -without using any additional parameters. However, there are examples of ESPShell commands that can only be terminated using `kill -9`. These special cases are described in the documentation for the "pin" command. Using -15, -TERM, or no signal at all indicates a graceful shutdown: the task is not deleted but is given a chance to terminate itself and release any allocated resources. Using -9 or -KILL results in immediate task suspension and deletion via FreeRTOS `vTaskDelete()`. This is equivalent to the Linux `kill -9` command, but unlike its Linux counterpart, ESPShell does not release any memory or resources allocated by the task.

## ⇮PROCESS PRIORITY, CHANGING PRIORITY

Tasks managed by FreeRTOS are scheduled according to their assigned priorities. A priority value can range from 0 to 24 — the higher the number, the higher the priority.

System-level inter-core communication tasks — ipc0 and ipc1 — run with the highest priority. Bluetooth and Wi-Fi components operate with high priority, while so-called idle tasks — IDLE0 and IDLE1 — have the lowest.

By default, ESPShell starts with priority 0, which corresponds to the priority of system idle tasks. All auxiliary tasks created by the shell are also launched with the same priority. Tasks started by the shell (e.g., background commands) inherit this priority.

The priority can be changed using the "priority NUM [TASK_ID | TASK_NAME]" command. If the second parameter (task ID) is omitted, the new priority is applied to the shell itself. If provided, the specified task’s priority will be updated instead.

Example: check the current priority of the shell and change it to 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
    ...

Note on task priorities: The shell command pin 2 low high loop inf generates a 150 kHz square wave when running with IDLE priority. However, when its priority is raised to 2, the frequency increases to 560 kHz. This happens because the pin command never yields the CPU, preventing lower-priority system tasks from executing.