agentsclimarketplace

Embedded project setup

Skill Victory-7291/project-scaffold-setup-skills/skills/embedded-project-setup

Reusable agent skills for scaffolding C++ and embedded projects

Install
npx -y skills add Victory-7291/project-scaffold-setup-skills --skill embedded-project-setup

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

2 things to look at

  • 23 days oldThe repository was created 23 days ago. New is not bad, but a brand new repository carrying a familiar-sounding name is the shape a typosquat arrives in, and there has been no time for anyone else to find a problem with it.
  • 7 stars7 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Embedded firmware setup: STM32, ESP32, AVR, RP2040, Nordic nRF, Zephyr/RTOS, vendor SDKs, CMake/CMakePresets, VS Code/clangd, cross toolchains, flash/debug, Docker/CI. Use for MCU scaffolds, existing firmware modernization, BSPs, linker/startup files, SDK package selection, and embedded CI; prefer cpp-project-setup for host-side C++.

SKILL.md

15.1 KB, as published. Nobody here has run it

Modern Embedded Project Setup

Overview

Create or modernize embedded firmware around a shared engineering pipeline, then adapt the target-specific compiler, SDK, flashing, and debug pieces to the selected MCU:

VS Code -> clangd -> clang-format -> clang-tidy -> CMake/CMakePresets -> Ninja -> target compiler/SDK -> firmware artifacts -> flash/debug -> MCU

Treat editor analysis, static checks, build generation, cross compilation, artifact generation, flashing, and debug as separate stages. First classify the user's working directory and host platform, then either generate a greenfield scaffold or modernize the existing firmware pipeline.

Workflow

  1. Determine the user's working directory and whether firmware already exists.

    • Check the user-provided path or current working directory before writing files.
    • Treat the directory as an existing firmware project if it already has source files, linker scripts, startup files, CubeMX files, CMake/Make/build scripts, vendor trees, flash/debug scripts, editor settings, CI, docs, or git history.
    • For existing firmware, inventory the full development pipeline before editing: build system, toolchain file, compiler version, MCU/board assumptions, linker/startup flow, vendor dependency model, flash/debug flow, tests or host-side checks, formatting/linting/static analysis, CI, and firmware artifacts.
  2. Detect the user's host development environment.

    • Determine OS and architecture: macOS/Linux/Windows plus arm64 or x64. Use local commands such as uname -s, uname -m, or PowerShell/.NET runtime information where appropriate.
    • Select a host profile: macos-arm64, macos-x64, linux-x64, linux-arm64, windows-x64, or windows-arm64.
    • If the agent is running somewhere other than the user's real development machine, ask for the user's OS/architecture instead of assuming the sandbox matches their workstation.
  3. Identify the firmware target before writing files.

    • Capture target ecosystem first: STM32/Cortex-M, ESP32/ESP-IDF, AVR/Arduino or bare-metal avr-gcc, RP2040/Pico SDK, Nordic nRF/nRF Connect SDK or Zephyr, Zephyr/RTOS board target, or another MCU family.
    • Capture the concrete MCU or board, firmware package/SDK, dependency path, package version/tag, debug probe, flash/RAM map when relevant, CPU core, FPU/float ABI when relevant, flash tool, debug server, and whether the project will use vendor HAL/SDK, RTOS APIs, CMSIS, bare-metal register access, or a mix.
    • If the user has not provided the target, ask for the MCU/board and preferred framework before writing files. Do not silently default to any STM32, ESP32, AVR, RP2040, Nordic, or Zephyr board.
    • If the user explicitly wants a target-agnostic starter before hardware is known, generate only a portable build-smoke scaffold with no hardware register writes, no final flash command assumptions, and clear TODOs for target selection.
  4. Choose and pin the firmware package or SDK before generating build files.

    • Read references/firmware-package-matrix.md when selecting or validating packages for STM32, ESP32, AVR, RP2040/RP2350, Nordic nRF, Zephyr, or standalone RTOS projects.
    • Record four facts before writing source lists or include paths: package name, source URL or package manager, local path such as vendor/STM32CubeG0 or an external SDK workspace, and pinned version/tag/manifest revision.
    • CMSIS is the common Cortex-M processor/device layer when official Cortex-M device headers exist. Do not claim CMSIS is required for non-Arm targets such as AVR or ESP32.
    • Prefer the ecosystem's normal dependency model: STM32Cube packages can live under vendor/ as a submodule or recursive clone; ESP-IDF usually lives outside the app as IDF_PATH or in an external/submodule path; Pico SDK can be a submodule or external SDK path; nRF Connect SDK and Zephyr should usually be managed by west; AVR bare-metal normally uses AVR GNU Toolchain plus AVR-LibC and only adds Microchip .atpack files when device support is missing or needs pinning.
    • If fetching packages requires network access or would add a large dependency tree, ask for approval or document the exact command and leave non-fake placeholders. Do not invent CMSIS/HAL paths or copy unrelated vendor examples into the project.
  5. Choose the target toolchain profile.

    • Use this matrix to choose the actual compiler, build driver, artifact tools, flash command, debug server, Docker image, and CI commands before generating files:
