Développement firmware STM32 & RP2040

VérifiéSûr

Développer et maintenir le firmware pour le projet OpenSkyhawk avec STM32 (PanelBridge, PanelGroup) et RP2040 (SimGateway). Comprend PlatformIO, protocole CAN, intégration DCS-BIOS et gestion des panneaux.

Spar Skills Guide Bot
DeveloppementAvancé
22/07/2026
Claude CodeCursorCodex
#firmware#embedded#stm32#rp2040#can-bus

Recommandé pour

Synthèse automatique

Encadre le développement du firmware OpenSkyhawk (STM32 PanelBridge/PanelGroup et RP2040 SimGateway) en imposant l'architecture à trois niveaux, les conventions NODE_ID et le recours aux spécifications FirmwarePlan/TechSpec.

Points forts

  • Cartographie documentaire précise qui évite de charger toute la spécification et oriente vers le seul document pertinent
  • Conventions durables explicites : NODE_ID en build_flags, variantes STM32F103C8/CB, accès aux expandeurs via classes et non via registres
  • Séparation nette des responsabilités avec les skills voisins (pcb-design pour le câblage électrique, Doxygen obligatoire sur l'API publique)
  • Garde-fou sur l'absence des specs dans un checkout partiel, avec repli sur les conventions et le code de Firmware/Libraries/

Limites

  • Fortement couplé au dépôt OpenSkyhawk : hors de ce contexte, la majorité des chemins et conventions ne s'appliquent pas
  • Le SKILL.md fourni est tronqué, la section sur l'organisation library/test s'arrête en cours de phrase
  • Suppose une connaissance préalable de l'embarqué (CAN, MCP23017, ADS1115) : peu d'explications de fond, surtout des règles de projet
Quand l'utiliser

À utiliser dès qu'une tâche touche au firmware OpenSkyhawk, à un projet PlatformIO, au protocole CAN, à l'attribution d'un NODE_ID ou aux classes d'entrée/sortie PanelGroup.

Quand l'éviter

À éviter pour du développement embarqué générique hors OpenSkyhawk ou pour la conception du câblage électrique des cartes, qui relève du skill pcb-design.

Analyse de sécurité

Sûr
Score qualité78/100

This is a purely declarative documentation/router skill for an avionics-simulator firmware project. It contains no executable commands, no shell invocations, no network fetches, no credential handling, and no destructive operations. The only tool reference is a CI checker script mentioned descriptively. Listing it poses no execution risk.

Aucun point d'attention détecté

Comment cette analyse est faite

Exemples

Add a new PanelGroup node
I need to add a new PanelGroup node for the caution-light panel. Claim the next free NODE_ID in Firmware/NODE_IDS.md, create the PlatformIO project with -DNODE_ID in build_flags, and implement the two switches and one LED using the PanelGroup input/output classes as described in 05-panelgroup-api.md.
Debug CAN control packets
PanelGroup node 7 never receives control packets from PanelBridge. Read 02-can-protocol.md and 09-startup-resync-diagnostics.md, then explain how NODE_ID filtering and the SYNC_REQ/READY handshake should behave and where my implementation likely diverges.
Add an analog axis to SimGateway
Add a new analog axis to the RP2040 SimGateway for the radar elevation knob: use the HIDAxis class per 07-simgateway-api.md, wire it to the ADS1115 through the existing firmware class, and add the matching test sketch under the library test layout.

name: firmware description: OpenSkyhawk firmware — STM32 (PanelBridge, PanelGroup) and RP2040 (SimGateway). Use when writing or changing firmware, PlatformIO projects, CAN protocol, NODE_ID assignment, DCS-BIOS integration, HID, panel sketches, shared libraries or their test sketches, or interacting with MCP23017/ADS1115 through the firmware classes (PanelGroup input/output classes). PanelGroup work is the most common interaction.

Firmware

Three-tier architecture:

PC ──USB HID + USB CDC(250k)── RP2040 SimGateway ──UART 250k── STM32 PanelBridge (NODE 0, CAN master)
                                                                      └─CAN 500k─ PanelGroup nodes (NODE 1–63)

Authoritative spec — route here, don't bulk-load

Firmware/ScratchPad/FirmwarePlan/ is the authoritative firmware specification (the what: contracts, data flows, decisions) and supersedes any firmware content in docs/_source/. Firmware/ScratchPad/TechSpec/ holds the how (public API, class structure, method signatures). Open the one relevant doc via the maps below rather than reading everything.

FirmwarePlan document map (read FirmwarePlan/README.md for the full index):

  • 00-decisions.md — why each choice was made
  • 01-system-overview.md — topology, library roles, data-flow narrative
  • 02-can-protocol.md — CAN frame IDs, NODE_ID, ControlPacket wire format, TX queue
  • 03-uart-usb-hid-protocol.md — UART mux, HID frame format, USB identity
  • 04-dcs-bios-integration.md — controlId space, DCSIN_*, input-map generator rules
  • 05-panelgroup-api.md — PinRef, MCP23017 management, all input & output classes
  • 06-panelbridge-api.md — node tracking, export listener, input dispatch, SYNC_REQ
  • 07-simgateway-api.md — HIDAxis/HIDButton, relay contract, HID dispatch
  • 08-hardware-firmware-contracts.md — STM32 pin assignments, DRV8833 ~SLEEP, ADS1115
  • 09-startup-resync-diagnostics.md — boot sequences, SYNC_REQ/READY, DIAG frames
  • 10-implementation-plan.md / 11-open-issues.md — phased plan / deferred items

TechSpec: one file per library/class (CANProtocol, STM32Board, PanelBridge, SimGateway, HIDControls, A4ECGenerator, and PanelGroup/{PinRef, PanelGroup, Inputs/*, Outputs/*}). Each cites its FirmwarePlan section. See TechSpec/README.md.

Availability guard: these specs are committed but may be absent in a partial checkout — if Firmware/ScratchPad/FirmwarePlan/ is missing, rely on the conventions below plus the committed code under Firmware/Libraries/.

Durable conventions (always apply)

  • MCU variant: STM32F103C8 (64 KB) is the default for CAN avionics nodes; use STM32F103CB (128 KB) only where flash demands it (PanelBridge runs the full DCS-BIOS input map). Use full part numbers in prose, never the CBT6 ordering code or C8/CB shorthand.
  • NODE_ID: compile-time only — build_flags = -DNODE_ID=N in platformio.ini, never a #define in main.cpp. 0 = PanelBridge; 1–63 = PanelGroup nodes. Claim the next free number in Firmware/NODE_IDS.md in the same PR that starts the work; never reuse one. tools/check_node_ids.py enforces this in CI.
  • Expander access is via classes, not registers: the PanelGroup library owns MCP23017 integration; ADS1115 via ADS1115.h. Instantiate input classes (Switch2Pos, Switch3Pos, RotarySwitch, SwitchMultiPos, AnalogInput, RotaryEncoder, …) and output classes (LED, IntegerOutput, SwitecX25Output, …) on a PinRef. The electrical wiring of those parts belongs to the pcb-design skill.
  • Timing: each class calls millis() directly and keeps its own uint32_t timestamp — no shared clock.
  • Docblocks: Doxygen style on every public class/method/enum/non-obvious constant (@brief, @param with units, @return, @note for ISR/timing constraints). Private members use plain //.
  • Library + test layout: each library is Firmware/Libraries/<Name>/ with a library.json; its tests are a standalone project Firmware/Tests/<Name>/ using src_dir = tests, an [env_base] section, and one build_src_filter per scenario. See TechSpec/README.md.
  • Implementation order (dependencies flow down): HIDControls → A4EC → CANProtocol → STM32Board → PanelBridge / SimGateway → PanelGroup (PinRef → PanelGroup → Inputs/Outputs).
  • Header ownership — keep shared headers single-purpose. HIDControls.h is HID controlId constants only; CANProtocol.h owns CAN frame transport (incl. NodeHealthPayload). The cross-node status contract — NODE_STATUS_* (DCS-BIOS reporting), NodeHealthFlag, NodeFaultCode, and FaultSource — lives in the neutral NodeStatus library, because every node type shares it (PanelGroup, PanelBridge, PDU) and it's broader than "health." Never shape a cross-node contract around one flavor (PanelGroup.h/OutputBase) or the HID namespace (D14).
  • Fault sources feed a node aggregator; no producer owns node health. A fault-producing object (DrumDisplay, a PDU rail monitor, a PanelBridge host-link watchdog) inherits OpenSkyhawk::FaultSource (NodeStatus.h), self-registers, and reports cached faultCode() (a NodeFaultCode) + local faultDetail() (DiagSerial-only string, never on the wire). The node-level aggregator walks FaultSource::head() → sets HEALTH_n.faultId + DEGRADED. OutputBase gets no fault API — an output is just one possible fault source, not special.
  • Includes: direct for what you use, but don't couple upward. Prefer a direct #include of a symbol's defining header over relying on a fragile transitive path — but if adding that include would drag a low-level/UI class into a heavier or conceptually-wrong layer, that's a signal the symbol is placed wrong (see the two rules above), not that you should hide it behind a transitive include. Don't add an include already reliably provided by a header the file must include anyway.
  • Spec-sync in the same PR. Any change to a public firmware API — struct/enum, class method, wire format, #define contract — updates the authoritative FirmwarePlan/ + TechSpec/ doc in the same PR, listed as a deliverable and self-checked before push. The spec is source of truth; drift defeats it. Grep the old value/claim before pushing.
  • Toolchain: PlatformIO. STM32 = platform = ststm32, framework = arduino. RP2040 = earlephilhower core with -DUSE_TINYUSB.
  • C++ standard: any project using DrumDisplay needs -std=gnu++20 + build_unflags = -std=gnu++17 — its DrumReadout descriptors are C++20 designated initializers. Already baked into the PanelGroup scaffold template, so B6 sketches get it by default; add it explicitly to a standalone test project. The whole PanelGroup dep stack (U8g2 / MCP23017 / ADS1X15) is gnu++20-clean.

Verify

Build the affected project(s) with platformio run -d <project>; exercise each class in isolation via its Firmware/Tests/<Name>/ sketch before integration.

Du fichier au premier essai

Le téléchargement contient exactement le contenu affiché sur cette fiche. Cette copie peut différer de la dernière version du dépôt source.

Consulter la source et ses fichiers annexes

Ce téléchargement contient uniquement SKILL.md. Les scripts, références, modèles et dépendances éventuels ne sont pas inclus. Récupérez les fichiers nécessaires depuis la source en conservant leur arborescence avant de poursuivre.

1. Télécharger le fichier

Télécharger SKILL.md

Depuis la racine d’un projet de test, enregistrez le fichier sous .skill-downloads/stm32-rp2040-firmware-development-mrwak9ej/SKILL.md, ou utilisez la commande suivante. Ce dossier sert à examiner la skill avant son installation.

Commande pour macOS/Linux ou WSL : un shell POSIX et curl sont nécessaires. Sous Windows sans WSL, utilisez le bouton de téléchargement et créez le dossier manuellement.

mkdir -p '.skill-downloads/stm32-rp2040-firmware-development-mrwak9ej' && curl --fail --show-error --location 'https://skills-guides.com/api/skills/stm32-rp2040-firmware-development-mrwak9ej/download' --output '.skill-downloads/stm32-rp2040-firmware-development-mrwak9ej/SKILL.md.part' && mv '.skill-downloads/stm32-rp2040-firmware-development-mrwak9ej/SKILL.md.part' '.skill-downloads/stm32-rp2040-firmware-development-mrwak9ej/SKILL.md'

2. Vérifier les prérequis

Lisez SKILL.md avant de l’utiliser. Si le fichier cite des scripts ou services externes, examinez-les et préparez les accès nécessaires dans votre environnement de test.

Aucune section de prérequis reconnue dans ce fichier. Cela ne signifie pas qu’il est autonome : les bibliothèques, outils et accès peuvent être cités ailleurs dans le contenu ou dans le dépôt source.

Les plateformes de la fiche sont des indications du catalogue. Les chemins ci-dessous suivent la documentation des outils ; ils ne prouvent pas que cette skill y a été exécutée. Aucune version minimale de ces outils n’est attestée pour cette fiche.

3. Charger la skill

Après vérification, copiez le dossier complet dans le projet avec l’une des commandes ci-dessous, puis ouvrez une nouvelle session de l’outil. La commande s’arrête si un dossier du même nom existe déjà : comparez les fichiers avant de le remplacer.

Claude Code
test -f '.skill-downloads/stm32-rp2040-firmware-development-mrwak9ej/SKILL.md' && test -s '.skill-downloads/stm32-rp2040-firmware-development-mrwak9ej/SKILL.md' && mkdir -p '.claude/skills' && test ! -e '.claude/skills/firmware' && cp -R '.skill-downloads/stm32-rp2040-firmware-development-mrwak9ej' '.claude/skills/firmware'

Cursor
test -f '.skill-downloads/stm32-rp2040-firmware-development-mrwak9ej/SKILL.md' && test -s '.skill-downloads/stm32-rp2040-firmware-development-mrwak9ej/SKILL.md' && mkdir -p '.cursor/skills' && test ! -e '.cursor/skills/firmware' && cp -R '.skill-downloads/stm32-rp2040-firmware-development-mrwak9ej' '.cursor/skills/firmware'

Codex
test -f '.skill-downloads/stm32-rp2040-firmware-development-mrwak9ej/SKILL.md' && test -s '.skill-downloads/stm32-rp2040-firmware-development-mrwak9ej/SKILL.md' && mkdir -p '.agents/skills' && test ! -e '.agents/skills/firmware' && cp -R '.skill-downloads/stm32-rp2040-firmware-development-mrwak9ej' '.agents/skills/firmware'

OpenSkills

OpenSkills doit déjà être installé. La procédure locale install/read est contrôlée avec OpenSkills 1.5.0, qui exige Node.js ≥ 20.6.0. Aucun slug du catalogue n’est résolu automatiquement.

Installation officielle d’OpenSkills
openskills install './.skill-downloads/stm32-rp2040-firmware-development-mrwak9ej'

openskills read 'stm32-rp2040-firmware-development-mrwak9ej'

La lecture doit afficher le contenu du fichier installé et son dossier de base. Elle ne lance ni la skill ni ses dépendances.

Pour un agent qui lit AGENTS.md, synchronisez ensuite l’index. Cette commande modifie AGENTS.md : relisez le diff avant de l’utiliser.

openskills sync

Mode manuel ou autre outil : joignez SKILL.md à une conversation, ou ouvrez-le dans un agent capable de lire les fichiers. Ajoutez les ressources annexes nécessaires. Il n’existe pas de dossier universel reconnu par tous les outils.

4. Faire un premier essai

Utilisez une entrée courte et fictive : un endpoint d’API, un petit document ou un brief d’interface. Dans une nouvelle conversation, joignez le fichier ou donnez son chemin à l’agent, puis adaptez cette demande :

Lis .skill-downloads/stm32-rp2040-firmware-development-mrwak9ej/SKILL.md et applique ses instructions à cet exemple : [décrire une entrée de test]. Indique les fichiers, dépendances ou accès qui manquent. Produis le résultat demandé par la skill sans inventer de données ni exécuter de script non examiné.

Résultat attendu : une sortie correspondant aux instructions de la skill, ou une liste précise des prérequis manquants. Une simple confirmation de lecture ne valide pas le premier usage. Si une ressource externe est indisponible, ce parcours reste à tester.

Skills similaires