AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified MIT Self-run

Embedded Firmware Dev

skill-amethystluna-embedded-workbench-embedded-firmware-dev · by AmethystLuna

Use when writing or reviewing embedded C firmware, FreeRTOS tasks, ISR handlers, NVM/flash storage, or sensor driver state machines. NOT for documentation-only RTOS references, conceptual RTOS discussions, or bare-metal projects without an RTOS or sensor subsystem.

No reviews yet
0 installs
15 views
0.0% view→install

Install

$ agentstack add skill-amethystluna-embedded-workbench-embedded-firmware-dev

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-amethystluna-embedded-workbench-embedded-firmware-dev)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
26d ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Embedded Firmware Dev? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

This is a domain implementation skill. If you are planning, designing, or entering plan mode — load Skill("embedded-workbench") first to activate the workflow gates (Plan Verification Gate, Approval Gate, Closure Gate). Domain skills carry implementation guidance, not workflow enforcement.

Embedded Firmware Development

FreeRTOS

  • Give each task a clear ownership boundary. Shared resources need a deliberate synchronization strategy.
  • Prefer task notifications for one-to-one wakeups, queues for data transfer, event groups for combined state, mutexes for mutual exclusion, semaphores for one-way signaling.
  • Use a mutex (not binary semaphore) when mutual exclusion matters and priority inheritance is needed.
  • Make every blocking wait explicit: use a timeout unless an infinite wait is deliberate.
  • Keep timer callbacks short and non-blocking — use them to schedule work, not do it.
  • Avoid holding locks across flash, storage, or long operations.
  • Size task stacks from worst-case call chains. Recheck high-water marks after adding buffers or deeper call trees.
  • Use ISR-safe APIs for interrupt-to-task handoff. Keep ISR state capture minimal.
  • Avoid priority inversion: don't hold shared locks across blocking I/O or long processing.
  • If a task can be paused/restarted/signaled from multiple places, define resume, timeout, and recovery paths explicitly.
  • For cross-task pointer ownership: make lifetime and invalidation rules obvious.
  • Prefer the smallest critical section that protects the state transition. Don't wrap whole operations in locks when narrower ordering suffices.
  • For objects handed between threads: define whether the receiver owns, borrows, or copies before crossing the boundary.

Interrupts / ISR

  • Keep the interrupt path short, deterministic, and bounded. Capture minimum state, clear the source, defer expensive work.
  • Do not block, sleep, allocate heap, or call non-ISR-safe APIs from an ISR.
  • Prefer top-half/bottom-half split when the handler needs more than quick state capture and wakeup.
  • Make shared-state ownership explicit. Use minimum synchronization for the data being shared.
  • If an ISR wakes a task, use the ISR-safe RTOS primitive and preserve yield-from-ISR behavior.
  • Define clear read/clear/re-enable ordering to avoid losing edges or creating re-trigger loops.
  • Avoid logging and complex branching in the hot interrupt path.
  • If code runs from both task and ISR context, separate wrappers so the ISR-safe path stays obvious.

Async Lifecycle Cleanup

  • Any async flag (pending, in-progress, busy, data-ready) that can be set during normal operation must be explicitly cleared in every stop, init, reset, power-off, and error-recovery path. A stale flag silently blocks the next operation.
  • When adding a new async operation, audit all lifecycle entry points and ensure each path resets flags to known-safe.
  • Cleanup must happen before any new operation is attempted, not after.
// CORRECT: every async flag cleared in stop path. No stale state survives restart.
uint8_t comm_stop_sample(void) {
    g_comm.data_ready         = false;
    g_comm.state              = COMM_STATE_IDLE;
    g_comm.activating         = false;
    g_comm.command_fail_count = 0;
    g_comm.protocol_locked    = false;
    g_comm.communication_lost = false;
    g_comm.warmup_start_time  = 0;
    comm_command_complete();                     // Release any pending I/O
    memset(&g_comm_data, 0, sizeof(g_comm_data));// Reset cached data
    comm_process_faults(false);                  // Clear fault detection state
    return COMM_OK;
}

// BAD: half the flags survive — next start inherits stale state
void comm_stop_bad(void) {
    g_comm.state = COMM_STATE_IDLE;              // Only state changed
    // Missing: data_ready, protocol_locked, communication_lost, fail_count...
    // Next start: data_ready==true blocks first sample; fail_count persists
}

// CALLER GUARD: clear stale flags at power-off boundaries before re-init
void comm_handler(void) {
    if (!power_get_status() && g_comm.command_pending) {
        comm_command_complete();                 // Clear before deinit
    }
    if (power_get_status()) {
        comm_state_process();
    }
}

One-Shot Event Consumption

  • When a low-level driver produces a transient event that multiple higher-level consumers need, use an atomic check-and-clear (consume) API rather than shared flags each consumer clears manually.
  • Manual clearing by multiple consumers creates races: consumer A clears before B reads, or B reads a flag already set again by the next cycle.
  • The consume primitive returns whether the event occurred and atomically clears the latch — every interested consumer observes the event exactly once per occurrence.
// Atomic check-and-clear: every consumer sees the event exactly once
static volatile uint32_t event_latch;

uint32_t event_consume(uint32_t mask) {
    uint32_t primask = __get_PRIMASK();
    __disable_irq();
    uint32_t pending = event_latch & mask;
    event_latch &= ~mask;               // Clear consumed bits atomically
    if (!primask) __enable_irq();
    return pending;                     // Non-zero = event occurred this cycle
}

// Each consumer independently observes — no races between consumers
void ui_consume(void) {
    if (event_consume(EVT_SENSOR_READY)) update_display();
}
void log_consume(void) {
    if (event_consume(EVT_SENSOR_READY)) write_log();
}

Storage / Persistence

  • Separate object corruption from schema change. Rebuild the whole store only when versioned layout rules require it.
  • Prefer recoverable write paths: write primary → read back and verify → write backup → read back and verify.
  • During delete, reset, or migration, preserve at least one valid recoverable copy.
  • Prefer targeted repair and re-sync over destructive reinitialization.
  • Treat startup repair, steady-state writes, emergency writes, and factory reset as separate paths with explicit guarantees.

Boundary Analysis

  • When thresholds trip at edges, inspect debounce latency, sample timing, and ring-vs-bounded assumptions before tuning constants.
  • When behavior diverges by mode, compare all branches side by side instead of debugging only the failing branch.
  • When a defect appears on only one trigger path, diff which state each caller resets, preserves, or derives.
  • For transient inconsistencies, inspect raw state, derived state, and cached state separately — stale data in any layer masquerades as a timing problem.
  • When a system undergoes mode switch, direction reversal, or re-initialization, allow a bounded tolerance window for the first post-transition deviation. Treating it with steady-state thresholds produces false error accumulation.

Deep Reference

This skill's references/ directory contains in-depth material. Load when you need more than the core rules:

| Reference | Topic | Load When | |-----------|-------|-----------| | architecture-principles.md | 12 architecture design principles | Designing module boundaries, state ownership, or GUI architecture | | embedded-patterns.md | GIF timer safety, async lifecycle, state latches | Debugging timer crashes, stale flags, or state corruption | | lvgl-pitfalls.md | LVGL layout, alignment, alpha, and mask traps | Debugging LVGL rendering artifacts or HardFault in draw paths |

See also: Skill("state-machine-design") for state transition rules, Skill("debug-methodology") for debugging process, Skill("hardfault-triage") for stack overflow and ISR crash triage.

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.