一键导入
embedded-tdd
Use when implementing any driver, sensor handler, or firmware component - requires HAL Mock test first, then hardware verification test
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Use when implementing any driver, sensor handler, or firmware component - requires HAL Mock test first, then hardware verification test
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Use when working on embedded systems, firmware, MCU, sensors, displays, hardware drivers, or IoT applications on ESP32, STM32, RP2040, nRF52 - enforces TDD-first workflow with HAL Mock tests and build-flash-monitor verification before any completion claims
Embedded SP - Superpowers-integrated embedded development skill. Use for ESP32, STM32, RP2040, nRF52. Enforces TDD-first, Build-Flash-Monitor verification.
Use when working on embedded systems, firmware, MCU, sensors, displays, hardware drivers, or IoT applications on ESP32, STM32, RP2040, nRF52 - enforces TDD-first workflow with HAL Mock tests and build-flash-monitor verification before any completion claims
Use when working on embedded systems, firmware, MCU, sensors, displays, hardware drivers, or IoT applications on ESP32, STM32, RP2040, nRF52 - enforces TDD-first workflow with HAL Mock tests and build-flash-monitor verification before any completion claims
Use BEFORE any embedded firmware development - clarifies hardware requirements, pin assignments, interface timing, and architecture through structured questions and design approval gate
Use when hardware config detected, problem solved with evidence, or verification passed - writes to AGENTS.md for persistent project memory
| name | embedded-tdd |
| description | Use when implementing any driver, sensor handler, or firmware component - requires HAL Mock test first, then hardware verification test |
Write HAL Mock test first. Watch it fail. Write minimal HAL implementation. Run hardware verification test.
Core principle: Test the driver logic WITHOUT hardware, then verify WITH hardware.
Announce at start: "I'm using the embedded-tdd skill to write HAL Mock tests before implementation."
NO FIRMWARE CODE WITHOUT FAILING HAL MOCK TEST FIRST
Write code before HAL Mock test? Delete it. Start over.
No exceptions:
Test driver logic WITHOUT real hardware:
spi_transmit() → verify command sequencei2c_read() → verify data parsinggpio_set_level() → verify timing logicPurpose: Prove driver logic is correct regardless of hardware behavior.
Test WITH real hardware:
Purpose: Prove driver works with actual hardware.
digraph embedded_tdd {
"Write HAL Mock test" [shape=box];
"Run test: FAIL?" [shape=diamond];
"STOP: Test must fail first" [shape=octagon, style=filled, fillcolor=red, fontcolor=white];
"Write minimal implementation" [shape=box];
"Run test: PASS?" [shape=diamond];
"Refactor implementation" [shape=box];
"Run Hardware test" [shape=box];
"Hardware test: PASS?" [shape=diamond];
"Invoke embedded-verification" [shape=doublecircle];
"Write HAL Mock test" -> "Run test: FAIL?";
"Run test: FAIL?" -> "STOP: Test must fail first" [label="no - test wrong"];
"Run test: FAIL?" -> "Write minimal implementation" [label="yes - RED verified"];
"Write minimal implementation" -> "Run test: PASS?";
"Run test: PASS?" -> "Write minimal implementation" [label="no - more code needed"];
"Run test: PASS?" -> "Refactor implementation" [label="yes - GREEN"];
"Refactor implementation" -> "Run Hardware test";
"Run Hardware test" -> "Hardware test: PASS?";
"Hardware test: PASS?" -> "Run Hardware test" [label="no - debug"];
"Hardware test: PASS?" -> "Invoke embedded-verification" [label="yes"];
}
| Component | HAL Functions to Mock |
|---|---|
| SPI LCD | spi_init(), spi_transmit(), spi_receive() |
| I2C Sensor | i2c_init(), i2c_read(), i2c_write() |
| GPIO Control | gpio_init(), gpio_set_level(), gpio_get_level() |
| UART Comm | uart_init(), uart_send(), uart_receive() |
| Layer | What NOT to Mock |
|---|---|
| Driver logic | Command sequences, data parsing, timing calculations |
| Application | Business logic, state machines |
| Platform SDK | ESP-IDF internals (use their test framework) |
// test/lcd_hal_mock.c
// Mock state
static uint8_t mock_spi_buffer[256];
static int mock_spi_buffer_len = 0;
static bool mock_spi_initialized = false;
// Mock functions
void mock_spi_init(spi_config_t *config) {
mock_spi_initialized = true;
mock_spi_buffer_len = 0;
}
void mock_spi_transmit(uint8_t *data, size_t len) {
if (!mock_spi_initialized) {
TEST_FAIL("SPI not initialized before transmit");
}
memcpy(mock_spi_buffer + mock_spi_buffer_len, data, len);
mock_spi_buffer_len += len;
}
uint8_t *mock_spi_get_buffer(void) {
return mock_spi_buffer;
}
int mock_spi_get_buffer_len(void) {
return mock_spi_buffer_len;
}
void mock_spi_reset(void) {
mock_spi_buffer_len = 0;
}
// test/test_lcd_hal.c
TEST_CASE("lcd_init_sends_reset_command") {
mock_spi_reset();
lcd_config_t config = {
.spi_host = SPI2_HOST,
.mosi_pin = 11,
.sck_pin = 12,
.cs_pin = 10,
.dc_pin = 9,
.rst_pin = 8
};
lcd_init(&config);
// Verify RESET command sent (0x01)
uint8_t *buffer = mock_spi_get_buffer();
TEST_ASSERT_EQUAL_UINT8(0x01, buffer[0]);
}
TEST_CASE("lcd_fill_sends_correct_command_sequence") {
mock_spi_reset();
lcd_init(&mock_config);
lcd_fill_rect(0, 0, 240, 240, COLOR_RED);
// Verify command sequence:
// CASET (0x2A), PASET (0x2B), RAMWR (0x2C), data...
uint8_t *buffer = mock_spi_get_buffer();
TEST_ASSERT_EQUAL_UINT8(0x2A, buffer[0]); // CASET
TEST_ASSERT_EQUAL_UINT8(0x2B, buffer[4]); // PASET
TEST_ASSERT_EQUAL_UINT8(0x2C, buffer[8]); // RAMWR
}
# Create test file
write test/test_lcd_hal.c
# Build tests
idf.py build
# Expected output:
# test_lcd_hal.c: undefined reference to `lcd_init'
# FAIL - lcd_init not implemented yet
Verify RED:
// src/hal/lcd_hal.c
void lcd_init(lcd_config_t *config) {
spi_init(config->spi_host, config->mosi_pin, config->sck_pin);
gpio_init(config->cs_pin, GPIO_OUTPUT);
gpio_init(config->dc_pin, GPIO_OUTPUT);
gpio_init(config->rst_pin, GPIO_OUTPUT);
// Send RESET command
gpio_set_level(config->cs_pin, 0);
gpio_set_level(config->dc_pin, 0); // Command mode
spi_transmit(config->spi_host, 0x01); // RESET
gpio_set_level(config->cs_pin, 1);
}
idf.py build
# Expected: PASS
After HAL Mock tests pass:
// test/test_lcd_hardware.c (runs on real hardware)
TEST_CASE("lcd_hardware_init_succeeds") {
lcd_config_t config = {
.spi_host = SPI2_HOST,
.mosi_pin = 11,
.sck_pin = 12,
.cs_pin = 10,
.dc_pin = 9,
.rst_pin = 8
};
esp_err_t ret = lcd_init(&config);
TEST_ASSERT_EQUAL(ESP_OK, ret);
// Verify LCD responds
uint32_t lcd_id = lcd_read_id();
TEST_ASSERT_EQUAL(LCD_ID_ST7789, lcd_id);
}
TEST_CASE("lcd_hardware_fill_visible") {
lcd_fill_rect(0, 0, 240, 240, COLOR_RED);
// This test requires visual verification
// Run idf.py flash monitor and check LCD screen
// Expected: RED screen visible
}
idf.py -p COM3 flash monitor
# Expected monitor output:
# I (100) LCD: LCD initialized successfully
# I (150) LCD: LCD ID: 0x7789
# I (200) LCD: Fill complete
| Excuse | Reality |
|---|---|
| "No hardware available" | Write HAL Mock tests first. Hardware test when available. |
| "Sensor too simple to test" | I2C address errors cost hours. HAL Mock takes 5 min. |
| "Already tested on breadboard" | Ad-hoc ≠ systematic. HAL Mock tests are repeatable. |
| "Mock doesn't prove hardware works" | Mock proves logic. Hardware test proves integration. |
| "I'll test after implementing" | That's not TDD. Write test FIRST. |
| "Keep old code as reference" | You'll adapt it. Delete means delete. |
| "This is just a small change" | Small changes need tests too. Regression happens. |
If you think:
STOP. You are rationalizing. Follow the Iron Law.
| Anti-Pattern | Fix |
|---|---|
| Testing mock behavior | Test driver logic, not mock internals |
| Test-only methods in HAL | Move to test utilities |
| Mock without understanding | Understand HAL interface before mocking |
| Incomplete mocks | Mock complete HAL interface |
| Hardware tests as afterthought | Hardware tests are Phase 2 of TDD |
Previous skill: embedded-brainstorming (hardware design approved)
Next skill: embedded-verification (evidence collection)
After hardware test passes: "Hardware tests pass. I'm invoking the embedded-verification skill to collect build-flash-monitor evidence."
| Reference | Content |
|---|---|
references/hal-mocking.md | HAL Mock patterns and examples |
references/chips.md | Chip-specific HAL interfaces |
references/hardware-interfaces.md | SPI/I2C/UART specifications |