Mdebug API

Mdebug (Mesh Network debug) is an important debugging solution used in ESP-MDF. It is designed to efficiently obtain ESP-MDF device logs through wireless espnow protocol, TCP protocol, serial port, etc., so that it can be read more conveniently and quickly. The device log information can then be analyzed according to the extracted logs.

Application Examples

For ESP-MDF examples, please refer to the directory function_demo/Mdebug, which includes:

  • The log information of the child node is transmitted to the root node through the ESP-Mesh network, and then outputted through the serial port of the root node or transmitted to the server through http;
  • Output the desired log information through the console.

1. UART enable

The serial port is enabled and the log information will be printed out via vprintf. Enable the following program:

if (config->log_uart_enable) { /**< Set log uart enable */
    mdebug_log_init();
} else {
    mdebug_log_deinit();
}

2. Flash enable

Write flash enable to store log information in flash. Enable the following program:

if (config->log_flash_enable) { /**< Set log flash enable */
      mdebug_flash_init();
} else {
      mdebug_flash_deinit();
}

2.1 Log information access

  1. The log is initialized, creating two text flash memory spaces, using the main functions as esp_vfs_spiffs_register, esp_spiffs_info, sprintf, fopen;
/**< Create spiffs file and number of files */
esp_vfs_spiffs_conf_t conf = {
    .base_path       = "/spiffs",
    .partition_label = NULL,
    .max_files       = MDEBUG_FLASH_FILE_MAX_NUM,
    .format_if_mount_failed = true
};
  1. Write the log data, and write down the address of the write pointer. In order to address the next log write flash, use the main function as fwrite. The following procedure:
/**< Record the address of each write pointer */
fseek(g_log_info[g_log_index].fp, g_log_info[g_log_index].size, SEEK_SET);
ret = fwrite(data, 1, size, g_log_info[g_log_index].fp);
  1. Read the log data, and write down the address of the read pointer. For the next time to read the log from the flash, address the address, use the main function as fread. The following procedure:
/**< Record the pointer address for each read */
flash_log_info_t *log_info = g_log_info + ((g_log_index + 1 + i) % MDEBUG_FLASH_FILE_MAX_NUM);
fseek(log_info->fp, log_info->offset, SEEK_SET);

ret = fread(data, 1, MIN(*size - read_size, log_info->size - log_info->offset), log_info->fp);
  1. The data is erased. When the data is full, the data pointer will be cleared, and the main function rewind will be restarted from the beginning or the end of the file header address. The following procedure:
/**< Erase file address pointer */
for (size_t i = 0; i < MDEBUG_FLASH_FILE_MAX_NUM; i++) {
    g_log_index          = 0;
    g_log_info[i].size   = 0;
    g_log_info[i].offset = 0;
    rewind(g_log_info[i].fp);
    mdf_info_save(MDEBUG_FLASH_STORE_KEY, g_log_info, sizeof(flash_log_info_t) * MDEBUG_FLASH_FILE_MAX_NUM);
}

Note

  1. The header of the log data is an added timestamp. It is only used as an experiment, and there is no real-time calibration. Users can modify it according to their own needs. The following procedure:
/**< Get the current timestamp */
time(&now);
localtime_r(&now, &timeinfo);
strftime(strtime_buf, 32, "\n[%Y-%m-%d %H:%M:%S] ", &timeinfo);
  1. Extract and select valid string data information. Because the log information in the MDF has unnecessary data at the beginning and the end, it needs to be removed. The following procedure removes unwanted data from the head and tail:
/**< Remove the header and tail that appear in the string in the log */
if (log_data->data[0] == 0x1b) {
    data = log_data->data + 7;
    size = log_data->size - 12;
}

3. ESPNOW enable

Espnow can be enabled to send the log data of the child node to the root node through espnow, so that the log information of the child node is read from the root node. Enable the following program:

/**< config espnow enable */
if (config->log_espnow_enable) {
    mdebug_espnow_init();
} else {
    mdebug_espnow_deinit();
}

Write the log to espnow. The procedure is as follows:

/**< write log information by espnow */
if (!g_log_config->log_espnow_enable && !MDEBUG_ADDR_IS_EMPTY(g_log_config->dest_addr)) {
    log_data->type |= MDEBUG_LOG_TYPE_ESPNOW;
}

if (log_data->type & MDEBUG_LOG_TYPE_ESPNOW) {
    mdebug_espnow_write(g_log_config->dest_addr, log_data->data,
                        log_data->size, MDEBUG_ESPNOW_LOG, pdMS_TO_TICKS(MDEBUG_LOG_TIMEOUT_MS));
}

Mdebug Console

Functions

mdf_err_t mdebug_console_init(void)

Initialize console module.

< _cplusplus

  • Initialize the console
  • Register help commands
  • Initialize filesystem
  • Create console handle task

Attention
Baudrate should not greater than 2030400 if console is enable
Return
  • MDF_OK
  • MDF_FAIL

mdf_err_t mdebug_console_deinit(void)

De-initialize console module Call this once when done using console module functions.

Return
  • MDF_OK
  • MDF_FAIL

void mdebug_cmd_register_common(void)

Register frequently used system commands.

  • version: Get version of chip and SDK
  • heap: Get the current size of free heap memory
  • restart: Software reset of the chip
  • reset: Clear device configuration information
  • log: Set log level for given tag
  • coredump: Get core dump information_cplusplus MDF_CONSOLE_DEBUG_H

Mdebug Espnow

Functions

mdf_err_t mdebug_espnow_init(void)

