Nutz95/SOLID-C++-ESP32

SOLID C++ / ESP32 Firmware Guardrails: Datei-/Klassengrößen, keine verschachtelten Klassen, strikte DI an Kompositionswurzeln, keine UNIT_TEST / Test-Ifdefs in Produktions-Headern (und vermeide sie in .cpp), keine hartcodierten Geheimnisse, ein Typ pro öffentlichem Header, öffentliche API ///-Kommentare, Dual-Core-Funk-Pinning (PRO_CPU 0 / APP_CPU 1), FreeRTOS-sichere Muster. Verwenden beim Bearbeiten von ESP-IDF-, Arduino-ESP32-, PlatformIO-Firmware oder ESP-NOW-/BLE-/WLAN-Aufgaben.

Was ist SOLID-C++-ESP32?

Diese Fertigkeit definiert eine Reihe strenger Guardrails für die Entwicklung von ESP32-Firmware in C++ mit Fokus auf SOLID-Prinzipien, testbare Architektur und FreeRTOS-Bewusstsein. Sie erzwingt harte Limits wie maximale Dateigröße von 400 Zeilen, maximal 30 Methoden pro Klasse und verbietet verschachtelte Klassen sowie hartcodierte Geheimnisse. Ein zentrales Merkmal ist das strikte Verbot von Test-Instrumentierung (#ifdef UNIT_TEST) in Produktions-Headern und .cpp-Dateien, das durch Dependency Injection (Interfaces wie `I*` mit konkreten Adaptern nur in der Kompositionswurzel) ersetzt wird. Die Fertigkeit unterstützt Plattformen wie ESP-IDF, Arduino-ESP32 und PlatformIO und enthält spezifische Richtlinien für Dual-Core-FreeRTOS (WiFi/BT auf Core 0, schwere App-Arbeit auf Core 1) sowie einen Validierungs-Checklist. Sie ist ideal für Entwickler, die saubere, wartbare und testbare ESP32-Firmware-Projekte erstellen oder warten.

Funktioniert mit~Claude Code~Codex CLI✓Cursor
npx skills add https://github.com/Nutz95/CursorCodingSkills/tree/HEAD/skills/solid-cpp-esp32

Installed? Explore more Produktivität & Zusammenarbeit skills: steipete/gemini, steipete/gh-issues, steipete/skill-creator · View all 6 →

In Ihrer bevorzugten KI fragen

Öffnet einen neuen Chat, in dem dieser Agent-Skill bereits geladen ist.

Dokumentation

SOLID C++ ESP32

Harte Grenzen

  • Bevorzuge Dateien unter 400 Zeilen; teile auf, wenn eine Übersetzungseinheit mehrere Verantwortlichkeiten erhält
  • Maximal ~30 Methoden pro Klasse
  • Bevorzuge Funktionsrümpfe unter ~60 Zeilen (hilfsweise auslagern)
  • Keine verschachtelten Klassen — verschiebe innere Typen in einen eigenen Header / eigene Übersetzungseinheit
  • Genau ein primärer Typ (class / struct / enum / enum class) pro öffentlichem Header, wenn das Projekt dies vorsieht (Hochlauf / strikte Oberflächen)

Sprache & Stil

  • Commitierter Code / Kommentare / Dokumentation in Englisch
  • Verwende immer geschweifte Klammern für if / for / while / switch
  • Keine einzeiligen Funktionsrümpfe für nicht-triviale Logik
  • Beschreibende Namen (telemetryManager, nicht mgr / tmp außer bei trivialen Schleifenzählern)
  • Bevorzuge einen namespace-Block pro Übersetzungseinheit
  • Header deklarieren die Absicht; .cpp-Dateien bleiben schlicht und direkt
  • Öffentliche Methoden in I*.h-Schnittstellen (und anderen optierten öffentlichen Headern) benötigen einen einzeiligen ///-Absichtskommentar

Architektur (SOLID + DI)

  • Bevorzuge Schnittstellen (I*) an Domänengrenzen
  • Hänge in Anwendungs-/Domänencode von Abstraktionen ab; konstruiere konkrete Adapter nur in main.cpp oder einer expliziten Kompositionswurzel
  • Hardware (BLE, WLAN, Display, NVS, Busse) bleibt hinter Schnittstellen, sodass Host-Komponententests Fakes verwenden – nicht #ifdef-Operationen
  • Bevorzuge kleine, reine Parser, die in native-/Host-Builds komponententestbar sind
  • Bevorzuge Komposition gegenüber wachsenden God-Objekten
  • Caste FreeRTOS void* sofort in einen benannten, typisierten Zeiger
  • Bevorzuge Projekt-Hilfsfunktionen (z. B. sicheres C-String-Kopieren) gegenüber strncpy-Varianten

Domänen-/Schichten-Isolation

  • Halte Hub-exklusive Stacks (Web, Auth, OTA, HTTP-API) von Bridge-/Leaf-Zielen fern
  • Führe keine #include von konkreten Adapter-Headern aus der falschen Schicht durch; wenn ein Guardrail Adapternamen auflistet, befolge es

Keine Testinstrumentierung in Produktions-APIs

Produktionscode darf nicht durch Test-Build-Flags geformt werden.

  • Verboten in Headern und .cpp: UNIT_TEST, #ifdef UNIT_TEST, #ifndef UNIT_TEST, #if defined(UNIT_TEST) oder jegliche äquivalente Test-Only-Abschottung (esp_cpp_guardrails schlägt standardmäßig hart fehl)
  • Bevorzuge DI: Extrahiere eine Schnittstelle, injiziere einen Fake in Host-Tests, oder schließe Geräteadapter-Übersetzungseinheiten vom native/Host-build_src_filter aus – niemals Produktionsquellen mit Ifdefs stutzen
  • Plattformerkenner (__has_include(<esp_random.h>), ESP_PLATFORM) sind in Ordnung; Test-Build-Flags, die Produktionslogik umformen, sind es nicht
  • Behalte portable Typen in Headern (std::mutex usw.) oder bedingungslose gerätespezifische Includes in gerätespezifischen Übersetzungseinheiten

Geruch → Behebung:

GeruchBehebung
#ifndef UNIT_TEST um WLAN-/BLE-Aufrufe in einem DienstInjiziere IWifiConnector / IBleClient; Fakes in Host-Tests
Header stutzt unterschiedliche Typen, wenn UNIT_TESTImmer portabler Typ, oder Geräteadapter aufteilen
God-Klasse benötigt Ifdefs, um auf Host zu kompilierenVerantwortlichkeiten aufteilen; Kompositionswurzel verdrahtet Adapter

Geheimnisse

  • Niemals WLAN-Passwörter, OTA-/Web-Passwörter, Gerätegeheimnisse, PMKs, Tokens oder LAN-Anmeldeinformationen in Quellen hartcodieren
  • Injiziere Geheimnisse über Umgebungsvariablen / Build-Flags, die von PlatformIO (oder Äquivalent) konsumiert werden – committe niemals .env mit echten Geheimnissen

Dual-Core-FreeRTOS (ESP32)

Klassischer ESP32 hat zwei Kerne:

KernIDTypische Verwendung
PRO_CPU0WLAN / BT / funknahe Arbeiten (ESP-NOW TX/RX-Schleifen, BLE/SPP-Funkaufgaben)
APP_CPU1Schwerere App-Arbeit: Display-UI, HTTP/Web, Parsing-Stöße, SD, nicht funkbezogene Schleifen

Standardeinstellungen (nur mit dokumentiertem Sonderfall überschreiben):

  • Hefte funk-/stackempfindliche Aufgaben mit xTaskCreatePinnedToCore(..., kRadioCoreId) an, wobei kRadioCoreId = 0
  • Hefte UI / schwere nicht-funkbezogene Aufgaben an kAppCoreId = 1
  • Vermeide lange blockierende Arbeit auf Kern 0; es hungert den Funk-Stack aus
  • Bevorzuge benannte Konstanten (kRadioCoreId / kAppCoreId) gegenüber magischen 0 / 1

Validierung

  • Führe das Guardrail-Skript des Projekts (oder tools/esp_cpp_guardrails) nach strukturellen Änderungen aus
  • Füge die kleinste Host-/Komponentenprüfung hinzu, die fehlschlägt, wenn neue Logik bricht
  • Baue nach Schnittstellenänderungen
  • Aktualisiere README, wenn sich Verhalten, Skripte, Hardwareannahmen oder Architektur ändern
  • Bevorzuge eine blockierende Code-Qualitätsüberprüfung vor dem Zusammenführen, wenn das Projekt dies erfordert

Checkliste

  • Geschweifte Klammern überall; englische Bezeichner/Kommentare
  • Unter ~400 Zeilen / ~30 Methoden; keine verschachtelte Klasse
  • Konkrete Adapter nur an der Kompositionswurzel; Domäne hängt von I* ab
  • Kein UNIT_TEST / Test-Ifdefs in Headern; vermeide sie in .cpp
  • Keine hartcodierten Geheimnisse
  • /// bei neuen öffentlichen Schnittstellenmethoden
  • Funkaufgaben auf Kern 0; schwere App-Arbeit auf Kern 1 (außer dokumentierte Ausnahme)
  • Guardrails / Tests grün

Individual skills in this repo

This repo contains 3 individual skills — each has its own dedicated page.

Verwandte Skills