
Embedded Systems Engineer
FreeOptimize firmware for microcontrollers and RTOS applications.
Free · Opens the source repo
What Embedded Systems Engineer does
The Embedded Systems Engineer skill is designed for developers working on firmware for microcontrollers, particularly in resource-constrained environments. It provides a structured workflow that guides users through the essential steps of embedded systems development, from analyzing hardware constraints to validating implementations and optimizing resource usage. This skill is particularly useful for those developing applications on platforms like STM32 and ESP32, and utilizing real-time operating systems such as FreeRTOS.
The core workflow consists of six critical steps: analyzing constraints, designing architecture, implementing drivers, validating implementations, optimizing resources, and testing. Each step is backed by best practices and guidelines that ensure robust and efficient design. For instance, users are advised to compile their code with strict warnings enabled and utilize static analysis tools to catch potential issues early in the development process. The skill emphasizes the importance of optimizing code size and RAM usage, which is crucial in embedded systems where resources are limited.
Additionally, the skill includes a reference guide that provides detailed information on various topics, such as RTOS patterns, microcontroller programming, power management, communication protocols, and memory optimization. This allows users to access targeted advice based on their specific development context. The skill also includes code templates for common tasks, such as interrupt service routines and FreeRTOS task creation, which can significantly speed up the development process by providing a solid starting point for implementation.
Overall, this skill is tailored for embedded systems engineers and developers who need to create efficient and reliable firmware. Whether you are implementing complex RTOS applications or optimizing power consumption for battery-operated devices, this skill provides the necessary guidance and resources to enhance your development workflow.
When to use it
Use this skill when developing firmware for microcontrollers, especially when working with real-time operating systems or optimizing power consumption.
When not to use it
This skill may not be suitable for high-level application development or projects that do not involve embedded systems or microcontroller programming.
What you can build with it
Developing Firmware for STM32
Use this skill to guide the development of efficient firmware for STM32 microcontrollers, ensuring optimal resource usage.
Implementing FreeRTOS Applications
Leverage this skill to structure and implement applications using FreeRTOS, following best practices for task management and synchronization.
Optimizing Power Consumption
Utilize the power optimization resources in this skill to enhance the battery life of your embedded devices.
How to install Embedded Systems Engineer
View source1. Install with the skills CLI
npx skills add jeffallan/claude-skills/embedded-systems --agent claude-code2. Or install it manually
Download the skill folder and drop it into ~/.claude/skills/ for all projects, or .claude/skills/ to scope it to one repo. Restart Claude Code so it picks up the new skill.
Anthropic's agentic coding CLI, and the reference implementation of Agent Skills. Drop a skill folder into ~/.claude/skills and Claude Code loads it automatically whenever a task matches the skill's description. Claude Code docs
Inside SKILL.md
Written by jeffallanEmbedded Systems Engineer
Senior embedded systems engineer with deep expertise in microcontroller programming, RTOS implementation, and hardware-software integration for resource-constrained devices.
Core Workflow
- Analyze constraints - Identify MCU specs, memory limits, timing requirements, power budget
- Design architecture - Plan task structure, interrupts, peripherals, memory layout
- Implement drivers - Write HAL, peripheral drivers, RTOS integration
- Validate implementation - Compile with
-Wall -Werror, verify no warnings; run static analysis (e.g.cppcheck); confirm correct register bit-field usage against datasheet - Optimize resources - Minimize code size, RAM usage, power consumption
- Test and verify - Validate timing with logic analyzer or oscilloscope; check stack usage with
uxTaskGetStackHighWaterMark(); measure ISR latency; confirm no missed deadlines under worst-case load; if issues found, return to step 4
Reference Guide
Load detailed guidance based on context:
| Topic | Reference | Load When |
|---|---|---|
| RTOS Patterns | references/rtos-patterns.md | FreeRTOS tasks, queues, synchronization |
| Microcontroller | references/microcontroller-programming.md | Bare-metal, registers, peripherals, interrupts |
| Power Management | references/power-optimization.md | Sleep modes, low-power design, battery life |
| Communication | references/communication-protocols.md | I2C, SPI, UART, CAN implementation |
| Memory & Performance | references/memory-optimization.md | Code size, RAM usage, flash management |
Constraints
MUST DO
- Optimize for code size and RAM usage
- Use
volatilefor hardware registers and ISR-shared variables - Implement proper interrupt handling (short ISRs, defer work to tasks)
- Add watchdog timer for reliability
- Use proper synchronization primitives
- Document resource usage (flash, RAM, power)
- Handle all error conditions
- Consider timing constraints and jitter
MUST NOT DO
- Use blocking operations in ISRs
- Allocate memory dynamically without bounds checking
- Skip critical section protection
- Ignore hardware errata and limitations
- Use floating-point without hardware support awareness
- Access shared resources without synchronization
- Hardcode hardware-specific values
- Ignore power consumption requirements
Code Templates
Minimal ISR Pattern (ARM Cortex-M / STM32 HAL)
/* Flag shared between ISR and task — must be volatile */
static volatile uint8_t g_uart_rx_flag = 0;
static volatile uint8_t g_uart_rx_byte = 0;
/* Keep ISR short: read hardware, set flag, exit */
void USART2_IRQHandler(void) {
if (USART2->SR & USART_SR_RXNE) {
g_uart_rx_byte = (uint8_t)(USART2->DR & 0xFF); /* clears RXNE */
g_uart_rx_flag = 1;
}
}
/* Main loop or RTOS task processes the flag */
void process_uart(void) {
if (g_uart_rx_flag) {
__disable_irq(); /* enter critical section */
uint8_t byte = g_uart_rx_byte;
g_uart_rx_flag = 0;
__enable_irq(); /* exit critical section */
handle_byte(byte);
}
}
FreeRTOS Task Creation Skeleton
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#define SENSOR_TASK_STACK 256 /* words */
#define SENSOR_TASK_PRIO 2
static QueueHandle_t xSensorQueue;
static void vSensorTask(void *pvParameters) {
TickType_t xLastWakeTime = xTaskGetTickCount();
const TickType_t xPeriod = pdMS_TO_TICKS(10); /* 10 ms period */
for (;;) {
/* Periodic, deadline-driven read */
uint16_t raw = adc_read_channel(ADC_CH0);
xQueueSend(xSensorQueue, &raw, 0); /* non-blocking send */
/* Check stack headroom in debug builds */
configASSERT(uxTaskGetStackHighWaterMark(NULL) > 32);
vTaskDelayUntil(&xLastWakeTime, xPeriod);
}
}
void app_init(void) {
xSensorQueue = xQueueCreate(8, sizeof(uint16_t));
configASSERT(xSensorQueue != NULL);
xTaskCreate(vSensorTask, "Sensor", SENSOR_TASK_STACK,
NULL, SENSOR_TASK_PRIO, NULL);
vTaskStartScheduler();
}
GPIO + Timer-Interrupt Blink (Bare-Metal STM32)
/* Demonstrates: clock enable, register-level GPIO, TIM2 interrupt */
#include "stm32f4xx.h"
void TIM2_IRQHandler(void) {
if (TIM2->SR & TIM_SR_UIF) {
TIM2->SR &= ~TIM_SR_UIF; /* clear update flag */
GPIOA->ODR ^= GPIO_ODR_OD5; /* toggle LED on PA5 */
}
}
void blink_init(void) {
/* GPIO */
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN;
GPIOA->MODER |= GPIO_MODER_MODER5_0; /* PA5 output */
/* TIM2 @ ~1 Hz (84 MHz APB1 × 2 = 84 MHz timer clock) */
RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
TIM2->PSC = 8399; /* /8400 → 10 kHz */
TIM2->ARR = 9999; /* /10000 → 1 Hz */
TIM2->DIER |= TIM_DIER_UIE;
TIM2->CR1 |= TIM_CR1_CEN;
NVIC_SetPriority(TIM2_IRQn, 6);
NVIC_EnableIRQ(TIM2_IRQn);
}
Output Templates
When implementing embedded features, provide:
- Hardware initialization code (clocks, peripherals, GPIO)
- Driver implementation (HAL layer, interrupt handlers)
- Application code (RTOS tasks or main loop)
- Resource usage summary (flash, RAM, power estimate)
- Brief explanation of timing and optimization decisions
Frequently asked questions about Embedded Systems Engineer
Similar skills
Spring Boot Testing
Master testing techniques for Spring Boot 4 applications.
GitHub Issues
Manage GitHub issues efficiently with MCP tools.
Geofeed Tuner
Optimize your IP geolocation feeds in CSV format.
Batch Files
Master Windows batch scripting for automation and task management.
Adobe Illustrator Scripting
Automate your Illustrator workflows with ExtendScript.
Plugin Structure
Create and organize Claude Code plugins effectively.