Initialize the wireless debug receiver.

  • register espnow log redirect function
  • Create mdebug espnow send and mdebug log send task
  • Create log send queue

Return
  • MDF_OK
  • MDF_FAIL

mdf_err_t mdebug_espnow_deinit(void)

De-initialize the wireless debug receiver.

Return
  • MDF_OK
  • MDF_FAIL

mdf_err_t mdebug_espnow_write(const uint8_t *dest_addr, const void *data, size_t size, mdebug_espnow_t type, TickType_t wait_ticks)

Send debug data with ESP-NOW.

Return
  • ESP_OK
  • ESP_FAIL
Parameters
  • dest_addr: Destination address
  • data: Point to send data buffer
  • size: send data len
  • type: Type of data
  • wait_ticks: wait time if a packet isn’t immediately available

mdf_err_t mdebug_espnow_read(uint8_t *src_addr, void *data, size_t *size, mdebug_espnow_t *type, TickType_t wait_ticks)

receive debug data with ESP-NOW

Return
  • ESP_OK
  • ESP_FAIL_cplusplus MDF_ESPNOW_DEBUG_H
Parameters
  • src_addr: Destination address
  • data: Point to send data buffer
  • size: send data len
  • type: Type of data
  • wait_ticks: wait time if a packet isn’t immediately available

Structures

struct mdebug_coredump_packet_t

Core dump data structure.

Public Members

uint8_t type

Type of packet

int16_t size

Size of data

int16_t seq

Sequence

uint8_t data[230]

data

Enumerations

enum mdebug_espnow_t

Type of data sent during wireless debugging.

< _cplusplus

Values:

MDEBUG_ESPNOW_COREDUMP = 1

Core dump information

MDEBUG_ESPNOW_CONSOLE

Remotely call local terminal commands

MDEBUG_ESPNOW_LOG

Log information

enum [anonymous]

Type of core dump data.

Values:

MDEBUG_COREDUMP_BEGIN = 1

Start transferring core dump data

MDEBUG_COREDUMP_DATA

Send core dump data

MDEBUG_COREDUMP_END

End core dump data transfer

Mdebug Flash

Functions

mdf_err_t mdebug_flash_init()

Init mdebug_flash Create Several files under the spiffs folder,open the file.Open the file for the storage of the next step data.paramters MDEBUG_FLASH_FILE_MAX_NUM if files sizes change.

< _cplusplus

Return
  • MDF-OK

mdf_err_t mdebug_flash_deinit()

Deinit medbug_flash If you open the file, close the file accordingly.

Return
  • MDF-OK

mdf_err_t mdebug_flash_write(const char *data, size_t size)

Write memory data in flash.

Note
Don’t include timestamp in interface input data
Return
  • MDF_OK
Parameters
  • data: Data from the flash’s spiffs files in the log
  • size: Size from the flash’s spiffs files in the log

mdf_err_t mdebug_flash_read(char *data, size_t *size)

Read memory data in flash.

Return
  • MDF_OK
  • read_size
Parameters
  • data: Data from the flash’s spiffs files in the log
  • size: Size from the flash’s spiffs files in the log

mdf_err_t mdebug_flash_erase()

Erase when the data and pointers is full.

Return
  • MDF_OK

size_t mdebug_flash_size()

Create files size,For the data to be stored in the file for subsequent calls.paramters MDEBUG_FLASH_FILE_MAX_NUM if files sizes change.

Return
  • size_cplusplus MDF_DEBUG_FLASH_H

Mdebug Log

Functions

mdf_err_t mdebug_log_get_config(mdebug_log_config_t *config)

Get the configuration of the log during wireless debugging.

Return
  • MDF_OK
  • MDF_FAIL
Parameters
  • config: The configuration of the log

mdf_err_t mdebug_log_set_config(const mdebug_log_config_t *config)

Set the configuration of the log during wireless debugging.

Return
  • MDF_OK
  • MDF_FAIL
Parameters
  • config: The configuration of the log

mdf_err_t mdebug_log_init(void)

Init log mdebug.

  • Set log mdebug configuration
  • Create log mdebug task

Return
  • MDF_OK

mdf_err_t mdebug_log_deinit(void)

De-initialize log mdebug Call this once when done using log mdebug functions.

Return
  • MDF_OK_cplusplus MDF_DEBUG_LOG_H

Structures

struct mdebug_log_config_t

Log sending configuration.

< _cplusplus

Public Members

bool log_uart_enable

Serial port enable

bool log_flash_enable

Write the log to flash enable

bool log_espnow_enable

enable log transferred via ESP-NOW

uint8_t dest_addr[6]

Turn off log sending if all is zero

struct mdebug_log_queue_t

Type of log storage queue.

Public Members

uint16_t size

The length of the log data

mdebug_log_type_t type

Ways to send logs

char data[0]

Log data

Enumerations

enum mdebug_log_type_t

Set the send type.

Values:

MDEBUG_LOG_TYPE_ESPNOW = 1 << 1
MDEBUG_LOG_TYPE_FLASH = 1 << 2

Mdebug Partially Referenced Header File

Macros

MDEBUG_PRINTF(fmt, ...)

Configuration mdebug print enable, whether the output information according to the client needs to know. please assign CONFIG_MDEBUG_PRINTF_ENABLE a value.

< _cplusplus

Note
CONFIG_MDEBUG_PRINTF_ENABLE = 1 enable CONFIG_MDEBUG_PRINTF_ENABLE = 0 disable

MDEBUG_ADDR_IS_EMPTY(addr)
MDF_EVENT_MDEBUG_FLASH_FULL

_cplusplus MDF_DEBUG_H