Firmware ECU rodando em CI — 100% testável sem hardware

A lógica safety-critical do firmware da ECU (trigger, fueling, ignition, knock, safety) virou um workspace Rust no_std que roda inteiro em cargo test no CI. Zero hardware necessário pra provar invariantes.

A Proteus F7 ainda não chegou (importação leva tempo), mas isso não precisava parar o que dá pra fazer: praticamente toda a parte safety-critical do firmware é matemática pura sobre tabelas e estados, e matemática pura tem como ser provada em cargo test no CI.

Resultado: o ecu-firmware/core virou um crate no_std que compõe os módulos da ECU e roda 100+ testes unitários e de integração no CI a cada push, sem precisar de placa.

O que está coberto hoje

  • Trigger decoder 32-2 — máquina de estados Lost → Searching → Synced, detecta a “lacuna” da roda fônica pelo período mais longo entre flancos, sincroniza em 1-2 voltas.
  • Tabelas 1D e 2D com interpolação bilinear — base de todos os mapas (VE, AFR alvo, avanço, dwell, dead-time de injetor, multiplicador de ECT, knock threshold por RPM).
  • Conversões de sensor — NTC (ECT/IAT), MAP, TPS, lambda Bosch LSU 4.9.
  • Controlador PID — derivada-no-medido + anti-windup (clamp da integral). Usado em closed-loop de AFR e idle/boost.
  • Fueling speed-densitym_air = (MAP × V_cyl × VE) / (R × T_K), cold-start enrichment via tabela ECT, after-start decay linear, acceleration enrichment, dead-time de injetor compensado por Vbat.
  • Ignition — avanço por RPM × MAP com clamp de safety, dwell calculado por Vbat com upper bound pra não fritar bobina.
  • Knock detector — janela por cilindro com threshold variável por faixa de RPM. Sugere retard de spark advance no próximo ciclo.
  • Safety state machine — over-rev e over-temp com histerese (warning → limp → cutoff), nunca volta de cutoff sem evento manual.
  • Cooperative watchdog — cada subsistema (trigger, fueling, ignition, knock, safety) registra seu próprio deadline. Se algum deixar de pingar, o supervisor detecta e dispara fail-safe.
  • CAN protocol — encode/decode dos 15 IDs do docs/can-protocol.md v0.1, com versionamento embutido no byte 0.

Por que isso importa

Safety-critical em solo dev sem code review de outro embarcado sênior é receita pra desastre se você só descobre os bugs com a ECU na mão. Trigger decoder com bug detecta sincronia errada → injetor pulsa fora do TDC → motor não dá partida (ou pior, dá no cilindro errado e bate piston em válvula). PID com anti-windup quebrado → boost overshoot permanente.

Cada módulo é testado em CI contra o que tem que acontecer (TDC alinhado no decoder, AFR convergindo no PI, limp ativando antes do cutoff). Quando a Proteus chegar, não vou estar debugando lógica de mapa numa bancada com osciloscópio — vou estar validando o driver (o que é puramente hardware-side), não o algoritmo.

CI

GitHub Actions workflow ecu-firmware.yml roda a cada push em ecu-firmware/: cargo fmt --check, cargo clippy -- -D warnings (sem warnings, sem unwrap em produção — clippy enforça), cargo test. Tudo em ubuntu-latest, sem cross-compilação ainda — o no_std core compila no host pra testes; cross pra thumbv7em-none-eabihf virá com a Proteus.

O que falta

Drivers (HAL Embassy STM32, USB CDC console, ADC, timers para scheduling de injeção/ignição), bootloader USB pro flash via Tuner, adapter harness pra ECM Delphi original. Tudo isso depende de hardware em mão. A lógica não.

Lista de espera

Quer saber em primeira mão.

Pistonix está em desenvolvimento ativo. Inscreva-se pra receber atualizações de produto, basemaps prévios, convites pra rodar nos eventos do Milwaukee Garage Drag Racing e prioridade na lista de compra do Pistonix Forge.

  • Atualizações mensais de roadmap e firmware
  • Convite para sessões de tuning na pré-venda
  • Prioridade para o lote inicial do Pistonix Forge
  • Acesso antecipado a basemaps por motor

Ao se inscrever você concorda em receber emails do Pistonix. Não compartilhamos seu email. Você pode descadastrar a qualquer momento. (LGPD)