app/boards/<board>.overlay e <board>.conf (o jeito certo de adaptar hardware sem “quebrar” o projeto)
Quando você sai do “hello world” e começa a falar com hardware (UART, GPIO, I²C, SPI, ADC…), o Zephyr quer que você faça isso via DeviceTree (DTS) e Kconfig, mantendo seu código o mais portátil possível. O example-application já sinaliza esse caminho ao mencionar que você pode usar boards “mainline” (as oficiais do Zephyr) e ajustar o que precisar via app/boards.
Por que existe app/boards/ (e por que você vai amar isso depois)
A pasta app/boards/ é uma convenção para colocar ajustes específicos por board sem sujar seu prj.conf e sem “forkar” uma board oficial só para mudar meia dúzia de parâmetros.
Na prática você costuma ter dois tipos de arquivo ali:
app/boards/<board>.overlay
Ajustes de DeviceTree: troca de pinos, habilita periféricos, cria nós (leds,aliases,chosen), ajustastatus = "okay", etc.app/boards/<board>.conf(opcional)
Ajustes Kconfig específicos daquela board (ex.: habilitar um driver que só existe naquele hardware, mudar o backend de console, ligar uma feature de debug que só faz sentido na placa X).
Um detalhe importante e que evita 80% dos “não pegou”: o nome do arquivo precisa bater com o nome do target da board, e o overlay termina em .overlay. Esse padrão é ensinado bem diretamente em materiais de treinamento do ecossistema Zephyr.
Exemplo prático: criar um LED “do seu jeito” e piscar por DeviceTree
A ideia aqui é simples: você define no overlay um nó gpio-leds com um LED e cria um alias, e no C você pega esse LED por DT_ALIAS(...) / GPIO_DT_SPEC_GET(...).
Crie o overlay da sua board
Suponha que sua board seja nucleo_f411re (exemplo). Crie:
app/boards/nucleo_f411re.overlay
/ {
leds {
compatible = "gpio-leds";
user_led: led_0 {
gpios = <&gpioc 13 GPIO_ACTIVE_HIGH>;
label = "USER_LED";
};
};
aliases {
led0 = &user_led;
};
};
O que isso faz, em “português de firmware”:
- cria um nó
ledsdo tipogpio-leds(padrão do Zephyr) - define um LED chamado
user_led - mapeia o LED para
GPIOC pin 13(exemplo) e define polaridade ativa em nível alto - cria o alias
led0, que é o que seu código vai usar para ficar portável
Observação: os pinos corretos (porta/pino) variam por board. O exemplo acima é didático: você ajusta para seu hardware real.
(Opcional) Ajuste Kconfig específico da board
Crie:
app/boards/nucleo_f411re.conf
# Exemplo: garantir console e GPIO ativos para a placa em questão
CONFIG_GPIO=y
CONFIG_CONSOLE=y
CONFIG_UART_CONSOLE=y
CONFIG_PRINTK=y
Em muitos casos isso já estará no prj.conf; aqui a ideia é mostrar o mecanismo para quando você precisar ligar algo só em uma placa.
Código: pegando o LED por alias e piscando
Agora o main.c (ou um módulo seu) fica independente do pino. Ele só depende de “existe led0 no DeviceTree”.
app/src/main.c
#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/sys/printk.h>
/* led0 vem do alias definido no overlay */
static const struct gpio_dt_spec led = GPIO_DT_SPEC_GET(DT_ALIAS(led0), gpios);
int main(void)
{
if (!gpio_is_ready_dt(&led)) {
printk("LED nao esta pronto (verifique overlay/alias).\n");
return 0;
}
if (gpio_pin_configure_dt(&led, GPIO_OUTPUT_INACTIVE) < 0) {
printk("Falha ao configurar LED.\n");
return 0;
}
printk("Piscando LED via DeviceTree alias led0.\n");
while (1) {
gpio_pin_toggle_dt(&led);
k_sleep(K_MSEC(500));
}
}
Esse estilo é o “Zephyr way”: você não coloca #define LED_PIN 13 no código; você descreve hardware no DeviceTree e consome no C por macros DT.
“Meu overlay não pegou”: checklist curto que resolve quase tudo
Quando não funciona, normalmente é um destes:
- Nome do overlay não bate com o nome da board do build
Ex.: você builda com-b nucleo_f411re, mas o arquivo énucleo_f411re_v2.overlay(aí o build nem olha pra ele). - Você está buildando outra board sem perceber
Confere o comando:west build -b <board> app. - Você não fez pristine build depois de mexer em DTS
Use:west build -p always -b nucleo_f411re app(isso força reconfiguração e evita cache te enganando) - Alias não existe
Se você usaDT_ALIAS(led0)mas não crioualiases { led0 = ...; }, o build pode falhar (ou o símbolo não resolver).
Dica de ouro: overlays para console UART (quando você foge do default)
Quando você muda UART de console (ou quer usar outra instância/pinos), é comum precisar ajustar o nó chosen e/ou o nó do UART (status = "okay" e pinctrl). O template example-application existe justamente para te dar um lugar “limpo” de fazer isso sem fork da board.