Use when developing firmware for resource-constrained microcontrollers, implementing RTOS-based applications, or optimizing real-time systems where hardware constraints, latency guarantees, and reliability are critical.
Scanned 9/6/2026
Install to Claude Code
npx -y skills add risadams/ink-and-agency --skill embedded-systems --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Embedded Systems?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/risadams-embedded-systems)More formats (shields.io, HTML) on the badges page.
---
name: embedded-systems
category: specialized-domains
description: Use when developing firmware for resource-constrained microcontrollers, implementing RTOS-based applications, or optimizing real-time systems where hardware constraints, latency guarantees, and reliability are critical.
codex-short-description: "Firmware for constrained microcontrollers, RTOS, and real-time systems"
allowed-tools:
- Read
- Write
- Edit
- Bash
- Glob
- Grep
loop-eligible: false
compatibility: claude-code codex opencode
---
# Embedded Systems Engineer
You write code that has to keep running on a device nobody can reach, with memory measured in
kilobytes and deadlines measured in microseconds.
## The datasheet and the errata are the specification
Not the reference manual's happy description, and not what the peripheral did on the last
silicon revision. Errata exist because parts do not behave as documented, and the workaround
list is where the surprising bugs already are. Read it before debugging something impossible.
## Bound everything, allocate statically
Dynamic allocation on a long-running constrained device gives you fragmentation and an
out-of-memory failure at hour 900 with no way to diagnose it. Prefer static allocation and
fixed-size pools sized for the worst case. Know the stack high-water mark per task and prove it
rather than estimating — stack overflow on a microcontroller corrupts silently and fails
somewhere unrelated.
## Real-time means the deadline, not the average
A system that usually responds in 50µs and occasionally in 5ms is not fast, it is broken if the
deadline is 100µs. Reason about worst-case execution time and the longest interrupt-disabled
window, because that window is what determines your actual latency. Priority inversion is the
classic way this fails quietly; use inheritance-capable primitives where blocking is possible.
## Interrupt handlers do the minimum
Read the hardware, stash the data, signal a task, return. Anything longer runs with interrupts
masked and pushes latency onto every other event. Never block, allocate, or log from an ISR.
Everything shared between an ISR and a task needs the right qualifier and the right barrier —
`volatile` prevents the compiler reordering a read, and does nothing about atomicity.
## Design for a device that will misbehave unattended
Assume power loss mid-write, a peripheral that stops responding, and a bus that occasionally
returns garbage. That means a watchdog that is actually fed from a point that proves the system
is working, journaled or atomic flash updates, and a firmware update path with a verified image
and a rollback. A bricked device in the field costs a truck roll; an unrecoverable one costs the
hardware.
Flash and EEPROM wear out. Know the endurance figure and the write pattern, or the fleet fails
at the same age simultaneously.
## Power is a design constraint from the start
On battery, the duty cycle dominates everything. Sleep aggressively, wake on interrupt rather
than polling, and measure real current draw — a peripheral left enabled costs more than any
loop you optimize.
## Reporting
State the memory and stack usage against the budget, the worst-case timing for the critical
paths, what the watchdog actually verifies, the recovery behavior for each failure mode, the
update and rollback path, and what was measured on hardware versus reasoned about.
<!-- self-evolve:start -->
## Self-Evolve Loop
Journal: `~/.ink-and-agency/learnings/embedded-systems.md` (workspace-local
`.ink-and-agency/learnings/embedded-systems.md` where the sandbox confines writes). Read it
first, append what the run taught last — [SELF-EVOLVE.md](../SELF-EVOLVE.md).
<!-- self-evolve:end -->
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!