Target/platformCompiler and build tools to configureFirmware artifactsFlash/debug tools to configure
STM32 MCUarm-none-eabi-gcc/g++, arm-none-eabi-objcopy, arm-none-eabi-size, arm-none-eabi-gdb, CMake, Ninja, selected CMSIS Device/Core and STM32 HAL/LL sources from STM32Cube<series>. Use GNU Tools for STM32 or ST Arm Clang instead when the project requests ST's toolchain..elf, .bin, .hex, .mapOpenOCD or STM32CubeProgrammer/ST-LINK GDB server, ST-Link or J-Link, Cortex-Debug or STM32 VS Code debug configuration.
ESP32 familyESP-IDF, CMake, Ninja, idf.py; configure xtensa-esp-elf-gcc/g++ for Xtensa ESP32 variants and riscv32-esp-elf-gcc/g++ for RISC-V ESP32 variants through ESP-IDF tooling.ESP-IDF app/bootloader/partition .bin images, .elf, .mapidf.py flash, esptool.py, idf.py monitor, Espressif OpenOCD/JTAG and ESP-IDF debug configuration when hardware debug is requested.
AVRAVR GNU Toolchain: avr-gcc/g++, avr-objcopy, avr-size, avr-objdump, AVR Libc, CMake or Make. Configure -mmcu=<device> from the exact AVR MCU..elf, .hex, .eep, .map when configuredavrdude with the user's programmer and port, or the existing Arduino/Microchip upload flow.
RP2040/RP2350Pico SDK, CMake, Ninja or Make, arm-none-eabi-gcc/g++, Pico SDK tools such as elf2uf2; configure PICO_SDK_PATH and board settings..elf, .uf2, .bin, .hex, .mapUSB bootloader drag-and-drop, picotool, Picoprobe/OpenOCD, arm-none-eabi-gdb, Cortex-Debug when debugging is requested.
Nordic nRFPrefer nRF Connect SDK / Zephyr SDK with west, CMake, Ninja, and the SDK-managed Arm toolchain. For direct bare-metal nRF projects, configure arm-none-eabi-gcc/g++, CMSIS/nrfx, CMake, and Ninja.Zephyr/nRF merged .hex and .elf, or direct bare-metal .elf, .bin, .hex, .mapwest flash, nrfjprog, J-Link tools, OpenOCD where supported, west debug, or Cortex-Debug/J-Link configuration.
Zephyr/RTOSZephyr SDK or the vendor RTOS toolchain selected by board architecture; configure west, CMake, Ninja, devicetree, Kconfig, and board overlays. Use architecture-specific toolchains such as arm-zephyr-eabi, RISC-V, Xtensa, x86, ARC, or vendor-provided compilers as required by the board.Zephyr .elf, .hex, .bin, merged images, signed images, or RTOS/vendor-specific outputswest flash, west debug, board runner config, OpenOCD/J-Link/pyOCD/vendor runners as selected by Zephyr or the RTOS.
  • The shared workflow is editor/build-system/quality/CI consistency. The compiler and flash/debug tools must come from the selected target profile.
  • Do not generate a generic arm-none-eabi-gcc toolchain file for ESP32, AVR, Zephyr non-Arm boards, or any platform whose SDK owns toolchain selection.
  1. Generate or update the project.
    • For greenfield scaffolding, run from this skill directory:
