| name | new-component |
| description | Scaffold a new Rexio ESP32-S3 flight controller component with all required files, tests, mocks, and build system wiring. Use when creating a new component in components/rexio_* or when the user says /new-component. |
Scaffold a new component for the Rexio flight controller. Creates all required files and wires them into both build systems (ESP-IDF and host tests).
Input
Gather these from the user (ask if not provided):
- name — component name without prefix (e.g.,
mixer). Becomes rexio_{name}.
- deps — other rexio_ components this depends on. Always includes
rexio_platform. If it uses topics, add rexio_topics.
- hal_mocks — which HAL mocks needed in tests:
i2c, time, gpio, rmt (comma-separated, or none)
- vtable —
yes if this component uses the swappable vtable pattern (like estimator, controller, blackbox). no for standard components.
Step 1: Create Component Directory
Create components/rexio_{name}/ with three files.
CMakeLists.txt
idf_component_register(
SRCS "src/{name}.c"
INCLUDE_DIRS "include"
REQUIRES rexio_platform {additional deps}
)
If the component is header-only (no .c files), omit SRCS:
idf_component_register(
INCLUDE_DIRS "include"
REQUIRES rexio_platform
)
include/{name}.h
#ifndef REXIO_{NAME}_H
#define REXIO_{NAME}_H
#include "platform.h"
If vtable=yes, add the vtable pattern:
typedef struct rexio_{name} rexio_{name}_t;
typedef struct {
int (*init)(rexio_{name}_t *self);
void (*reset)(rexio_{name}_t *self);
} rexio_{name}_ops_t;
struct rexio_{name} {
const rexio_{name}_ops_t *ops;
void *impl;
};
rexio_{name}_t {name}_{impl_name}_create(void);
If vtable=no, declare standard functions:
rexio_err_t {name}_init(void);
End with:
#endif
src/{name}.c
#include "{name}.h"
For vtable components, add the stub create function:
#include "{name}.h"
static int {name}_{impl}_init(rexio_{name}_t *self) {
(void)self;
return REXIO_OK;
}
static const rexio_{name}_ops_t {impl}_ops = {
.init = {name}_{impl}_init,
};
rexio_{name}_t {name}_{impl}_create(void) {
return (rexio_{name}_t){ .ops = &{impl}_ops, .impl = NULL };
}
Step 2: Create Test File
Create test/test_{name}.c:
#include "unity.h"
#include "{name}.h"
If hal_mocks includes specific mocks, add includes and setUp:
#include "mock_hal_i2c.h"
#include "mock_hal_time.h"
#include "mock_hal_gpio.h"
#include "mock_hal_rmt.h"
If topics are used:
#include "topics.h"
#include "topic_data.h"
void setUp(void) {
g_hal_i2c = &mock_hal_i2c;
g_hal_time = &mock_hal_time;
g_hal_gpio = &mock_hal_gpio;
g_hal_rmt = &mock_hal_rmt;
mock_i2c_reset();
mock_time_set(0);
mock_gpio_reset();
mock_rmt_reset();
topics_init();
}
void tearDown(void) {}
void test_{name}_placeholder(void) {
TEST_PASS();
}
Step 3: Wire into Host Test Build
test/CMakeLists.txt
Add the component's source file to the test executable's source list. Find the add_executable or target_sources section and add:
${PROJECT_SOURCE_DIR}/../components/rexio_{name}/src/{name}.c
Add the component's include directory:
${PROJECT_SOURCE_DIR}/../components/rexio_{name}/include
Add the test file:
${PROJECT_SOURCE_DIR}/test_{name}.c
test/test_main.c
Add RUN_TEST() entries for the test functions. Find the test runner function and add:
RUN_TEST(test_{name}_placeholder);
Also add the extern declaration at the top:
extern void test_{name}_placeholder(void);
Step 4: Verify
Run make test to confirm:
- The component source compiles in the host test build
- The test file compiles and links
- The placeholder test passes
- No link errors from missing symbols
If make test fails, fix the build errors before considering the scaffold complete.
Conventions Reminder
- Naming:
snake_case functions/variables, UPPER_CASE macros, _t suffix on typedefs
- Include guard:
REXIO_{NAME}_H (all caps)
- Returns: all functions return
rexio_err_t (0=OK, negative=error) unless they return data
- Error codes:
REXIO_OK, REXIO_ERR, REXIO_ERR_TIMEOUT, REXIO_ERR_INVALID
- No malloc: static allocation only in flight-critical components
- SI units: m/s^2, rad/s, Pa, m — see
references/component_template.md
Scope Boundaries
- Do NOT write business logic. Scaffold only.
- Do NOT modify
topic_data.h — use /add-topic for that.
- Do NOT create FreeRTOS tasks — use
/wire-task for that.
- Do NOT add external library dependencies — those come in their respective PRs.
- After scaffolding, the user implements logic via
/tdd-cycle.
Reference
See references/component_template.md for full file templates.
See references/cmakelists_patterns.md for build system wiring examples.