dunot: C de baixo nível, makefile e disciplina — sem inventar o jogo

dunot é repositório privado. O que eu afirmo com segurança é o que cabe na mesa: um dunot.c, um makefile, um README com arte ASCII. Não abro aqui um inventário de fases, inimigos, rede ou engine — porque isso seria ficção. Trato o projeto como estudo de C de baixo nível / experimento lúdico de console, e desvio o texto para o que realmente transfere para painel, PIC e STM32: toolchain, make e disciplina de código.

Por que um C “só de terminal” ainda importa

A tentação do tecnólogo que já piscou LED no PIC18 e já gravou 328P no WSL é achar que C de host é descanso. Não é. No MCU você negocia com registrador e com Flash. No host você negocia com libc, locale, buffering de stdout, inteiro de tamanho certo e o fato de que make é o contrato. O músculo é o mesmo: um arquivo, uma regra, um binário reproduzível.

Eu uso esse tipo de experimento — nome dunot, arte ASCII no README — como laboratório de higiene, não como produto. ASCII no README é honesto: o programa se apresenta como texto. Não há captura de tela de engine, não há loja, não há métrica de download. O site da Wilson Tecnologia também não precisa disso para justificar o estudo.

O que eu não faço neste artigo: descrever gameplay, inventar teclas, afirmar que há mapa, física, save ou placa de LED. Se o dunot.c for um loop de console com putchar e um makefile de uma regra, já basta para a tese.

A unidade mínima: dunot.c

Um único .c na raiz (ou como alvo do make) é uma escolha pedagógica. Força:

  1. Fronteira visível. Tudo o que o programa faz está num arquivo. Não há “módulo mágico” para esconder gambiarra.
  2. Dependência explícita. #include <stdio.h> é contrato com a libc. #include "minha.h" seria outro arquivo — e outro arquivo teria de aparecer no make. Enquanto for um .c, o grafo é uma aresta.
  3. Tamanho como alarme. Quando o arquivo passa de algumas centenas de linhas, o próprio autor sente a dívida. No PIC da Fatec isso já virou UART.c, lcd_16x2.c, Hardware.c. No dunot, o exercício é aguentar a tensão antes de fatiar — ou fatiar de propósito, com o makefile acompanhando.

C de baixo nível, neste contexto, não significa assembly inline. Significa: tipos da <stdint.h> quando o tamanho importa, cuidado com signed/unsigned (o LCD da Fatec ainda me lembra o -100 em unsigned int), buffers com tamanho, e nenhum system("cls") como se fosse API portátil.

Nota de bancada (host). Compilar com -Wall -Wextra -Werror uma vez por sessão dói e ensina. O avr_mcu já usa -Wall -Os no 328P. O host não tem desculpa para menos. -pedantic e -std=c11 (ou c99, se o curso pediu) evitam o dialeto “GCC na minha máquina”. O XC8 da bancada PIC é outro dialeto; por isso o hábito de padrão explícito importa nos dois mundos.

makefile: o mesmo contrato do blink AVR

Se o pic_mcu vive dentro do MPLAB X e o arm ainda é só apt de toolchain, o dunot alinha com o avr_mcu: o make é o produto. Um makefile mínimo de host parece com isto — e eu descrevo o padrão, não um arquivo que não vou transcrever:

  • variável CC, CFLAGS, TARGET;
  • regra $(TARGET): dunot.c;
  • clean que apaga o binário.

O valor não é a originalidade da receita. É a reprodução. Qualquer máquina com make e um GCC/Clang entrega o mesmo jogo-ou-demo. IDE que esconde o comando de link gera o clássico “na minha máquina abre”. No comissionamento de painel o análogo é o projeto do CLP que só abre na versão X do software com o pack de hardware Y. Versionar o comando é um ato de respeito com o eu do ano que vem.

Hábitos que eu cobro de um makefile de estudo, sejam no 328P ou no dunot:

  • .PHONY: clean all — para clean não colidir com arquivo de mesmo nome.
  • flags no CFLAGS, não cravadas só na cabeça do autor.
  • um alvo run opcional (./dunot) se o README com ASCII convidar a executar. Opcional: o repo pode não ter.
  • não commitar o binário. Artefato se reconstrói. O README ASCII é fonte; o ELF não é.

Se o dunot crescer para dois .c, o makefile deixa de ser cerimônia e vira grafo. Aí o paralelo com o Task Manager da Fatec fica óbvio: unidade de tradução, header, guarda de include. O PDF de estilo C do curso existe para isso.

Arte ASCII no README: documentação como interface

