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.
In this repository28 other files it gives its agents.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- .github/copilot-instructions.mdCopilot instructions
- api-designSkill
- architecture-decisionSkill
- autonomous-relaySkill
- browser-verificationSkill
- code-review-passSkill
- data-analysisSkill
- data-modelingSkill
- data-pipelineSkill
- data-qualitySkill
- documentationSkill
- frontend-buildSkill
- incident-responseSkill
- incremental-deliverySkill
- ml-lifecycleSkill
- performance-passSkill
- release-and-rollbackSkill
- requirements-interviewSkill
- security-hardeningSkill
- simplification-passSkill
- spec-writingSkill
- systematic-debuggingSkill
- tdd-loopSkill
- team-escalationSkill
- using-agent-dev-teamSkill
- work-breakdownSkill
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
- Distinctive: line 35
No blocking, no allocation, no logging, no long loop, no floating point unless the platform saves the FPU context.
- Distinctive: line 40
Bound every wait: Every peripheral operation gets a timeout and a defined failure behavior.
- Distinctive: line 45
Feed the watchdog from progress,: not from a timer interrupt.
- Distinctive: line 58
Run before claiming the change works:
- Very specific: line 75
If the device does not boot, the peripheral never responds, or the fault is below the register level, that is board-bringup-engineer, not …
≈ “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.
Files
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
- 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.
- 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
consttable that lands in RAM instead of flash is a common and expensive surprise. - 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.
volatilestops 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
-O0is a timing orvolatilebug, 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
| Thought | Reality |
| "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. |
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
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.