python3 scripts/scaffold_embedded_project.py \
  --name firmware \
  --out /path/to/workspace/firmware \
  --host-platform macos-arm64 \
  --target-family <target-family> \
  --board <board-name> \
  --mcu <mcu-name> \
  --cpu <cpu-core>
  • Use the bundled scaffold script only for direct CMake-style Cortex-M projects that fit the arm-none-eabi-gcc flow. For STM32 HAL/LL projects, pair the shared CMake/editor scaffold with an explicit STM32Cube<series> package path and selected CMSIS/HAL source list. For ESP-IDF, AVR, Pico SDK, Zephyr, or other ecosystems, either adapt the generated standard configs carefully or create/update the ecosystem-native files directly.
  • For a concrete Cortex-M target, pass explicit target values:
python3 scripts/scaffold_embedded_project.py \
  --name sensor_fw \
  --out /path/to/workspace/sensor_fw \
  --target-family nrf52 \
  --board custom-nrf52840-board \
  --mcu nrf52840 \
  --device-define NRF52840_XXAA \
  --cpu cortex-m4 \
  --fpu fpv4-sp-d16 \
  --float-abi hard \
  --flash-origin 0x00000000 \
  --flash-kb 1024 \
  --ram-origin 0x20000000 \
  --ram-kb 256 \
  --openocd-interface jlink \
  --openocd-target nrf52
  • The scaffold script renders reusable standard configuration from assets/ for CMake, presets, clangd/tidy, VS Code, Docker, and debug tasks. Update assets when the shared firmware standard changes; update the Python script when generation logic, MCU arguments, linker/startup defaults, BSP templates, or command entry points change.
  • For existing firmware, inspect CMakeLists.txt, CMakePresets.json, toolchain files, linker scripts, startup files, .vscode/, .clangd, .clang-tidy, flash/debug scripts, Dockerfile, CI workflows, and local docs before editing.
  • Omit --host-platform only when generating on the same machine where the project will be developed; the script will auto-detect that host.
  1. Preserve the embedded layer model.

    • Keep application logic above board support and drivers.
    • Keep the BSP thin and explicit: board wiring belongs there, reusable chip drivers belong below it, application behavior belongs above it.
    • Use CMSIS Core plus CMSIS Device as the lowest common Cortex-M/device layer when vendor headers are available; do not apply CMSIS expectations to AVR, ESP-IDF, or other non-Cortex-M targets.
    • Use vendor HALs, SDK drivers, ESP-IDF components, Pico SDK libraries, Arduino cores, Zephyr drivers, or RTOS APIs when they match the chosen ecosystem; use lower-level APIs or direct registers only for startup, BSP smoke tests, bootloaders, or performance-critical code.
    • Treat RTOS selection separately from silicon support. Zephyr and nRF Connect SDK can own startup/linker/drivers through their board model; standalone FreeRTOS still needs the vendor firmware package or device support layer underneath it.
    • Do not vendor-copy large SDK trees blindly; prefer a documented submodule, package manager, west manifest, generated vendor directory, or user-provided dependency path.
  2. Wire the toolchain.

    • Use CMake presets named from a target-neutral prefix, by default firmware-debug, firmware-release, and firmware-analyze.
    • Configure the compiler and build driver from the selected target profile: create a CMake toolchain file for direct bare-metal GCC flows, use ESP-IDF's idf.py and managed toolchains for ESP32, use AVR GCC and -mmcu settings for AVR, use Pico SDK variables for RP2040/RP2350, and preserve west/Zephyr SDK or vendor RTOS toolchain selection for Zephyr/RTOS projects.
    • Keep generated CMakePresets.json, VS Code settings/tasks/launch configs, shell/PowerShell scripts, Dockerfile, and GitHub Actions workflow aligned with that selected compiler and build command.
    • Export compile_commands.json for clangd.
    • Pass the embedded target triple to clangd and clang-tidy when the target compiler flags require it.
    • Use Ninja for builds.
    • Produce the firmware artifacts expected by the target ecosystem, such as .elf, .bin, .hex, .map, .uf2, or vendor-specific images.
  3. Wire editor, flashing, and debug.

    • Recommend VS Code extensions that match the target: clangd and CMake Tools for CMake flows, Cortex-Debug for Cortex-M GDB flows, and ecosystem-specific extensions only when they help the selected target.
    • Disable competing IntelliSense when clangd owns semantic analysis.
    • Use OpenOCD with ST-Link or J-Link when that is the right GDB server for the selected target.
    • Set flash/debug config from the actual target and probe. Do not invent OpenOCD target names; ask the user or inspect existing project files when uncertain.
    • Keep shell and PowerShell command entry points for build, format, analyze, flash, and debug-server startup when generating a cross-platform scaffold.

