At the beginning of each coding session, before making any code changes, you should build a comprehensive
understanding of the codebase by invoking the /explore-codebase skill.
This ensures you:
- Understand the project architecture before modifying code
- Follow existing patterns and conventions
- Do not introduce inconsistencies or break integrations
You MUST invoke the appropriate style skill before performing ANY of the following tasks:
| Task | Skill to invoke |
|---|---|
| Writing or modifying C++ code | /cpp-style |
| Writing or modifying README files | /readme-style |
| Writing or modifying Sphinx docs files | /api-docs |
Writing or modifying tox.ini |
/tox-config |
| Writing git commit messages | /commit |
| Writing or modifying skill files | /skill-design |
Each skill contains a verification checklist that you MUST complete before submitting any work. Failure to invoke the appropriate skill results in style violations.
This project depends on the following Ataraxis framework library:
| Library | Import header | Role |
|---|---|---|
| ataraxis-transport-layer-mc | axtlmc_shared_assets.h |
Bidirectional serial communication with CRC and COBS |
Before writing code that interacts with a cross-referenced library, you MUST:
-
Check for local version: Look for the library in the parent directory (e.g.,
../ataraxis-transport-layer-mc/). -
Compare versions: If a local copy exists, compare its version against the latest release or main branch on GitHub:
- Read the local
library.jsonto get the current version - Use
gh api repos/Sun-Lab-NBB/{repo-name}/releases/latestto check the latest release
- Read the local
-
Handle version mismatches: If the local version differs from the latest release or main branch, notify the user with the following options:
- Use online version: Fetch documentation and API details from the GitHub repository
- Update local copy: The user will pull the latest changes locally before proceeding
-
Proceed with correct source: Use whichever version the user selects as the authoritative reference for API usage, patterns, and documentation.
Why this matters: Skills and documentation may reference outdated APIs. Always verify against the actual library state to prevent integration errors.
All skills are distributed through the ataraxis marketplace. The skills
below are the ones relevant to this C++ PlatformIO firmware library (the automation plugin plus the microcontroller
plugin's firmware-module). The Python/C# style skills (/python-style, /pyproject-style, /csharp-style) and the
communication/video plugin skills target other repositories and are omitted here.
| Skill | Description |
|---|---|
/explore-codebase |
Perform in-depth codebase exploration at session start |
/explore-dependencies |
Build a live API snapshot of installed ataraxis dependencies |
/firmware-module |
Guide creation of custom hardware Module subclasses |
/cpp-style |
Apply Ataraxis framework C++ coding conventions (REQUIRED for all C++ changes) |
/readme-style |
Apply Ataraxis framework README conventions (REQUIRED for README changes) |
/api-docs |
Apply Ataraxis framework Sphinx documentation conventions (REQUIRED for docs) |
/tox-config |
Apply Ataraxis framework tox.ini conventions (REQUIRED for tox.ini changes) |
/project-layout |
Apply Ataraxis framework project directory structure conventions |
/commit |
Draft Ataraxis framework style-compliant git commit messages |
/pr |
Draft a style-compliant pull request summary for the active branch |
/release |
Draft style-compliant release notes from merged pull requests |
/skill-design |
Generate and verify skill files and CLAUDE.md project instructions |
/audit-facts |
Audit documentation for factual accuracy against the source code |
/audit-style |
Audit files for style and convention compliance |
This library (ataraxis-micro-controller) and its Python counterpart (ataraxis-communication-interface) implement
the same hardware module framework on opposite ends of the connection. Any change to the message protocols, status
codes, prototype resolution, module addressing, or kernel command handling in this library MUST be synchronized with
the corresponding change in ataraxis-communication-interface, and vice versa.
Before modifying any protocol-level behavior, you MUST:
-
Identify the companion repository: Check for a local copy at
../ataraxis-communication-interface/. If unavailable, usegh api repos/Sun-Lab-NBB/ataraxis-communication-interfaceto access the remote repository. -
Review the corresponding implementation: Read the Python source that implements the same functionality you are modifying. Verify that the current MC and PC implementations are in sync before making changes.
-
Plan synchronized changes: Document what must change in both libraries. Notify the user of the required companion changes so they can be applied together.
-
Never modify protocol behavior unilaterally: A change applied to only one side of the connection will cause communication failures. Both libraries must agree on all synchronized elements listed below.
What requires synchronization:
kProtocolsenum values and meanings (13 message types)kPrototypesenum values and lookup table (252 type-count prototype codes)- Message structure layouts (
RepeatedModuleCommand,OneOffModuleCommand,DequeueModuleCommand,KernelCommand,ModuleParameters,ModuleData,ModuleState,KernelData,KernelState) kCommunicationStatusCodesvalues and meanings- Kernel status codes and kernel command codes
- Module core status codes (0-3) and user-defined code range (51-250)
- Module addressing scheme (
module_type,module_id) - Prototype resolution logic (type index mapping and count-based lookup)
What does NOT require synchronization:
- Module subclass implementations (hardware-specific logic)
- Kernel runtime scheduling (keepalive intervals, LED error indication, command queue priority)
- Platform-specific buffer sizes and serial baud rates
- Test infrastructure, build system, and PlatformIO configuration
- Arduino/Teensy-specific timing and
elapsedMicrosusage
This is ataraxis-micro-controller, a C++17 PlatformIO library that provides a framework for integrating custom
hardware modules with a centralized PC control interface (ataraxis-communication-interface). It abstracts
communication, command scheduling, and runtime management, allowing developers to focus on hardware-specific module
logic. The library targets Arduino and Teensy microcontrollers within the
Ataraxis framework.
| Directory | Purpose |
|---|---|
src/ |
Library source code (4 headers + main.cpp development entry) |
test/ |
Unity test suite for Communication class |
examples/ |
TestModule implementation and main.cpp integration example |
docs/ |
Sphinx + Breathe documentation source (consumes Doxygen XML) |
- Kernel (
kernel.h): Main runtime manager that integrates custom module instances with the PC interface. Constructor takescontroller_id(1-255),Communicationreference,Modulepointer array, and optionalkeepalive_interval(milliseconds, 0 = disabled).Setup()initializes hardware and all modules;RuntimeCycle()runs one iteration of the main loop. Internally routes received messages by protocol code: kernel commands are handled directly, module commands and parameters are dispatched to the target module via(module_type, module_id)lookup. Implements keepalive monitoring (two consecutive missed windows trigger emergency reset) and LED-based error indication (constant HIGH = transmission error, 2-second blink = setup error). - Communication (
communication.h): Bidirectional message interface built onTransportLayerfromataraxis-transport-layer-mcwith CRC-16 (polynomial 0x1021, initial 0xFFFF). Handles 13 message protocols (kProtocolsenum) and 252 data prototypes (kPrototypesenum). ProvidesSendDataMessage()(event code + typed data payload),SendStateMessage()(event code only),SendCommunicationErrorMessage(),SendServiceMessage()(reception codes, controller/module identification), andReceiveMessage()(parses incoming protocol-specific structures).ExtractModuleParameters()unpacks parameter payloads into user-defined structures. - Module (
module.h): Abstract base class for custom hardware modules. Constructor takesmodule_type,module_id, andCommunicationreference. Three pure virtual methods:SetupModule()(hardware initialization),SetCustomParameters()(unpack PC parameters), andRunActiveCommand()(execute active command). Manages command execution state viaExecutionControlParametersstruct tracking active command, stage, non-blocking mode, queued command, and recurrent execution with configurable cycle delay. Public methods used by Kernel:QueueCommand(),ResolveActiveCommand(),ResetCommandQueue(),ResetExecutionParameters(),SendCommandActivationError(). Protected utility methods for subclass use:get_active_command(),get_command_stage(),CompleteCommand(),AbortCommand(),AdvanceCommandStage(),WaitForMicros(),SendData(),ExtractParameters(),AnalogRead(),DigitalRead(). - Shared assets (
axmc_shared_assets.h): Two namespaces.axmc_shared_assetscontainskCommunicationStatusCodesenum.axmc_communication_assetscontainskProtocolsenum (13 message types),kPrototypesenum (252 prototype codes), allPACKED_STRUCTmessage structures, thekPrototypeLookupcompile-time 2D lookup table,ResolvePrototype<T>()template function, and reimplemented type traits for Arduino Mega compatibility (is_array,array_extent,remove_extent,PrototypeTypeIndex). Both namespaces are brought into scope viausing namespacein the library's source files.
| Component | File | Purpose |
|---|---|---|
Kernel |
kernel.h |
Runtime management, command routing, keepalive monitoring |
Communication |
communication.h |
Bidirectional PC-microcontroller message handling |
Module |
module.h |
Abstract base class for custom hardware modules |
kProtocols |
axmc_shared_assets.h |
13 message protocol codes for PC-microcontroller exchange |
kPrototypes |
axmc_shared_assets.h |
252 data prototype codes for type-safe serialization |
kPrototypeLookup |
axmc_shared_assets.h |
Compile-time 2D table mapping (count, type) to prototypes |
ResolvePrototype<T>() |
axmc_shared_assets.h |
Compile-time prototype resolution from C++ types |
ExecutionControlParameters |
module.h |
Command execution state tracking (stage, queue, recurrence) |
- Header-only library: All source lives in
.hfiles undersrc/. Themain.cppis excluded from library export and serves as a development entry point. - Stage-based command execution: Commands execute across multiple
RuntimeCycle()iterations in discrete stages.AdvanceCommandStage()transitions between stages;WaitForMicros()provides non-blocking delays. This enables cooperative multitasking across modules without threads or interrupts. - Command queue priority: Active command runs to completion first, then newly queued commands, then recurrent
commands (if cycle delay has elapsed).
ResolveActiveCommand()implements this priority chain. - Compile-time prototype resolution:
ResolvePrototype<T>()maps C++ types to wire protocol codes at compile time viakPrototypeLookup. Supports 11 scalar types and C-style arrays at specific element counts. Static assertions catch unsupported type/count combinations during compilation. - PACKED_STRUCT serialization: All message structures use
PACKED_STRUCTfor byte-level serialization with no compiler padding, ensuring binary compatibility with the companion Python library. - Status code returns: All operations return enum status codes rather than throwing exceptions, consistent with embedded C++ patterns.
- Platform-conditional compilation:
elapsedMillisdependency is included only for non-Teensy boards; Teensy provides nativeelapsedMicros. Maximum data payload sizes vary by platform (Teensy: 248 bytes, Due: 244 bytes, Mega: 52 bytes); the underlying serial buffers are larger (8192/256/64 bytes on Teensy/Due/Mega). using namespace axmc_shared_assets;in source files is intentional for readability in the embedded context.- LED error indication:
LED_BUILTINis used as a fallback error channel when serial communication has failed. - Module core status codes 0-3 are reserved by the base
Moduleclass. Custom module status codes must use the range 51-250, unique within each module class.
| Library | Purpose | Platforms |
|---|---|---|
| Arduino.h | Core Arduino framework (Serial, Stream, types) | All |
| elapsedMillis | Non-blocking timers on non-Teensy boards | atmelsam, atmelavr |
| digitalWriteFast | Fast GPIO read/write operations | All |
| ataraxis-transport-layer-mc | CRC-16 checksummed serial communication with COBS | All |
This is a PlatformIO library project. The platformio.ini defines three board environments:
| Environment | Board | Platform | Monitor speed |
|---|---|---|---|
teensy41 |
Teensy 4.1 | teensy | 115200 |
due |
Arduino Due | atmelsam | 5250000 |
mega |
Arduino Mega | atmelavr | 1000000 |
All environments use the Arduino framework, Unity test framework, and -std=c++17 build flag.
pio run -e teensy41 # Build for Teensy 4.1
pio run -e due # Build for Arduino Due
pio run -e mega # Build for Arduino Mega
pio test -e teensy41 # Run Unity tests on Teensy 4.1
pio check -e teensy41 # Run static analysis
tox -e docs # Build Sphinx API documentation (Doxygen + Breathe)Modifying Kernel:
- Review
src/kernel.hfor the current implementation - Understand the message routing architecture:
ReceiveMessage()parses protocol,RunKernelCommand()handles kernel commands,RunModuleCommands()dispatches to modules viaResolveTargetModule() - All status codes return via
SendServiceMessage()orSendDataMessage()— do not introduce exception handling - Keepalive logic uses a two-window miss threshold; modifying this affects safety guarantees
- LED error indication is a fallback — it must remain functional even when serial communication has failed
Modifying Communication:
- Review
src/communication.hfor the current implementation - Message structures are defined in
src/axmc_shared_assets.h— changes to structure layout require companion library synchronization TransportLayerfromataraxis-transport-layer-mchandles CRC and COBS — do not reimplement these- All 13 protocol codes must remain synchronized with
ataraxis-communication-interface ExtractModuleParameters()uses template parameter deduction — the storage object type determines extraction
Implementing custom Module subclasses:
- Invoke the
/firmware-moduleskill for guided module creation - Review
examples/example_module.hfor the TestModule reference implementation - Override
SetupModule(),SetCustomParameters(), andRunActiveCommand()— all three are required - Use stage-based execution with
AdvanceCommandStage()andWaitForMicros()for non-blocking operations - Custom parameters must use
PACKED_STRUCTfor serialization and match the PC-side parameter structure exactly - Custom status codes must be in the range 51-250 and unique within the module class
Modifying prototype resolution:
- Review the
kPrototypesenum andkPrototypeLookuptable insrc/axmc_shared_assets.h PrototypeTypeIndex<T>()maps scalar types to row indices (11 types: bool through double)ResolvePrototype<T>()handles both scalar types and C-style arrays viais_arraytrait detection- Adding new prototype entries requires updating both the enum, the lookup table, and the companion Python library
- Maximum payload size is constrained by
TransportLayerbuffer sizes (platform-dependent)
Important considerations:
- Maximum data payload size varies by platform: Teensy (248 bytes), Due (244 bytes), Mega (52 bytes). These are the
data-object limits (
kMaximumPayloadSize - sizeof(ModuleData)), not the raw serial buffer sizes (8192/256/64 bytes) - The reimplemented type traits in
axmc_shared_assets.hexist because Arduino Mega lacks<type_traits> library.jsoncontrols what gets exported to the PlatformIO registry —main.cppis explicitly excluded- Controller ID 0 is reserved; valid range is 1-255
- Module type and module ID are both
uint8_t— the(type, id)pair must be unique across all modules managed by a single Kernel instance