一键导入
embedded-systems-patterns
Expert reference for embedded systems development — resource-constrained design, real-time patterns, and hardware-software integration
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Expert reference for embedded systems development — resource-constrained design, real-time patterns, and hardware-software integration
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Expert reference for application security — OWASP Top 10 mitigations, auth/authz, secrets management, cryptography, input validation, dependency hygiene, and secure-by-default code patterns
Expert reference for token counting, prompt compression, cost estimation, and quality preservation when optimizing prompts for Claude models
Experimentation design and A/B testing standards for product teams
Expert reference for digital accessibility — WCAG conformance, ARIA, and inclusive design patterns
Authoritative reference for agent architecture selection, multi-agent orchestration, tool design, memory systems, and failure mode prevention
Expert reference for evaluating LLM systems, RAG pipelines, and AI features in production
| name | embedded-systems-patterns |
| description | Expert reference for embedded systems development — resource-constrained design, real-time patterns, and hardware-software integration |
| version | 1.0.0 |
malloc/free) in production firmware unless the allocator is deterministic and bounded (static pool allocator, TLSF). Heap fragmentation on embedded is a time-bomb.volatile; use __disable_irq()/__enable_irq() (or equivalent) for multi-byte accessdelay_ms() burns CPU and breaks RTOS scheduling.0xDEAD, observe high water mark). Never guess.printf in production firmware (pulls in large stdio, non-deterministic). Use a ring-buffer-backed UART logger with fixed-width format strings.Mistake: Unprotected multi-byte shared variable Bad:
// In ISR:
g_timestamp = get_tick(); // 32-bit write, two 16-bit bus transactions on some cores
// In main:
if (g_timestamp > THRESHOLD) { ... } // may read torn value
Good:
volatile uint32_t g_timestamp;
// In ISR: write atomically or use critical section
// In main:
__disable_irq();
uint32_t ts = g_timestamp;
__enable_irq();
if (ts > THRESHOLD) { ... }
Mistake: Blocking inside an ISR Bad:
void UART_IRQHandler(void) {
char buf[64];
HAL_UART_Receive(&huart1, buf, 64, 100); // 100ms timeout in ISR — system halted
}
Good: Set a flag or push to a ring buffer in the ISR. Process in main loop or a deferred task.
Mistake: Using memset on hardware register structs
Bad: memset(&DMA1->LISR, 0, sizeof(DMA_TypeDef)); — writes to read-only status registers
Good: Write to specific registers only. Read the reference manual for clear-on-write vs write-1-to-clear semantics.
Mistake: Uninitialized peripheral before enabling interrupt Bad: Enable NVIC interrupt, then configure peripheral — ISR fires before peripheral is ready Good: Always: configure peripheral fully → clear pending flags → enable peripheral interrupt → enable NVIC entry
Mistake: Stack overflow detection absent Bad: Stack overflows silently corrupt heap or .data; bug manifests far from the cause Good: Enable MPU stack guard region, or RTOS stack overflow hook, or stack painting. Make stack overflow a hard fault with a clear diagnostic.
Mistake: Timeout-free communication wait
Bad: while (!(USART1->SR & USART_SR_TXE)); — infinite spin if peripheral locks up
Good: uint32_t deadline = tick_ms() + TIMEOUT_MS; while (!(USART1->SR & USART_SR_TXE)) { if (tick_ms() > deadline) return ERR_TIMEOUT; }
Bad state machine:
void process(uint8_t event) {
if (state == 0) {
if (event == 1) { state = 1; do_a(); }
else if (event == 2) { if (flag) { state = 3; } else { state = 2; } }
} else if (state == 1) { ... } // 200 lines of nested if/else
}
Good state machine:
typedef enum { ST_IDLE, ST_ACTIVE, ST_ERROR, ST_COUNT } State;
typedef enum { EV_START, EV_DATA, EV_ERROR, EV_COUNT } Event;
typedef State (*TransitionFn)(void);
static State on_idle_start(void) { do_a(); return ST_ACTIVE; }
static State on_active_data(void) { process_data(); return ST_ACTIVE; }
static State on_any_error(void) { log_error(); return ST_ERROR; }
static const TransitionFn fsm[ST_COUNT][EV_COUNT] = {
[ST_IDLE][EV_START] = on_idle_start,
[ST_ACTIVE][EV_DATA] = on_active_data,
[ST_ACTIVE][EV_ERROR] = on_any_error,
};
void process(Event ev) {
TransitionFn fn = fsm[current_state][ev];
if (fn) current_state = fn();
}
Bad driver init sequence:
HAL_NVIC_EnableIRQ(DMA1_Stream0_IRQn); // IRQ enabled too early
HAL_DMA_Init(&hdma);
HAL_UART_Init(&huart1);
Good driver init sequence:
HAL_DMA_Init(&hdma);
HAL_UART_Init(&huart1);
__HAL_UART_CLEAR_FLAG(&huart1, UART_FLAG_ORE | UART_FLAG_NE | UART_FLAG_FE);
HAL_NVIC_SetPriority(USART1_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(USART1_IRQn); // last
Real-time: Correctness depends on timing, not just output value. Hard real-time = missed deadline is a failure. Soft real-time = occasional misses are tolerable.
Critical section: A code region where interrupts are disabled (or a mutex is held in RTOS context) to ensure atomicity of a multi-step operation.
ISR latency vs ISR execution time: Latency = time from event to ISR entry (hardware + NVIC preemption). Execution time = cycles inside the ISR. Both must be bounded.
Stack painting: Initialize the stack with a known sentinel value (e.g., 0xDEADBEEF). At runtime, scan for the high-water mark — where the sentinel was overwritten — to measure actual stack usage.
Fixed-point arithmetic: Represent fractional values as integers scaled by a power of 2 (Q15, Q31 formats). Deterministic, fast on CPUs without FPU. Requires careful tracking of the scaling factor through operations.
DMA (Direct Memory Access): Hardware that moves data between peripherals and memory without CPU involvement. Frees the CPU but introduces cache coherency issues on cores with D-cache — explicit cache invalidation required.
RTOS task priorities: Assign priorities by deadline, not importance. The task with the tightest deadline gets the highest priority (Rate Monotonic Scheduling).
Watchdog timer (WDT): Hardware timer that resets the MCU if not "kicked" within a timeout period. Proves the system is making forward progress. Kick only from a known-good state, not unconditionally.
Write-1-to-clear (W1C): A register bit-clearing mechanism where writing 1 clears the flag (not writing 0). Common in status/interrupt flag registers. Read-modify-write with OR mask, not AND mask.
Volatile keyword: Tells the compiler not to optimize reads/writes to a variable — the value may change outside the compiler's knowledge (hardware register, ISR-modified variable). Does NOT provide atomicity.