The shim-layer problem
In real automotive firmware, signals are never referenced by their DBC name. Between the DBC definition and the C source file sits one or more abstraction layers:BrakeController, you need to know:
- Which signals does it consume? (
BrakeDemand.Value,EngineData.RPM,VehicleSpeed.Speed) - Which signals does it produce? (
BrakeStatus.Active,BrakeStatus.Pressure)
crucihil analyze does it in under a minute.
How it works — the full pipeline
Stage 1 — Identifier extraction (tree-sitter)
tree-sitter parses every.c, .cpp, .h, .hpp, .cc, .cxx file under --source and any --dep paths. It collects every node of type identifier, field_identifier, and type_identifier from the AST — a broad sweep that captures function calls, variable names, macro names, and type names.
The result is a set of raw strings like:
Stage 2 — Noise filter
A static blocklist removes:- C/C++ keywords (
int,static,typedef, …) - AUTOSAR primitive types (
uint8_t,Std_ReturnType,E_OK, …) - Common local variable names (
value,result,status,i, …) - Any identifier shorter than 4 characters
- Any identifier starting with
__
Stage 3 — Signal corpus
DBC files are parsed with cantools. EveryMessageName.SignalName pair becomes a corpus entry:
can_dbc → CAN, eth_dbc → ETH. Explicit --dbc paths default to unknown.
Stage 4 — AI matching
The AI receives:- The filtered identifier list (up to 500 entries)
- The full signal corpus with interface labels
- A system prompt that explains the direction rules (Read/Receive/Get → INPUT, Write/Send/Set → OUTPUT)
review_required: true when confidence < 0.85, and deduplicates by signal — keeping only the highest-confidence match when a signal is matched via multiple shim paths.
Confidence score system
The direction inference rules
The AI determines input vs. output from the shim identifier’s verb:
Ambiguous identifiers are classified as INPUT when context is insufficient.
Using —dep for better coverage
Many AUTOSAR SWCs have this pattern:Rte_Read_BC_BrakeDemandVal is declared in rte/Rte_BrakeController.h, not in the SWC source itself. Without --dep rte/Rte_BrakeController.h, tree-sitter still finds the call — but the additional type annotations in the header make the semantic match stronger.
Good dependency pattern
Avoid
Multi-interface support
CruciHiL supports DBC-encoded definitions for any interface type. A singlecrucihil analyze call can match signals across multiple buses:
can_dbc = "..."→CANeth_dbc = "..."→ETH
--dbc, defaulting to unknown unless the TOML key is used.
What is NOT sent to the AI
CruciHiL never sends raw source code to the AI — only the extracted identifier list and the DBC signal corpus. This means:- Firmware IP (algorithms, constants, proprietary logic) stays on your machine
- The AI never sees function bodies, comments, or string literals
- Only a filtered list of identifier names (up to 500) is transmitted
Integration with generate_test_suite
The output ofcrucihil analyze feeds directly into test generation: