agentleFS
khuynh22khuynh22/agent-dev-team/skills/firmware-build/SKILL.md

firmware-build

Skill9 starsChanged 2 months agoMITView on GitHub

Implements microcontroller firmware within hard limits: static memory, bounded interrupt handlers, a testable HAL boundary, measured stack and flash budgets, and on-target verification. Use for embedded work on an MCU, driver or RTOS task code, or a change that must be proven on hardware rather than in a test runner.

The file

We split this skill into the rules it gives an agent

5 rules. About 0 are common, 4 are distinctive, and 1 is very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈4

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 1

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    No blocking, no allocation, no logging, no long loop, no floating point unless the platform saves the FPU context.

    line 35
  2. Distinctive:

    Bound every wait: Every peripheral operation gets a timeout and a defined failure behavior.

    line 40
  3. Distinctive:

    Feed the watchdog from progress,: not from a timer interrupt.

    line 45
  4. Distinctive:

    Run before claiming the change works:

    line 58
  5. Very specific:

    If the device does not boot, the peripheral never responds, or the fault is below the register level, that is board-bringup-engineer, not …

    line 75

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Firmware Build

Server habits break devices. No heap, bounded interrupt handlers, every wait has a timeout, and nothing is verified without a number.

Standing reference: references/firmware-constraints.md.

Before writing code

  1. Read the datasheet section and the errata. Cite the section in a comment where the required register order is not obvious. An erratum found after two days of debugging is two days lost.
  2. Write the memory budget. RAM, stack per task, flash, and which section each large object lands in. Check the map file rather than assuming; a const table that lands in RAM instead of flash is a common and expensive surprise.
  3. Draw the HAL boundary. Everything above it is host-testable logic. Everything below it touches registers. Logic that reads a register directly cannot be tested off-target, and off-target tests are orders of magnitude faster.

While writing

  • No dynamic allocation after initialisation. Static pools and fixed-size buffers. Fragmentation is unrecoverable on a device that runs for months.
  • Interrupt handlers do four things: acknowledge the source, move data, signal, return. No blocking, no allocation, no logging, no long loop, no floating point unless the platform saves the FPU context.
  • Guard shared state properly. volatile stops the compiler caching a value. It is not atomicity and not a memory barrier. Multi-byte state shared with an interrupt needs a critical section, kept as short as possible.
  • Bound every wait. Every peripheral operation gets a timeout and a defined failure behavior. A bus that never asserts ready must not hang the device.
  • Prefer a state machine over a task per feature. Fewer stacks, fewer races.
  • Handle rollover. Tick arithmetic uses unsigned subtraction so a counter wrap behaves correctly.
  • Feed the watchdog from progress, not from a timer interrupt. A watchdog fed by a timer keeps a wedged application alive, which defeats the purpose.

Testing

  • Host-test all logic through the HAL seam with a fake peripheral layer, using tdd-loop.
  • On-target tests cover timing, interrupt behavior, and peripheral quirks only.
  • Assert stack high-water mark and heap usage in the suite, not by eye.
  • Build and test at the shipping optimisation level. A bug that disappears at -O0 is a timing or volatile bug, and its disappearance is the diagnosis.

On-target verification

Run before claiming the change works:

- **Build:** <toolchain, version, optimisation level>
- **Flash:** <used> / <total>   (delta <n>)
- **RAM:** <used> / <total>     (delta <n>)
- **Stack high-water:** <per task, with margin>
- **Worst-case ISR duration:** <measured with a pin toggle or cycle counter>
- **Host tests:** <quoted summary>
- **On-target tests:** <what ran on hardware, quoted>
- **Power:** <current per state, if battery powered>
- **Soak:** <duration, result>

A change that reports no numbers has not been verified. Prefer a pin toggle and a logic analyser over print statements: printing changes timing and hides the bug you are chasing.

If the device does not boot, the peripheral never responds, or the fault is below the register level, that is board-bringup-engineer, not more application debugging.

Update path

  • Firmware update is atomic with a rollback slot. An update that can brick the device on power loss is not shippable.
  • The build embeds a version and a commit readable from the device.
  • Images are signed if the device is reachable by anyone but you.
  • Brownout behavior is defined for anything that writes to non-volatile storage. A half-written record is a corrupted device.

Red flags

ThoughtReality
"One malloc at startup, so a bit more is fine"Fragmentation is unrecoverable over months. Static pools.
"I'll print from the ISR to debug"Printing changes timing and hides the bug. Toggle a pin.
"volatile makes it safe"It prevents caching. Not atomicity, not ordering.
"The stack is probably fine"Measure the high-water mark. Probably is how devices fault in the field.
"It works at -O0"That is the diagnosis, not a workaround.
"I'll retry until it responds"Bounded, with a timeout and a defined failure. Unbounded retries hang the device.
"It ran for ten minutes on the bench"Soak it. These bugs appear over hours.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.