README com ASCII art é uma escolha de tom. Em repositório lúdico, o banner é a embalagem. Em repositório de firmware, eu prefiro pinout e comando de gravação — o avr_mcu faz isso em texto puro; o arm cabe em três linhas. Os dois estilos são válidos se forem verdadeiros.

O risco do banner é cobrir a falta de instrução. Um README honesto de estudo C, mesmo privado, ainda precisa de:

  • como compilar (make);
  • dependência (libc, ncurses? se não está no repo, não afirmo);
  • o que o programa não é.

Como não vou inventar dependência, a instrução padrão permanece: make e um compilador C de host. Se amanhã o dunot.c incluir uma lib que o make não linka, o README ASCII deixa de ser charme e vira dívida. A mesma regra vale para o “SPI //coming soon” do pic_mcu.

Disciplina de código que transfere para o ferro

A lista abaixo é princípio, não feature do dunot. É o que eu cobro de qualquer C que eu ainda queira ler daqui a cinco anos — no console, no PIC18 ou num stub de STM32.

  1. Entrada e saída com política. printf sem flush em laço apertado mente sobre tempo. No MCU, UART com buffer cheio mente igual. No CLP, o TRACE no ciclo livre também mente.
  2. Tempo. sleep / busy-wait no host é o _delay_ms do AVR. Serve para demo. Não serve para modelo de tempo real. Se o experimento lúdico usa delay para animar ASCII, o autor precisa saber que está animando, não escalonando.
  3. Erro é valor de retorno. malloc que não se checa, fopen que não se checa: no host o programa morre; no MCU o heap (se houver) corrompe o stack. Preferir buffer estático em estudo pequeno é escolha adulta.
  4. Nomes e um arquivo de estilo. O PDF da Fatec e um .clang-format mínimo são primos. Privado não é desculpa para a1, a2, temp2.
  5. Comentário que não diverge. O blink AVR ainda hoje diz “500 ms” ao lado de _delay_ms(1000). Comentário é parte do produto. ASCII art no README que promete o que o .c não faz é o mesmo bug em fonte maior.

Ponte industrial. Ladder mal comentado em painel de prensa é mais perigoso que um console lúdico. A disciplina, porém, é uma só: o próximo técnico precisa entender a intenção sem telepatia. Eu levo o makefile do estudo para o hábito de ter um “como buildar” em todo firmware. Levo o .c único para o respeito de não fatiar cedo demais nem tarde demais.

Armadilhas da toolchain de host (make, GCC/Clang, libc)

Estudo de console parece “mais fácil que MCU”. As armadilhas mudam de forma, não de família.

Makefile sem .PHONY. Se existir um arquivo chamado clean, make clean não limpa — “não faz nada” e o autor culpa o shell. No AVR o mesmo padrão aparece; no host a densidade de arquivos na pasta é maior e o acidente é mais comum.

Tabs versus espaços. Make exige tab real na receita. Editor que converte tab em espaço quebra o build com erro críptico. Em WSL/Windows, checkout com core.autocrlf errado ainda injeta \r e o make fala em “missing separator”. O diário de bancada deve anotar cat -A makefile | head quando o erro aparecer — o mesmo rigor do cabo SWD invertido.

GCC versus Clang e flags silenciosas. -Wall não é portátil no detalhe; -Werror num CI com versão diferente da do notebook transforma aviso novo em vermelho. Pine o compilador no README (gcc --version / clang --version) como o Fatec pinou XC8 1.45.

Locale e UTF-8. ASCII art no README é ASCII; string no programa com acento sem locale definido vira mojibake no terminal do colega. Em painel industrial o análogo é HMI com code page errado: o operador lê alarme trocado. Estudo lúdico que só usa ASCII de 7 bits evita a dor — e ensina a decidir encoding de propósito.

Buffering de stdout. printf + laço sem \n e sem fflush parece programa travado. No MCU, TX sem empty-check parece igual. Quem aprende a forçar flush no host reconhece o problema na UART do PIC/STM32 mais rápido.

Biblioteca “óbvia” não linkada. Se alguém adicionar matemática (-lm) ou curses sem atualizar o makefile, o erro de link é progresso — desde que o README não continue dizendo “só make”. Dependência fantasma é o primo do “coming soon” no firmware.

Sanitizers como rede de estudo. -fsanitize=address,undefined no host (quando a plataforma permite) pega o class de bug que no MCU vira HardFault sem stack útil. Não transformo isso em requisito do dunot; registro como ferramenta de sessão de higiene.

Analogias industriais: make como contrato de fábrica

