# embedded-patterns > Embedded C firmware patterns for HAL/driver layering, state machines, ring buffers, and low-level safety practices. Use for MCU firmware architecture and device driver design. - Author: establers - Repository: Establers/claude_skills_for_our_team - Version: 20260124205403 - Stars: 0 - Forks: 0 - Last Updated: 2026-02-06 - Source: https://github.com/Establers/claude_skills_for_our_team - Web: https://mule.run/skillshub/@@Establers/claude_skills_for_our_team~embedded-patterns:20260124205403 --- --- name: embedded-patterns description: Embedded C firmware patterns for HAL/driver layering, state machines, ring buffers, and low-level safety practices. Use for MCU firmware architecture and device driver design. --- # Embedded Firmware Patterns ## HAL / Driver Layering ```c // hal_spi.h typedef struct { status_t (*write)(const uint8_t *data, size_t len); status_t (*read)(uint8_t *data, size_t len); } hal_spi_t; // driver uses HAL only status_t sensor_read_id(const hal_spi_t *spi, uint8_t *out_id) { uint8_t cmd = 0x9FU; status_t st = spi->write(&cmd, 1U); if (st != STATUS_OK) return st; return spi->read(out_id, 1U); } ``` ## Finite State Machine ```c typedef enum { ST_INIT, ST_READY, ST_RUN, ST_FAULT } app_state_t; static app_state_t state = ST_INIT; void app_tick(void) { switch (state) { case ST_INIT: if (app_init_ok()) state = ST_READY; break; case ST_READY: if (app_start_requested()) state = ST_RUN; break; case ST_RUN: if (app_fault()) state = ST_FAULT; break; case ST_FAULT: app_handle_fault(); break; default: state = ST_FAULT; break; } } ``` ## Ring Buffer for UART/Logging ```c typedef struct { uint8_t *buf; size_t size; size_t head; size_t tail; } ringbuf_t; bool ringbuf_push(ringbuf_t *rb, uint8_t v); bool ringbuf_pop(ringbuf_t *rb, uint8_t *out); ``` ## Error Codes (No Exceptions) ```c typedef enum { STATUS_OK = 0, STATUS_INVALID_ARG, STATUS_TIMEOUT, STATUS_IO_ERROR, STATUS_BUSY } status_t; ``` ## Low-Power Pattern ```c void app_idle_hook(void) { // Enter sleep when no work is pending if (can_sleep()) { enter_sleep_mode(); } } ``` **Remember**: Keep ISRs tiny, validate all inputs, and separate hardware access from application logic.