MCU & FPGA RTOS Tutorial Zephyr OS: Como Criar o Primeiro Projeto com example-application, DeviceTree e West

Tutorial Zephyr OS: Como Criar o Primeiro Projeto com example-application, DeviceTree e West


Quando “não aparece nada no terminal”: console UART vs RTT vs USB CDC + debug.conf (sem poluir o prj.conf)

Essa é a parte que mais “trava” quem está começando: você builda, flashea… e o terminal fica mudo. Em Zephyr, quase sempre é configuração de console / backend de log + hardware (pinos/USB) + overlay/chosen.

O example-application já te aponta um caminho maduro para lidar com variações de debug: ele mostra o uso de config extra por arquivo com -DEXTRA_CONF_FILE=debug.conf.
Vamos transformar isso em um método de trabalho.


printk x LOG_*: por que um aparece e outro não

  • printk() depende de ter um backend de console funcional, mas tende a ser mais “tolerante” em early boot.
  • LOG_* depende do subsistema de logging estar habilitado e do backend estar certo (UART/RTT etc.). Se você habilitar CONFIG_LOG=y mas não configurar o backend, você pode ter logs “presos” (ou indo pra outro lugar).

No template, eu recomendo manter os dois: LOG_* para normalidade, printk para emergências.


Padrão de ouro: prj.conf “limpo” + debug.conf “agressivo”

Você mantém no prj.conf o mínimo necessário para o firmware “rodar” e cria um arquivo debug.conf para o que é pesado/verboso.

app/prj.conf (produção / base)

CONFIG_CONSOLE=y
CONFIG_UART_CONSOLE=y
CONFIG_PRINTK=y

CONFIG_LOG=y
CONFIG_LOG_MODE_DEFERRED=y
CONFIG_LOG_DEFAULT_LEVEL=3

app/debug.conf (debug)

# Log mais verboso
CONFIG_LOG_DEFAULT_LEVEL=4
CONFIG_LOG_BACKEND_SHOW_COLOR=y

# Ajuda muito em bugs de memória / stacks
CONFIG_ASSERT=y
CONFIG_THREAD_NAME=y

# Em alguns targets, rastreio de stack/erro
CONFIG_STACK_SENTINEL=y
CONFIG_HW_STACK_PROTECTION=y

Build usando o arquivo extra (exatamente no estilo que o template mostra):

west build -p always -b <SUA_BOARD> app -DEXTRA_CONF_FILE=debug.conf

Esse fluxo é excelente porque você não “contamina” seu projeto com debug permanente.


UART Console: o caminho mais comum (e onde dá errado)

Para UART console funcionar, você precisa de:

  • CONFIG_CONSOLE=y
  • CONFIG_UART_CONSOLE=y
  • uma UART válida na board (DeviceTree) e frequentemente um chosen apontando para ela

Se sua board é oficial do Zephyr, normalmente isso já vem OK. Quando não vem (ou quando você quer mudar a UART/pinos), você faz isso com overlay.

Exemplo de ajuste de chosen (conceito)

Em algumas situações você quer garantir que zephyr,console aponte para a UART certa. Um overlay pode incluir algo como:

/ {
    chosen {
        zephyr,console = &uart1;
    };
};

Isso é um exemplo conceitual: a UART (&uart1) precisa existir naquela board e estar status = "okay".

O ponto prático: quando o console não aparece, muitas vezes é porque você está falando na UART “errada” ou o pino está diferente do que você imagina.


RTT (SEGGER): quando você não quer depender de UART/pinos

RTT é muito usado porque evita a dependência de UART e funciona via debug probe (J-Link e afins). Em boards e probes compatíveis, é um “plano B” excelente.

Em geral você habilita RTT e aponta o log/console para ele via Kconfig. O detalhe exato muda conforme versão/board, então o jeito correto (sem chute) é:

  1. Ver quais opções estão disponíveis:west build -t menuconfig
  2. Buscar por “RTT” e “LOG_BACKEND” no menuconfig e habilitar.

Esse método é consistente porque o Zephyr expõe Kconfig de acordo com a board/SoC.


USB CDC ACM (console via USB): bom para ESP32/boards com USB nativo

Se sua board tem USB device e você quer um “serial over USB”, normalmente você habilita USB e o driver CDC ACM.

Novamente: varia por board/SoC. O processo robusto é o mesmo:

  • conferir o DeviceTree (USB device habilitado)
  • habilitar Kconfig correspondente (USB device stack + CDC ACM + console backend)
  • se necessário, overlay para chosen do console

Se você já usa Zephyr em ESP32, isso é muito comum porque elimina adaptador USB-UART externo.


Checklist rápido de “terminal mudo” (ordem que eu uso na vida real)

  1. A board está correta no build? (-b ...)
  2. O flash realmente gravou? (às vezes o west flash fala ok, mas a placa resetou em bootloader)
  3. Estou olhando a porta certa? (/dev/ttyACM0 vs /dev/ttyUSB0 etc.)
  4. Baudrate certo? (muitas boards usam 115200, mas não é lei universal)
  5. Existe CONFIG_PRINTK=y e CONFIG_UART_CONSOLE=y?
  6. Overlay mudou UART/console sem querer? (principalmente chosen)
  7. Se ainda falhar: tenta RTT, porque ele remove “UART/pinos/baud” do caminho.

Crescendo o projeto sem virar monolito: logs por arquivo (padrão limpo)

Quando você dividir seu src/ em arquivos, faça assim:

  • src/app_main.cLOG_MODULE_REGISTER(app_main, LOG_LEVEL_INF);
  • src/sensors.cLOG_MODULE_REGISTER(app_sensors, LOG_LEVEL_INF);
  • src/control.cLOG_MODULE_REGISTER(app_control, LOG_LEVEL_INF);

E no CMakeLists.txt:

target_sources(app PRIVATE
    src/app_main.c
    src/sensors.c
    src/control.c
)

Isso te dá logs filtráveis por subsistema desde o dia 1.


0 0 votos
Classificação do artigo
Inscrever-se
Notificar de
guest
0 Comentários
mais antigos
mais recentes Mais votado
Feedbacks embutidos
Ver todos os comentários

Related Post

Como Criar Tarefas e Soft Timers no FreeRTOS: Guia Prático e Didático para Sistemas EmbarcadosComo Criar Tarefas e Soft Timers no FreeRTOS: Guia Prático e Didático para Sistemas Embarcados

Este artigo apresenta um guia completo e didático sobre como criar e gerenciar tarefas e soft timers no FreeRTOS, explicando conceitos fundamentais de escalonamento, prioridades, dimensionamento de stack e comunicação

0
Adoraria saber sua opinião, comente.x