Skip to main content

HAL Integration

EdgeEmbed Runtime dispatches platform work through a dynamic backend plugin. The SDK ships libmock_hal.so and its source as the reference implementation.

Plugin Contract

A production backend should:

  1. Include include/edgeembed_backend_abi.h.
  2. Declare the required ABI with EDGEEMBED_BACKEND_ABI_REQUIRED(major, minor).
  3. Implement a static edgeembed_backend_ops_t table.
  4. Export edgeembed_backend_entry() with C linkage and default visibility.
  5. Build as a shared object loaded from the bundle's backends/ directory.
#include <edgeembed_backend_abi.h>

EDGEEMBED_BACKEND_ABI_REQUIRED(0, 0);

static edgeembed_result_t backend_init(
void** out_ctx,
const edgeembed_backend_init_t* init) {
(void)init;
*out_ctx = NULL;
return EDGEEMBED_OK;
}

static edgeembed_result_t backend_dispatch(
void* ctx,
const edgeembed_action_t* action) {
(void)ctx;
(void)action;
return EDGEEMBED_OK;
}

static edgeembed_result_t backend_cancel(void* ctx, uint32_t action_id) {
(void)ctx;
(void)action_id;
return EDGEEMBED_OK;
}

static edgeembed_result_t backend_query_capabilities(
void* ctx,
edgeembed_capabilities_t* out_caps) {
(void)ctx;
*out_caps = (edgeembed_capabilities_t){0};
return EDGEEMBED_OK;
}

static void backend_shutdown(void* ctx) {
(void)ctx;
}

static const edgeembed_backend_ops_t k_ops = {
.abi_version = EDGEEMBED_BACKEND_ABI_VERSION,
.name = "robot_mock_plugin",
.version = "1.0.0",
.init = backend_init,
.dispatch = backend_dispatch,
.cancel = backend_cancel,
.query_capabilities = backend_query_capabilities,
.shutdown = backend_shutdown,
};

EDGEEMBED_EXPORT const edgeembed_backend_ops_t* edgeembed_backend_entry(void) {
return &k_ops;
}

dispatch() must return quickly. Long-running platform work should be queued by the plugin, then reported asynchronously through the edgeembed_ack_callback_t provided in edgeembed_backend_init_t.

Backend Selection

Backend selection is part of the loaded bundle. The robotics demo bundle keeps plugin artifacts under backends/:

robotics_bundle/
manifest.json
events.json
intents.json
actions.json
action_mapping.json
policy.json
resources.json
concurrency.json
backends/
robot_mock_plugin.so
robot_mock_plugin.manifest.json

The plugin table name must match the backend manifest's name field. During edgeembed_load_bundle(), the loader checks the plugin's exported edgeembed_backend_abi_required symbol before it calls ops->init(). A missing or incompatible ABI declaration rejects the bundle with EDGEEMBED_ERR_BACKEND_ABI_MISMATCH.

Runtime Open Flow

edgeembed_init()
|
v
edgeembed_load_bundle("robotics_bundle")
|
v
read manifest.json and vocabulary files
|
v
load backends/<plugin>.so
|
v
resolve edgeembed_backend_abi_required
|
v
resolve edgeembed_backend_entry()
|
v
ops->init(&ctx, &init)
|
v
ops->query_capabilities(ctx, &caps)
|
v
Execution Engine calls ops->dispatch(ctx, &action)

Backend ACK and NACK records use edgeembed_ack_t. On success, emit EDGEEMBED_ACK_ACCEPTED, then EDGEEMBED_ACK_STARTED, then EDGEEMBED_ACK_COMPLETED. On failure, emit EDGEEMBED_ACK_ACCEPTED, then EDGEEMBED_ACK_STARTED, then EDGEEMBED_ACK_FAILED with an edgeembed_nack_kind_t value of EDGEEMBED_NACK_TRANSIENT or EDGEEMBED_NACK_FATAL. A cancelled operation should emit EDGEEMBED_ACK_CANCELLED when the backend actively cancels it.

Reference Mock HAL

cmake -S hal/mock_hal -B build/mock_hal
cmake --build build/mock_hal

The output is build/mock_hal/libmock_hal.so. Use it to understand ACK flow, command dispatch, failure injection, and capability reporting before implementing a platform-specific backend.