O makefile do dunot não controla linha de montagem. O conceito de contrato de build sim:

  • Receita reproduzível. make no estudo ↔ script de build na CI de firmware ↔ export versionado do projeto de CLP. Se só a IDE da bancada “sabe” gerar o binário, a fábrica herda risco.
  • Alvo clean. Apagar artefato ↔ limpar Output/Dist do MPLAB ↔ não arquivar .o no Git. Artefato sujo gera falso positivo de “já estava compilando”.
  • Flags explícitas. -std=c11 -Wall no host ↔ opções de XC8/avr-gcc no README ↔ opções de compilação salvas no projeto industrial. O que não está escrito não existe na auditoria.
  • Um binário, muitas estações. O colega clona e builda ↔ o técnico de manutenção abre o projeto na versão documentada. “Na minha máquina funciona” é o inimigo comum de console, MCU e painel.
  • Documentação verdadeira. Banner ASCII honesto ↔ sinótico de IHM que mostra o estado real. Mentira estética (README ou tela) custa confiança igual.

No quadro, ninguém vai “jogar dunot”. Vai precisar do mesmo reflexo: como eu reconstruo o que está rodando?

Roteiro de estudo (higiene de C, sem inventar o jogo)

Como o repo é privado e eu não invento features, o roteiro é de disciplina, aplicável a qualquer dunot.c mínimo:

  1. Sessão build limpo. make clean && make duas vezes; segunda deve ser no-op ou relink previsível. Anotar compilador e OS.
  2. Sessão warnings. Ligar -Wall -Wextra; zerar avisos antes de adicionar linha nova. Se -Werror for demais no dia, use-o pelo menos numa branch de higiene.
  3. Sessão tipos. Trocar literais mágicos por stdint.h onde o tamanho importa; revisar casts signed/unsigned (lição do LCD Fatec).
  4. Sessão I/O. Identificar todo printf/putchar em laço; decidir flush ou newline. Medir “na mão” se a animação ASCII depende de busy-wait — e nomear isso no comentário.
  5. Sessão fronteira. Se o arquivo passou do conforto, fatiar com o makefile (dois .c, um .h, guarda de include). Não fatiar só por estética.
  6. Sessão README. Banner ASCII + três linhas: build, run, “isto não é…”. Remover qualquer promessa que o código não cumpra.
  7. Sessão ponte. Escrever num notes/ (mesmo privado): uma prática deste C que você vai exigir no próximo firmware PIC/AVR/ARM. Uma basta.

Critério de sucesso do roteiro: outro eu, daqui a um ano, builda sem perguntar no chat — e não acredita em feature que o Git não mostra.

O que isto não é — sobretudo ASIL

dunot não é item de segurança. Não é ECU, não é runtime de CLP, não é evidência ISO 26262 nem ISO 13849. Um programa de console — mesmo que seja um joguinho, mesmo que seja um gerador de ASCII — vive em QM informal: autor, makefile, compilador de desktop.

Este estudo cobre Este estudo não cobre
C de host, um .c, um make Requisitos, HARA, ASIL A–D
Higiene de compilação e README verdadeiro Certificação de ferramenta
Transferência de hábito para MCU/CLP Tempo real, watchdog, dual-channel
Tom lúdico (ASCII) sem fingir produto Métrica de usuário, loja, tráfego
Contrato de build reproduzível MISRA oficial, MC/DC, qualificação de compilador

A frase “eu programo C, logo posso assinar software de direção” é o mesmo salto que “eu pisquei PWM no 16F628A, logo faço torque vectoring”. O dunot ajuda no primeiro degrau: ler o próprio C sem IDE-mãe. O degrau ASIL é processo, hardware-alvo e evidência. Nenhum banner ASCII substitui isso.

Limites honestos

  • Repo privado: não publico trechos longos do dunot.c nem inventário de funções.
  • Não afirmo dependência (ncurses, SDL, threads) que não esteja evidenciada no estudo.
  • Não há gameplay, telemetria de jogadores nem captura de tela.
  • Não uso métricas inventadas de “linhas de código” ou “bugs corrigidos” para enfeitar.
  • Este artigo ensina o contrato ao redor do experimento lúdico; não substitui o código-fonte.

Fechamento

Repositório privado, dunot.c, makefile, README com arte ASCII: estudo de C, provavelmente um experimento de console, deliberadamente sem ficha de features. O texto que vale a pena extrair daí não é o enredo — é o contrato de build e a recusa de inventar o que o Git não mostra. No restante da série (PIC, AVR, ARM, Fatec) o silício muda. A disciplina não deveria mudar.