SGKEMBEDDED PERFORMANCEEpicTunerSDK · PrereleaseContact ↗
EpicTuner SDK/ Calibration service (SDK 1.0, et.tune.v1)

Download the complete Markdown manual ↓
One file with guides, API headers and examples for developers and coding agents.

Calibration service (SDK 1.0, et.tune.v1)

The optional ET_SERVICE_TUNE table is an et_tune_service, layout-compatible with et_read_service. Negotiate version 1.0. tune.read is needed to negotiate; every operation is independently checked against the worker session's granted capabilities at both ends. Existing C ABI 1.0/1.1 prefixes are unchanged. Use epictuner/tune.h from C, or epictuner/sdk/tune.hpp from C++20.

All requests and callbacks run on the worker dispatcher. Inputs are copied before return, replies are borrowed until callback return. Limits, cancellation, acknowledgement and terminal-callback semantics are those in READ.md. Cancelling before dispatch prevents local changes. An already accepted commit is authoritative; cancellation is never a rollback. A transport timeout never means it is safe to retry a write: refresh first.

Request mapping

Initialize with Reads::make(operation, projectGeneration). Unused fields must remain at their defaults. count is 1..32 for catalog/snapshot pages. A revision is a monotonically advancing 32-bit host token, returned in reply schema. Project generations are the same as the project/read service. Revision changes are conservative: manual edits, AutoTune, project/save and connection changes invalidate an old preview. Never derive a revision by adding to it.

Operation Request Reply
CATALOG offset/count Paginated field/table/curve IDs; item label is kind, units is field units or backing value field; text is definition SHA-256; schema is revision
SNAPSHOT id is field/table/curve ID; offset/count are value indices items contain actual stored physical values and element indices in sequence; text is bounded JSON metadata
PROPOSE id is definition SHA-256; schema is base revision; text is proposal below Host-owned proposal handle and normalized preview values; does not modify calibration
APPLY same definition/base revision plus proposal handle Consumes that session-owned proposal; actual stored values and local acceptance flags
UNDO / REDO definition and current revision One labeled coherent group for the last accepted plugin transaction; rejects if another edit intervened
STATUS generation Current RAM readback status in flags/text; revision in schema
BURN definition and current revision Opens host confirmation; does not burn on receipt; requires separate tune.burn capability
DISCARD proposal handle Releases an unused preview; no apply capability needed

PROPOSE and DISCARD require tune.propose; APPLY/UNDO/REDO require tune.apply. CATALOG/SNAPSHOT/STATUS require tune.read. Handles are scoped to worker session and project generation. There are at most eight outstanding proposals per worker; DISCARD unused previews. Refreshing a revision retires older previews. Restart, project replacement and disconnect invalidate proposals without replaying them.

A proposal is UTF-8 TSV, with a nonempty label of at most 128 characters on its first line, followed by 1..64 lines field<TAB>index<TAB>expected<TAB>requested. The entire payload is at most 4096 bytes. Field names and labels cannot contain embedded tab/newline/NUL. Use the supplied encoder rather than locale-dependent number formatting:

const auto body = et::sdk::Tune::proposal("Fuel correction", {
    {"fuel", 0, oldValue, newValue}
});
auto request = et::sdk::Reads::make(ET_TUNE_PROPOSE, generation);
request.id = et::sdk::string(definitionHash);
request.schema = baseRevision;
request.text = et::sdk::string(body);
tune.request(request, previewCallback);

Preview/result items use id = field, sequence = element index, timestamp = expected old value, value = normalized stored value. This mapping is specific to tune operations; timestamp is not a time for a tune item.

Snapshot JSON includes id, units, digits, bounds and whether each bound exists, shape, enum value/label pairs, readOnly, and native field type. Table/curve metadata also includes kind, title, axisLabels, backing x/y/z field IDs and read-only axes. Read their backing fields separately to obtain axis values. String/PC-variable and protected/read-only axis writes are rejected; this numeric service never exposes raw page pointers. Unsupported metadata exceeding 4096 bytes returns a limit error rather than truncating a definition.

Correctness and ECU outcomes

The host validates every element on an isolated copy using ProjectManager's storage/scaling rules. It rejects malformed numbers, bounds, dimensions, duplicate cells, old-value conflicts, protected axes and overlapping/scaling changes whose final stored values disagree with the proposed normalization. It serializes and reads back the candidate before publishing the live state once. The normal host write queue receives changed spans after local acceptance. There are no partial local commits on validation failure; undo reverses the complete accepted group.

LOCAL_ACCEPTED is distinct from RAM_UNVERIFIED, RAM_VERIFIED, RAM_FAILED, OFFLINE, and FLASH_PENDING. In connected mode the comms thread drains the normal write queue and reads ECU pages to verify the exact accepted snapshot. STATUS reports the result only while the project/revision still matches. A failed or mismatched readback retains the local tune and directs the user to the normal synchronization flow. It does not replay or silently roll back physical writes. Whole-page readback briefly pauses polling on the communications thread.

Firmware updates, tune synchronization and packet-proxy ownership block edits. Disconnected operation is rejected unless the project is explicitly offline. Only verified Serial/TcpBridge/Mock local project connections are supported; remote sessions are rejected. Burn is a separate confirmation tied to the current session, generation and revision. The existing Burn flow reports its result; opening a panel, reconnecting, proposing, applying or restoring state never burns.

See PREFABS.md and the two calibration examples. The fuel demo accepts offline/Mock proposals only and has no Burn capability.