17 de maio de 2021

Do bit Ao Byte

Embarcados, Linux e programação

Debug do ESP32 no VS Code com ESP-Prog

ESP32 no VS Code

No artigo anterior relacionado fiz a apresentação da placa e a configuração inicial para usar o ESP-Prog com o ESP32 no VS Code. Nesse artigo vamos aos detalhes de ambiente, seguido por um vídeo mostrando o debug de um sketch simples para ficar claro o que é o debug para quem não conhece, e para quem conhece, apresentar o ambiente para ESP32.

Configuração do ambiente

É fundamental a leitura do artigo “Como depurar com o ESP-Prog“, para saber o pinout da placa, o fluxo do programa e os jumpers. Já a parte de configuração de sistema, vou repetir e adicionar alguns detalhes mais.

Configuração de sistema

Aqui descrevo o processo de configuração do ESP32 no VS Code para Linux. Para Windows e Mac, siga a documentação da Espressif.

No Linux devemos configurar as regras de udev para que seja possível usar o ESP-Prog sem problemas. Para isso, siga esses 3 passos:

#1 - entrar no diretório
cd /etc/udev/rules.d
#2 - baixar o arquivo de regras
sudo wget -c https://raw.githubusercontent.com/platformio/platformio-core/master/scripts/99-platformio-udev.rules
#3 - aplicar as regras sem reiniciar.
udevadm control --reload-rules && udevadm trigger 

Configuração de projeto (platformio.ini)

Feito isso, pode abrir o VS Code, criar um novo projeto com o Wemos D1 Mini32 (é a placa que estou usando nesse artigo, mas praticamente todas funcionam, basta deixar os respectivos pinos para debug), edite o arquivo de projeto platformio.ini e adicione essas linhas:

[env:wemos_d1_mini32]
platform         = espressif32
board            = wemos_d1_mini32
framework        = arduino
; ESP32 no VS Code com ESP-Prog
;###########################################
;--------- velocidade da serial -------------
monitor_speed    = 9600
;--------- JTAG ESP-PROG --------------------
debug_tool       = esp-prog
;--------- opcionalmente, também faz upload -
upload_protocol  = esp-prog
;--------- breakpoint para debug ------------
debug_init_break = tbreak setup loop blink

Aqui temos algumas linhas opcionais, mas que vale a pena comentar.

A monitor_speed é 9600 por padrão, essa variável não precisa ser adicionada se for usar realmente em 9600, mas eu coloquei para servir de referência para quem normalmente usa em 115200.

A linha debug_tool é onde indicamos a ferramenta de debug – no caso, a esp-prog.

A linha seguinte é a ferramenta de upload. Opcionalmente upload_protocol pode ser o esp-prog, mas se for fazer upload pela USB, não conecte ambos ao mesmo tempo: ou USB, ou debugger.

Podemos definir de imediato um ponto para parada pelo próprio arquivo de projeto. Não sei se realmente vale a pena fazer isso, mas eu coloquei para experimentar. Funciona, mas os breakpoints relacionados à função blink eu coloquei direto no main.cpp. O parâmetro para debug_init_break deve começar com tbreak seguido pelos pontos de parada, que podem ser:

;desabilitado
debug_init_break =
; parada no setup
debug_init_break = tbreak setup
; parada na linha 25 de main.cpp
debug_init_break main.cpp:25

error while loading shared libraries: libpython2.7.so.1.0

No Ubuntu 20.10 o Python 2.7 já é passado. Ao tentar iniciar a depuração, o xtensa-esp32-elf-gdb vai invocar essa biblioteca, que não estará no sistema e consequentemente dará erro. Para evitar esse problema, instale a dependência:

sudo apt-get install libpython2.7

Iniciando o debug do ESP32 no VS Code e ESP-Prog

Agora sim, com todo o ambiente devidamente configurado, podemos iniciar o debug. Apenas uma coisa em relação ao wiring: para alimentar o ESP32, usei o pino 3v3 da placa, já que a saída do ESP-Prog está com o jumper em 3v3.

ESP32 no VS Code

Aperte o botão boot da ESP-Prog, então clique em upload no rodapé da janela do VS Code (na seta apontando para a direita) e o programa deverá subir para a placa. Para fazer debug, clique no menu Run > Start Debugging e na parte debaixo da janela, clique em DEBUG CONSOLE. Na altura das abas de arquivos deverá aparecer o menu de debug. Clique em step over para avançar pelos breakpoints, e clique em step in para entrar nas funções que forem chamadas dentro do breakpoint. No vídeo mostro um pouco mais.

Código do debug

Para esse vídeo estou usando um código bem simples, que foi tema de outro artigo, só adicionei as coisas relacionadas ao debug. Além da modificação do platformio.ini já disposto, temos o main.cpp com o código:

#include <Arduino.h>
#include "driver/uart.h"

#define BUF_SIZE (1024)
char *data = (char *) malloc(BUF_SIZE);

bool STATE = false;

uart_config_t uart_config = {
  .baud_rate = 9600,
  .data_bits = UART_DATA_8_BITS,
  .parity    = UART_PARITY_DISABLE,
  .stop_bits = UART_STOP_BITS_1,
  .flow_ctrl = UART_HW_FLOWCTRL_DISABLE
};

void blink(){
    digitalWrite(LED_BUILTIN,STATE); //O LED da Wemos32 Mini é o pino 2
    delay(500);
    STATE = !STATE;
    Serial.println(STATE);
}

void setup() {

  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
  pinMode(LED_BUILTIN,OUTPUT);

  uart_param_config(UART_NUM_1, &uart_config);
  uart_set_pin(UART_NUM_1, GPIO_NUM_21, GPIO_NUM_22, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
  uart_driver_install(UART_NUM_1, BUF_SIZE * 2, 0, 0, NULL, 0);
}

void loop() {
  int len = uart_read_bytes(UART_NUM_1, (uint8_t *) data, BUF_SIZE, 20 / portTICK_RATE_MS);
  if (len > 0) {
    Serial.println(data);
    bzero(data,1024);   
  }
  blink();
}

Para adicionar breakpoints manualmente, clique na coluna do lado esquerdo dos números de linha; aparecerá um ponto vermelho. O exemplo da parada no blink:

ESP32 no VS Code - breakpoint

Enfim, é um espetáculo programar o ESP32 dessa maneira, sem precisar encher o código de prints, e sem precisar ficar adivinhando onde pode estar o problema, uma vez que podemos adicionar as variáveis em WATCH (na coluna da esquerda na janela de debug), fazer breakpoints em funções ou linhas específicas do código e analisar muito mais a fundo cada etapa de processamento do código.

Quando estiver fazendo o debug, o programa será executado na placa, mas não gravado nela. Se desconectá-la, o programa depurado não estará lá ao reconectar. Parando o debug, o código deverá rodar livremente fazendo o blink como se nada estivesse acontecendo além do próprio sketch.

Vídeo do ESP-Prog

Para ver essa deliciosa ferramenta em ação, confira o vídeo onde apresento a placa e faço uma demonstração de debug, em nosso canal DobitaobyteBrasil no Youtube. Se não é inscrito, aproveite para se inscrever e alegrar o dia do velhote careca que vos escreve!

Revisão: Ricardo Amaral de Andrade