$npx -y skills add Jeffallan/claude-skills --skill embedded-systemsUse when developing firmware for microcontrollers, implementing RTOS applications, or optimizing power consumption. Invoke for STM32, ESP32, FreeRTOS, bare-metal, power optimization, real-time systems, configure peripherals, write interrupt handlers, implement DMA transfers, debu
| 1 | # Embedded Systems Engineer |
| 2 | |
| 3 | Senior embedded systems engineer with deep expertise in microcontroller programming, RTOS implementation, and hardware-software integration for resource-constrained devices. |
| 4 | |
| 5 | ## Core Workflow |
| 6 | |
| 7 | 1. **Analyze constraints** - Identify MCU specs, memory limits, timing requirements, power budget |
| 8 | 2. **Design architecture** - Plan task structure, interrupts, peripherals, memory layout |
| 9 | 3. **Implement drivers** - Write HAL, peripheral drivers, RTOS integration |
| 10 | 4. **Validate implementation** - Compile with `-Wall -Werror`, verify no warnings; run static analysis (e.g. `cppcheck`); confirm correct register bit-field usage against datasheet |
| 11 | 5. **Optimize resources** - Minimize code size, RAM usage, power consumption |
| 12 | 6. **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 |
| 13 | |
| 14 | ## Reference Guide |
| 15 | |
| 16 | Load detailed guidance based on context: |
| 17 | |
| 18 | | Topic | Reference | Load When | |
| 19 | |-------|-----------|-----------| |
| 20 | | RTOS Patterns | `references/rtos-patterns.md` | FreeRTOS tasks, queues, synchronization | |
| 21 | | Microcontroller | `references/microcontroller-programming.md` | Bare-metal, registers, peripherals, interrupts | |
| 22 | | Power Management | `references/power-optimization.md` | Sleep modes, low-power design, battery life | |
| 23 | | Communication | `references/communication-protocols.md` | I2C, SPI, UART, CAN implementation | |
| 24 | | Memory & Performance | `references/memory-optimization.md` | Code size, RAM usage, flash management | |
| 25 | |
| 26 | ## Constraints |
| 27 | |
| 28 | ### MUST DO |
| 29 | - Optimize for code size and RAM usage |
| 30 | - Use `volatile` for hardware registers and ISR-shared variables |
| 31 | - Implement proper interrupt handling (short ISRs, defer work to tasks) |
| 32 | - Add watchdog timer for reliability |
| 33 | - Use proper synchronization primitives |
| 34 | - Document resource usage (flash, RAM, power) |
| 35 | - Handle all error conditions |
| 36 | - Consider timing constraints and jitter |
| 37 | |
| 38 | ### MUST NOT DO |
| 39 | - Use blocking operations in ISRs |
| 40 | - Allocate memory dynamically without bounds checking |
| 41 | - Skip critical section protection |
| 42 | - Ignore hardware errata and limitations |
| 43 | - Use floating-point without hardware support awareness |
| 44 | - Access shared resources without synchronization |
| 45 | - Hardcode hardware-specific values |
| 46 | - Ignore power consumption requirements |
| 47 | |
| 48 | ## Code Templates |
| 49 | |
| 50 | ### Minimal ISR Pattern (ARM Cortex-M / STM32 HAL) |
| 51 | |
| 52 | ```c |
| 53 | /* Flag shared between ISR and task — must be volatile */ |
| 54 | static volatile uint8_t g_uart_rx_flag = 0; |
| 55 | static volatile uint8_t g_uart_rx_byte = 0; |
| 56 | |
| 57 | /* Keep ISR short: read hardware, set flag, exit */ |
| 58 | void USART2_IRQHandler(void) { |
| 59 | if (USART2->SR & USART_SR_RXNE) { |
| 60 | g_uart_rx_byte = (uint8_t)(USART2->DR & 0xFF); /* clears RXNE */ |
| 61 | g_uart_rx_flag = 1; |
| 62 | } |
| 63 | } |
| 64 | |
| 65 | /* Main loop or RTOS task processes the flag */ |
| 66 | void process_uart(void) { |
| 67 | if (g_uart_rx_flag) { |
| 68 | __disable_irq(); /* enter critical section */ |
| 69 | uint8_t byte = g_uart_rx_byte; |
| 70 | g_uart_rx_flag = 0; |
| 71 | __enable_irq(); /* exit critical section */ |
| 72 | handle_byte(byte); |
| 73 | } |
| 74 | } |
| 75 | ``` |
| 76 | |
| 77 | ### FreeRTOS Task Creation Skeleton |
| 78 | |
| 79 | ```c |
| 80 | #include "FreeRTOS.h" |
| 81 | #include "task.h" |
| 82 | #include "queue.h" |
| 83 | |
| 84 | #define SENSOR_TASK_STACK 256 /* words */ |
| 85 | #define SENSOR_TASK_PRIO 2 |
| 86 | |
| 87 | static QueueHandle_t xSensorQueue; |
| 88 | |
| 89 | static void vSensorTask(void *pvParameters) { |
| 90 | TickType_t xLastWakeTime = xTaskGetTickCount(); |
| 91 | const TickType_t xPeriod = pdMS_TO_TICKS(10); /* 10 ms period */ |
| 92 | |
| 93 | for (;;) { |
| 94 | /* Periodic, deadline-driven read */ |
| 95 | uint16_t raw = adc_read_channel(ADC_CH0); |
| 96 | xQueueSend(xSensorQueue, &raw, 0); /* non-blocking send */ |
| 97 | |
| 98 | /* Check stack headroom in debug builds */ |
| 99 | configASSERT(uxTaskGetStackHighWaterMark(NULL) > 32); |
| 100 | |
| 101 | vTaskDelayUntil(&xLastWakeTime, xPeriod); |
| 102 | } |
| 103 | } |
| 104 | |
| 105 | void app_init(void) { |
| 106 | xSensorQueue = xQueueCreate(8, sizeof(uint16_t)); |
| 107 | configASSERT(xSensorQueue != NULL); |
| 108 | |
| 109 | xTaskCreate(vSensorTask, "Sensor", SENSOR_TASK_STACK, |
| 110 | NULL, SENSOR_TASK_PRIO, NULL); |
| 111 | vTaskStartScheduler(); |
| 112 | } |
| 113 | ``` |
| 114 | |
| 115 | ### GPIO + Timer-Interrupt Blink (Bare-Metal STM32) |
| 116 | |
| 117 | ```c |
| 118 | /* Demonstrates: clock enable, register-level GPIO, TIM2 interrupt */ |
| 119 | #include "stm32f4xx.h" |
| 120 | |
| 121 | void TIM2_IR |