Validation

Run what is available locally. For the bundled direct Cortex-M scaffold, use:

cmake --preset firmware-debug
cmake --build --preset firmware-debug
bash scripts/format.sh --check
cmake --preset firmware-analyze
cmake --build --preset firmware-analyze

On Windows, use the generated PowerShell entry points such as pwsh scripts/build.ps1, pwsh scripts/format.ps1 -Check, and pwsh scripts/analyze.ps1.

For ESP-IDF, AVR, Pico SDK, Zephyr, or RTOS projects, use the ecosystem-native validation commands after adding the shared editor/format/CI layers, for example idf.py build, west build, Pico SDK CMake presets, avr-gcc/avrdude smoke commands, or the existing project scripts.

Also validate the firmware package decision itself:

  • STM32: confirm vendor/STM32Cube<series> or the documented external package path exists, is pinned to a tag/commit, and exposes Drivers/CMSIS plus the selected Drivers/STM32<series>xx_HAL_Driver paths.
  • ESP-IDF: run idf.py --version, confirm the chosen IDF_PATH or submodule path, then run idf.py set-target <chip> and idf.py build when tools are installed.
  • AVR: confirm avr-gcc -mmcu=<device> recognizes the MCU, and record whether AVR-LibC or a Microchip .atpack supplies headers/startup/device libraries.
  • Pico SDK: confirm PICO_SDK_PATH or the submodule path and run the Pico SDK CMake configure/build that produces .uf2.
  • Nordic nRF / Zephyr: run west list to verify the manifest-resolved SDK modules, then west build -b <board> and west flash only when hardware is attached.

For the bundled direct Cortex-M scaffold, run flashing or debug validation only when hardware is attached and the user expects hardware access:

bash scripts/flash.sh
bash scripts/openocd_server.sh

If clang-format, clang-tidy, the selected target compiler, flash/debug tools, or hardware are unavailable, report the skipped step and leave the project ready for that tool.

References

  • Read references/embedded-project-blueprint.md when choosing directory layout, CMake/toolchain settings, target ecosystem layers, target-family parameters, flashing/debug flow, or CI design.
  • Read references/firmware-package-matrix.md when choosing or validating vendor firmware packages, SDK paths, vendor/ directories, .atpack files, west manifests, ESP-IDF/Pico SDK setup, CMSIS applicability, or RTOS package layering.
  • Read the scaffold script before changing generated linker/startup defaults, supported MCU arguments, or generated command entry points.
  • Read assets/ before changing standard generated configuration files; treat those files as templates and keep board-, MCU-, probe-, and project-specific values behind @PLACEHOLDER@ variables.

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.