ESPShell for Arduino :: Accessing Sketch Variables

[ Russian ] ↔ [ English ]

SKETCH VARIABLES: REGISTRATION

To make a variable accessible from ESPShell, it must first be registered.

ESPShell provides an API for registering and managing sketch variables. Naturally, the shell knows nothing about your sketch variables until you explicitly tell it which variables should be exposed through the shell interface. It is also possible to create arbitrary variables directly from the shell. For example, you can create a variable named MyVar of type unsigned short int and bind it to address 0x3fcef000 using a single command (see below). Only basic C types are supported, including signed/unsigned int, char, short, float, and void* pointers. Arrays of these basic types are supported as well.

The convar_add() macro is used to register variables. Specialized macros are also available, such as convar_addp() for pointers and convar_adda() for arrays.

Example usage in an Arduino sketch. Suppose we have three variables that we want to make accessible from the shell command line:

  static int some_variable;
  unsigned char *pointer;
  char array[10];

  void setup() {
    ...
    convar_add(some_variable); ← Register a regular variable
    convar_addp(pointer);      ← Register a pointer
    convar_adda(array);        ← Register an array
    ...
  }

Additional registration macros are available: convar_addap(Name) — register an array of pointers, convar_addpp(Name) — register a pointer to a pointer.

VARIABLES: CREATING NEW VARIABLES

Suppose you want to inspect the contents of memory at address 0x3fcef100, not as a hexadecimal dump but, for example, as an array of 10 float elements. To do this, you need to tell the shell that a variable of a specific type is located at the given address:

    esp32#>var 0x3fcef100 zzz float [10]

After executing this command, a variable named zzz will be created and bound to address 0x3fcef100. You can then inspect and modify it. All reads and writes will be performed directly through the specified memory address, taking both the data type size and byte order into account automatically.

DISPLAYING VARIABLES AND VALUES

The code snippet above registers three variable types: an integer, a pointer, and an array. Once registered using the appropriate convar_addX() macros, these variables can be accessed via the shell using the commands var NAME and show memory ADDRESS.

When executed without arguments, the var command lists all registered variables:

    esp32#>var
    % Sketch variables:
    % Variable X name | sizeof(X) |     typeof(X)    |     Value
    %-----------------+-----------+------------------+----------------
    %           table |         4 |            int * |       0x3ffbdb88
    %              a4 |         4 |          float * |       0x3ffbdbb4
    %              a3 |         4 |            float |        10.000000
    %              a2 |         4 |     unsigned int |                0
    %              a1 |         1 |    unsigned char |               99
    %              a0 |         4 |              int |              -99
    %     tbl_min_len |         2 |   unsigned short |               16
    %       bypass_qm |         4 |              int |                0
    %       pcnt_unit |         4 |              int |                0
    %    pcnt_channel |         4 |              int |                0
    %ls_show_dir_size |         4 |              int |                1
    esp32#>

Note that for pointers and arrays, their address is shown rather than the content. To dereference a pointer or view array contents, use var VAR_NAME:

    esp32#>var a4
    % float * a4 = 0x3ffbdbb4;  // Pointer to a 4-byte memory region
    % a4[1] = {
    %    10.000000, // a4[0]
    % };

Another example:

    esp32#>var table
    % int * table = 0x3ffbdb88;  // Array of 10 elements (4 bytes each)
    % int table[10] = {
    %    1, // table[0]
    %    2, // table[1]
    %    3, // table[2]
    %    4, // table[3]
    %    5, // table[4]
    %    6, // table[5]
    %    7, // table[6]
    %    8, // table[7]
    %    9, // table[8]
    %    0, // table[9]
    % };

To access a specific array element, use an index, just like in C:

    esp32#>var table[5]
    % int table[5] = 6;
    esp32#>

This syntax can also be used to access memory pointed to by a pointer. When using an index on a pointer variable, ESPShell will display a warning, as it cannot determine valid memory bounds.

Here's another example of displaying a variable:

    esp32#>var a1
    % unsigned char a1 = 99;
    esp32#>

SETTING VARIABLE VALUES

To change a variable's value, use the command var VARIABLE_NAME NEW_VALUE. For example, to change a1 to 88:

    esp32#>var a1 88
    esp32#>var a1
    % unsigned char a1 = 88;  // Use "var 88" to view this number in hex, octal, binary, etc.
    esp32#>

Some basic type checks are enforced. For example, you cannot assign a signed value to an unsigned variable or a floating-point value to an integer. Array values cannot be changed this way, as their address is fixed by the linker and cannot be modified at runtime.

NUMBER BASE CONVERSION

Another use of the var command is number base conversion. If the argument passed to var is a number (decimal, hexadecimal, floating point, octal, or binary), ESPShell will display the value in multiple bases and perform an unsafe C-style memory cast. This is mainly useful to inspect how negative or floating-point numbers are represented in memory.

Example:

                          
    esp32#>var 666
    % "666" is a number, represented as:
    % C-style memory cast:
    % unsigned : 666
    %   signed : 666
    % float    : 0.000000
    % In different bases:
    % Hex      : 0x29a
    % Octal    : 01232
    % Binary   : 0b1010011010
    esp32#>

Or:

    esp32#>var 666.666
    % "666.666" is a number, represented as:
    % C-style memory cast:
    % unsigned : 1143384736
    %   signed : 1143384736
    % float    : 666.666016
    % In different bases:
    % Hex      : 0x4426aaa0
    % Octal    : 010411525240
    % Binary   : 0b1000100001001101010101010100000
    esp32#>

Or:

    esp32#>var 0b111
    % "0b111" is a number, represented as:
    % C-style memory cast:
    % unsigned : 7
    %   signed : 7
    % float    : 0.000000
    % In different bases:
    % Hex      : 0x7
    % Octal    : 07
    % Binary   : 0b111
    esp32#>