Skip to main content

Runtime API

[!IMPORTANT] This page is generated from the public C headers under firmware/lib/zplc_core/include/. Edit the headers or rerun python3 tools/docs/generate_runtime_reference.py instead of editing this file manually.

The Spanish wrapper text is localized, while API names, signatures, and source-derived descriptions remain anchored to the English headers to avoid documentation drift.

Source headers

  • firmware/lib/zplc_core/include/zplc_comm_dispatch.h
  • firmware/lib/zplc_core/include/zplc_core.h
  • firmware/lib/zplc_core/include/zplc_debug.h
  • firmware/lib/zplc_core/include/zplc_hal.h
  • firmware/lib/zplc_core/include/zplc_isa.h
  • firmware/lib/zplc_core/include/zplc_loader.h
  • firmware/lib/zplc_core/include/zplc_scheduler.h

zplc_comm_dispatch.h

zplc_comm_dispatch.h

Source: firmware/lib/zplc_core/include/zplc_comm_dispatch.h

Functions

zplc_comm_register_handler

int zplc_comm_register_handler(zplc_comm_fb_kind_t kind, zplc_comm_handler_t fn);

Source summary: Register a handler for a communication FB kind.

Parameters

NameTypeSource description
kindzplc_comm_fb_kind_t
fnzplc_comm_handler_t

zplc_comm_fb_exec

int zplc_comm_fb_exec(zplc_comm_fb_kind_t kind, uint8_t *fb_mem);

Source summary: Execute a communication FB instance (called by VM from OP_COMM_EXEC).

Parameters

NameTypeSource description
kindzplc_comm_fb_kind_t
fb_memuint8_t *

zplc_comm_fb_reset

int zplc_comm_fb_reset(zplc_comm_fb_kind_t kind, uint8_t *fb_mem);

Source summary: Reset a communication FB instance (called by VM from OP_COMM_RESET).

Parameters

NameTypeSource description
kindzplc_comm_fb_kind_t
fb_memuint8_t *

Types

NameKindSource summary
zplc_comm_fb_kind_tEnumCommunication function block kind identifiers.
zplc_comm_status_tEnumCommunication status codes written to FB.STATUS.
zplc_comm_handler_tTypedefComm FB handler function type.

Constants and macros

None.

zplc_core.h

ZPLC Core Runtime Public API

This header declares the public interface for the ZPLC Virtual Machine. The API supports two usage patterns: 1. Legacy Singleton API (zplc_core_): Uses a default VM instance. Simple to use for single-task applications. 2. Instance-based API (zplc_vm_): Each task gets its own VM instance. Required for multi-task scheduling where each task has private state. Memory Model: - IPI/OPI: Shared across all VM instances (synchronized by scheduler) - Work/Retain: Shared (tasks coordinate via addresses) - Stack/CallStack/PC: Private per VM instance - Code: Shared (multiple VMs can reference same code with different entry points)

Source: firmware/lib/zplc_core/include/zplc_core.h

Functions

zplc_mem_init

int zplc_mem_init(void);

Source summary: Initialize shared memory regions.

Zeros IPI, OPI, Work, and Retain memory. Call once at system startup, before creating any VM instances.

Parameters

NameTypeSource description
None.

Source return value: 0 on success

zplc_mem_get_region

uint8_t* zplc_mem_get_region(uint16_t base);

Source summary: Get pointer to shared memory region.

Parameters

NameTypeSource description
baseuint16_tBase address (ZPLC_MEM_IPI_BASE, etc.)

Source return value: Pointer to memory region, or NULL if invalid

zplc_mem_load_code

int zplc_mem_load_code(const uint8_t *code, size_t size, uint16_t offset);

Source summary: Load code into the shared code segment.

Parameters

NameTypeSource description
codeconst uint8_t *Bytecode to load
sizesize_tSize in bytes
offsetuint16_tOffset within code segment (for multiple programs)

Source return value: 0 on success, negative on error

zplc_mem_get_code

const uint8_t* zplc_mem_get_code(uint16_t offset, size_t size);

Source summary: Get pointer to code segment.

Parameters

NameTypeSource description
offsetuint16_tOffset within code segment
sizesize_tSize of code to access

Source return value: Pointer to code, or NULL if out of bounds

zplc_mem_get_code_size

uint32_t zplc_mem_get_code_size(void);

Source summary: Get current loaded code size.

Parameters

NameTypeSource description
None.

Source return value: Total bytes loaded in code segment

zplc_vm_init

int zplc_vm_init(zplc_vm_t *vm);

Source summary: Initialize a VM instance.

Resets all execution state. Does not allocate memory. The zplc_vm_t struct must already be allocated.

Parameters

NameTypeSource description
vmzplc_vm_t *Pointer to VM instance

Source return value: 0 on success

zplc_vm_set_entry

int zplc_vm_set_entry(zplc_vm_t *vm, uint16_t entry_point, uint32_t code_size);

Source summary: Configure VM to execute code at specified entry point.

Parameters

NameTypeSource description
vmzplc_vm_t *Pointer to VM instance
entry_pointuint16_tOffset within code segment
code_sizeuint32_tSize of code for this task

Source return value: 0 on success, negative on error

zplc_vm_step

int zplc_vm_step(zplc_vm_t *vm);

Source summary: Execute a single instruction.

Parameters

NameTypeSource description
vmzplc_vm_t *Pointer to VM instance

Source return value: ZPLC_VM_OK on success, error code otherwise

zplc_vm_run

int zplc_vm_run(zplc_vm_t *vm, uint32_t max_instructions);

Source summary: Run VM for a fixed number of instructions or until halted.

Parameters

NameTypeSource description
vmzplc_vm_t *Pointer to VM instance
max_instructionsuint32_tMaximum instructions (0 = unlimited)

Source return value: Number of instructions executed, or negative error code

zplc_vm_run_cycle

int zplc_vm_run_cycle(zplc_vm_t *vm);

Source summary: Run one complete PLC scan cycle.

Resets PC to entry point, executes until HALT, returns.

Parameters

NameTypeSource description
vmzplc_vm_t *Pointer to VM instance

Source return value: Number of instructions executed, or negative error code

zplc_vm_reset_cycle

void zplc_vm_reset_cycle(zplc_vm_t *vm);

Source summary: Reset VM for a new cycle without full init.

Faster than zplc_vm_init() - only resets PC, SP, and status.

Parameters

NameTypeSource description
vmzplc_vm_t *Pointer to VM instance

zplc_vm_get_error

int zplc_vm_get_error(const zplc_vm_t *vm);

Source summary: Get VM error code.

Parameters

NameTypeSource description
vmconst zplc_vm_t *Pointer to VM instance

Source return value: Error code

zplc_vm_is_halted

int zplc_vm_is_halted(const zplc_vm_t *vm);

Source summary: Check if VM is halted.

Parameters

NameTypeSource description
vmconst zplc_vm_t *Pointer to VM instance

Source return value: 1 if halted, 0 if running

zplc_vm_get_stack

uint32_t zplc_vm_get_stack(const zplc_vm_t *vm, uint16_t index);

Source summary: Get stack value.

Parameters

NameTypeSource description
vmconst zplc_vm_t *Pointer to VM instance
indexuint16_tStack index (0 = bottom)

Source return value: Stack value, or 0 if out of bounds

zplc_vm_get_sp

uint16_t zplc_vm_get_sp(const zplc_vm_t *vm);

Source summary: Get stack pointer.

Parameters

NameTypeSource description
vmconst zplc_vm_t *Pointer to VM instance

Source return value: Stack pointer

zplc_vm_get_pc

uint16_t zplc_vm_get_pc(const zplc_vm_t *vm);

Source summary: Get program counter.

Parameters

NameTypeSource description
vmconst zplc_vm_t *Pointer to VM instance

Source return value: Program counter

zplc_vm_is_paused

int zplc_vm_is_paused(const zplc_vm_t *vm);

Source summary: Check if VM is paused at a breakpoint.

Parameters

NameTypeSource description
vmconst zplc_vm_t *Pointer to VM instance

Source return value: 1 if paused, 0 if running or halted

zplc_vm_resume

int zplc_vm_resume(zplc_vm_t *vm);

Source summary: Resume execution after a breakpoint pause.

Clears the paused flag so the next zplc_vm_step() continues execution.

Parameters

NameTypeSource description
vmzplc_vm_t *Pointer to VM instance

Source return value: 0 on success, -1 if NULL

zplc_vm_add_breakpoint

int zplc_vm_add_breakpoint(zplc_vm_t *vm, uint16_t pc);

Source summary: Add a breakpoint at a program counter address.

When the VM's PC reaches this address, execution will pause.

Parameters

NameTypeSource description
vmzplc_vm_t *Pointer to VM instance
pcuint16_tProgram counter address to break at

Source return value: 0 on success, -1 if NULL, -2 if breakpoint table full, -3 if already exists

zplc_vm_remove_breakpoint

int zplc_vm_remove_breakpoint(zplc_vm_t *vm, uint16_t pc);

Source summary: Remove a breakpoint at a program counter address.

Parameters

NameTypeSource description
vmzplc_vm_t *Pointer to VM instance
pcuint16_tProgram counter address to remove

Source return value: 0 on success, -1 if NULL, -2 if not found

zplc_vm_clear_breakpoints

int zplc_vm_clear_breakpoints(zplc_vm_t *vm);

Source summary: Clear all breakpoints.

Parameters

NameTypeSource description
vmzplc_vm_t *Pointer to VM instance

Source return value: 0 on success, -1 if NULL

zplc_vm_get_breakpoint_count

uint8_t zplc_vm_get_breakpoint_count(const zplc_vm_t *vm);

Source summary: Get the number of active breakpoints.

Parameters

NameTypeSource description
vmconst zplc_vm_t *Pointer to VM instance

Source return value: Number of breakpoints, or 0 if NULL

zplc_vm_get_breakpoint

uint16_t zplc_vm_get_breakpoint(const zplc_vm_t *vm, uint8_t index);

Source summary: Get a breakpoint address by index.

Parameters

NameTypeSource description
vmconst zplc_vm_t *Pointer to VM instance
indexuint8_tIndex in breakpoint array (0 to count-1)

Source return value: PC address of breakpoint, or 0xFFFF if invalid

zplc_ipi_write32

int zplc_ipi_write32(uint16_t offset, uint32_t value);

Source summary: Write a 32-bit value to IPI.

Parameters

NameTypeSource description
offsetuint16_tByte offset within IPI
valueuint32_tValue to write

Source return value: 0 on success, -1 if out of bounds

zplc_ipi_write16

int zplc_ipi_write16(uint16_t offset, uint16_t value);

Source summary: Write a 16-bit value to IPI.

Parameters

NameTypeSource description
offsetuint16_tByte offset within IPI
valueuint16_tValue to write

Source return value: 0 on success, -1 if out of bounds

zplc_ipi_write8

int zplc_ipi_write8(uint16_t offset, uint8_t value);

Source summary: Write an 8-bit value to IPI.

Parameters

NameTypeSource description
offsetuint16_tByte offset within IPI
valueuint8_tValue to write

Source return value: 0 on success, -1 if out of bounds

zplc_ipi_read32

uint32_t zplc_ipi_read32(uint16_t offset);

Source summary: Read a 32-bit value from IPI.

Parameters

NameTypeSource description
offsetuint16_tByte offset within IPI

Source return value: Value at offset, or 0 if out of bounds

zplc_ipi_read16

uint16_t zplc_ipi_read16(uint16_t offset);

Source summary: Read a 16-bit value from IPI.

Parameters

NameTypeSource description
offsetuint16_tByte offset within IPI

Source return value: Value at offset, or 0 if out of bounds

zplc_ipi_read8

uint8_t zplc_ipi_read8(uint16_t offset);

Source summary: Read an 8-bit value from IPI.

Parameters

NameTypeSource description
offsetuint16_tByte offset within IPI

Source return value: Value at offset, or 0 if out of bounds

zplc_opi_read32

uint32_t zplc_opi_read32(uint16_t offset);

Source summary: Read a 32-bit value from OPI.

Parameters

NameTypeSource description
offsetuint16_tByte offset within OPI

Source return value: Value at offset, or 0 if out of bounds

zplc_opi_read16

uint16_t zplc_opi_read16(uint16_t offset);

Source summary: Read a 16-bit value from OPI.

Parameters

NameTypeSource description
offsetuint16_tByte offset within OPI

Source return value: Value at offset, or 0 if out of bounds

zplc_opi_read8

uint8_t zplc_opi_read8(uint16_t offset);

Source summary: Read an 8-bit value from OPI.

Parameters

NameTypeSource description
offsetuint16_tByte offset within OPI

Source return value: Value at offset, or 0 if out of bounds

zplc_force_set_bytes

int zplc_force_set_bytes(uint16_t addr, const uint8_t *bytes, uint16_t size);

Source summary: Set a forced byte range and apply it immediately.

Parameters

NameTypeSource description
addruint16_tAbsolute logical address
bytesconst uint8_t *Forced bytes buffer
sizeuint16_tNumber of bytes in the buffer

Source return value: 0 on success, negative on error

zplc_force_clear

int zplc_force_clear(uint16_t addr);

Source summary: Clear the force entry that starts at the given address.

Parameters

NameTypeSource description
addruint16_tAbsolute logical address of the force entry

Source return value: 0 on success, negative on error

zplc_force_clear_all

void zplc_force_clear_all(void);

Source summary: Clear all active force entries.

Parameters

NameTypeSource description
None.

zplc_force_get_count

uint8_t zplc_force_get_count(void);

Source summary: Get the number of active force entries.

Parameters

NameTypeSource description
None.

Source return value: Active entry count

zplc_force_get

int zplc_force_get(uint8_t index, uint16_t *addr, uint16_t *size, uint8_t *bytes);

Source summary: Get a force entry by index.

Parameters

NameTypeSource description
indexuint8_tForce table index
addruint16_t *Output absolute address
sizeuint16_t *Output byte count
bytesuint8_t *Output buffer receiving the stored bytes

Source return value: 0 on success, negative on error

zplc_force_write_bytes

int zplc_force_write_bytes(uint16_t addr, const uint8_t *bytes, uint16_t size);

Source summary: Write raw bytes then re-apply any overlapping force overrides.

Parameters

NameTypeSource description
addruint16_tAbsolute logical address
bytesconst uint8_t *Source bytes
sizeuint16_tNumber of bytes to write

Source return value: 0 on success, negative on error

zplc_pi_lock

int zplc_pi_lock(void);

Source summary: Lock the Process Image.

Acquires a mutex or spinlock to protect memory regions. Must be called before accessing IPI/OPI from external threads.

Parameters

NameTypeSource description
None.

Source return value: 0 on success, negative on error or timeout

zplc_pi_unlock

void zplc_pi_unlock(void);

Source summary: Unlock the Process Image.

Releases the lock acquired by zplc_pi_lock.

Parameters

NameTypeSource description
None.

zplc_core_get_tag_count

uint16_t zplc_core_get_tag_count(void);

Source summary: Get the number of variable tags loaded.

Parameters

NameTypeSource description
None.

zplc_core_get_tag

const zplc_tag_entry_t* zplc_core_get_tag(uint16_t index);

Source summary: Get a variable tag by index.

Parameters

NameTypeSource description
indexuint16_tTag index (0 to count-1)

Source return value: Pointer to tag entry, or NULL if out of bounds.

zplc_core_version

const char* zplc_core_version(void);

Source summary: Get the ZPLC core version string.

Parameters

NameTypeSource description
None.

Source return value: Version string in format "major.minor.patch"

zplc_core_init

int zplc_core_init(void);

Source summary: Initialize the ZPLC core.

Initializes shared memory and default VM instance.

Parameters

NameTypeSource description
None.

Source return value: 0 on success

zplc_core_shutdown

int zplc_core_shutdown(void);

Source summary: Shutdown the ZPLC core.

Parameters

NameTypeSource description
None.

Source return value: 0 on success

zplc_core_load

int zplc_core_load(const uint8_t *binary, size_t size);

Source summary: Load a .zplc binary program.

Parameters

NameTypeSource description
binaryconst uint8_t *Pointer to .zplc file contents
sizesize_tSize of binary data

Source return value: 0 on success, negative error code otherwise

zplc_core_load_raw

int zplc_core_load_raw(const uint8_t *bytecode, size_t size);

Source summary: Load raw bytecode directly.

Parameters

NameTypeSource description
bytecodeconst uint8_t *Raw bytecode bytes
sizesize_tSize of bytecode

Source return value: 0 on success

zplc_core_step

int zplc_core_step(void);

Source summary: Execute a single instruction.

Parameters

NameTypeSource description
None.

Source return value: ZPLC_VM_OK on success, error code otherwise

zplc_core_run

int zplc_core_run(uint32_t max_instructions);

Source summary: Run VM for a fixed number of instructions.

Parameters

NameTypeSource description
max_instructionsuint32_tMaximum instructions (0 = unlimited)

Source return value: Number of instructions executed, or negative error code

zplc_core_run_cycle

int zplc_core_run_cycle(void);

Source summary: Run one complete PLC scan cycle.

Parameters

NameTypeSource description
None.

Source return value: Number of instructions executed, or negative error code

zplc_core_get_state

const zplc_vm_state_t* zplc_core_get_state(void);

Source summary: Get a read-only pointer to the default VM state.

Parameters

NameTypeSource description
None.

Source return value: Pointer to VM state (legacy zplc_vm_state_t)

zplc_core_get_sp

uint16_t zplc_core_get_sp(void);

Source summary: Get the current stack pointer.

Parameters

NameTypeSource description
None.

Source return value: Stack pointer value

zplc_core_get_pc

uint16_t zplc_core_get_pc(void);

Source summary: Get the current program counter.

Parameters

NameTypeSource description
None.

Source return value: Program counter value

zplc_core_get_stack

uint32_t zplc_core_get_stack(uint16_t index);

Source summary: Get a value from the evaluation stack.

Parameters

NameTypeSource description
indexuint16_tStack index (0 = bottom)

Source return value: Stack value

zplc_core_get_error

int zplc_core_get_error(void);

Source summary: Get the last error code.

Parameters

NameTypeSource description
None.

Source return value: Error code

zplc_core_is_halted

int zplc_core_is_halted(void);

Source summary: Check if VM is halted.

Parameters

NameTypeSource description
None.

Source return value: 1 if halted, 0 if running

zplc_core_set_ipi

int zplc_core_set_ipi(uint16_t offset, uint32_t value);

Source summary: Write to IPI (legacy).

Parameters

NameTypeSource description
offsetuint16_tByte offset
valueuint32_t32-bit value

Source return value: 0 on success

zplc_core_set_ipi16

int zplc_core_set_ipi16(uint16_t offset, uint16_t value);

Source summary: Write 16-bit to IPI (legacy).

Parameters

NameTypeSource description
offsetuint16_tByte offset
valueuint16_t16-bit value

Source return value: 0 on success

zplc_core_get_opi

uint32_t zplc_core_get_opi(uint16_t offset);

Source summary: Read from OPI (legacy).

Parameters

NameTypeSource description
offsetuint16_tByte offset

Source return value: 32-bit value

zplc_core_get_default_vm

zplc_vm_t* zplc_core_get_default_vm(void);

Source summary: Get pointer to default VM instance.

Useful for transitioning code to instance-based API.

Parameters

NameTypeSource description
None.

Source return value: Pointer to default VM

zplc_core_load_tasks

int zplc_core_load_tasks(const uint8_t *binary, size_t size, zplc_task_def_t *tasks, uint8_t max_tasks);

Source summary: Load tasks from a .zplc binary containing a TASK segment.

Parses the TASK segment and populates an array of task definitions. Also loads the code segment into shared memory.

Parameters

NameTypeSource description
binaryconst uint8_t *Pointer to .zplc file contents
sizesize_tSize of binary data
taskszplc_task_def_t *Output array to fill with task definitions
max_tasksuint8_tMaximum number of tasks to load

Source return value: Number of tasks loaded, or negative error code

zplc_task_get_entry

static inline uint16_t zplc_task_get_entry(const zplc_task_def_t *task);

Source summary: Get entry point for a loaded task.

Parameters

NameTypeSource description
taskconst zplc_task_def_t *Pointer to task definition

Source return value: Entry point offset in code segment

zplc_task_get_interval_us

static inline uint32_t zplc_task_get_interval_us(const zplc_task_def_t *task);

Source summary: Get interval in microseconds for a task.

Parameters

NameTypeSource description
taskconst zplc_task_def_t *Pointer to task definition

Source return value: Interval in microseconds

zplc_task_get_priority

static inline uint8_t zplc_task_get_priority(const zplc_task_def_t *task);

Source summary: Get priority for a task.

Parameters

NameTypeSource description
taskconst zplc_task_def_t *Pointer to task definition

Source return value: Priority (0 = highest)

Types

NameKindSource summary
pcStructVM instance structure.

Constants and macros

None.

zplc_debug.h

ZPLC Hardware-in-the-Loop Debug API

This header declares the debug output API for HIL (Hardware-in-the-Loop) testing. When enabled, the runtime outputs JSON-formatted trace information via the Zephyr shell for parsing by the HIL test framework. The debug output is runtime-controllable (not compile-time), allowing the same firmware to be used in production and testing modes. Protocol: Line-based JSON with CRLF terminators. See: specs/002-hil-testing/contracts/debug-protocol.md

Source: firmware/lib/zplc_core/include/zplc_debug.h

Functions

hil_set_mode

void hil_set_mode(hil_mode_t mode);

Source summary: Set the HIL debug output mode.

Parameters

NameTypeSource description
modehil_mode_tThe desired debug mode

hil_get_mode

hil_mode_t hil_get_mode(void);

Source summary: Get the current HIL debug output mode.

Parameters

NameTypeSource description
None.

Source return value: Current debug mode

hil_set_shell

void hil_set_shell(const struct shell *sh);

Source summary: Set the shell instance for debug output.

Must be called before any trace functions. Typically called by the zplc hil mode shell command.

Parameters

NameTypeSource description
shconst struct shell *Pointer to shell instance

hil_trace_opcode

void hil_trace_opcode(uint8_t op, uint16_t pc, uint8_t sp, int32_t tos);

Source summary: Trace an opcode execution.

Emits: {"t":"opcode","op":"ADD","pc":18,"sp":2,"tos":7} Only outputs in HIL_MODE_VERBOSE.

Parameters

NameTypeSource description
opuint8_tOpcode value (from zplc_opcode_t)
pcuint16_tProgram counter BEFORE execution
spuint8_tStack pointer AFTER execution
tosint32_tTop of stack value AFTER execution (signed)

hil_trace_fb

void hil_trace_fb(const char *name, uint8_t id, bool q, int32_t et_or_cv);

Source summary: Trace a function block execution.

Emits: {"t":"fb","name":"TON","id":0,"q":true,"et":100} Outputs in HIL_MODE_SUMMARY and HIL_MODE_VERBOSE.

Parameters

NameTypeSource description
nameconst char *Function block type name (e.g., "TON", "CTU")
iduint8_tInstance ID (0-255)
qboolQ output value
et_or_cvint32_tElapsed time (timers) or current value (counters), -1 if N/A

hil_trace_task

void hil_trace_task(uint8_t id, uint32_t start_ms, uint32_t end_ms, uint32_t us, bool overrun);

Source summary: Trace a task completion.

Emits: {"t":"task","id":1,"start":1000,"end":1045,"us":45,"ovr":false} Outputs in HIL_MODE_SUMMARY and HIL_MODE_VERBOSE.

Parameters

NameTypeSource description
iduint8_tTask ID (0-7)
start_msuint32_tTask start time (ms since boot)
end_msuint32_tTask end time (ms since boot)
usuint32_tExecution time in microseconds
overrunboolTrue if task overran its period

hil_trace_cycle

void hil_trace_cycle(uint32_t n, uint32_t us, uint8_t tasks);

Source summary: Trace a VM cycle completion.

Emits: {"t":"cycle","n":100,"us":850,"tasks":3} Outputs in HIL_MODE_SUMMARY and HIL_MODE_VERBOSE.

Parameters

NameTypeSource description
nuint32_tCycle number (0-2^31)
usuint32_tTotal cycle time in microseconds
tasksuint8_tNumber of tasks executed this cycle

hil_trace_error

void hil_trace_error(uint8_t code, const char *msg, uint16_t pc);

Source summary: Trace a VM error.

Emits: {"t":"error","code":3,"msg":"DIV_BY_ZERO","pc":42} Always outputs regardless of mode (errors are always important).

Parameters

NameTypeSource description
codeuint8_tError code (from zplc_vm_error_t)
msgconst char *Human-readable error message
pcuint16_tProgram counter where error occurred

hil_trace_break

void hil_trace_break(uint16_t pc);

Source summary: Trace a breakpoint hit.

Emits: {"t":"break","pc":42} Always outputs regardless of mode (breakpoint events are critical).

Parameters

NameTypeSource description
pcuint16_tProgram counter where the breakpoint was hit

hil_trace_watch

void hil_trace_watch(uint16_t addr, const char *type, int32_t val);

Source summary: Trace a watched variable change.

Emits: {"t":"watch","addr":8192,"type":"i32","val":42}

Parameters

NameTypeSource description
addruint16_tVariable address
typeconst char *Type string: "i8", "i16", "i32", "u8", "u16", "u32", "f32", "bool"
valint32_tCurrent value (as signed 32-bit, caller converts)

hil_send_ready

void hil_send_ready(const char *fw_version, const char *caps);

Source summary: Send the ready signal on boot.

Emits: {"t":"ready","fw":"1.5.0","caps":["sched","hil"]} Should be called once after boot when shell is ready.

Parameters

NameTypeSource description
fw_versionconst char *Firmware version string (e.g., "1.5.0")
capsconst char *Comma-separated capability list (e.g., "sched,hil,sfc")

hil_send_ack

void hil_send_ack(const char *cmd, const char *val, bool ok, const char *err);

Source summary: Send a command acknowledgment.

Emits: {"t":"ack","cmd":"mode","val":"verbose","ok":true}

Parameters

NameTypeSource description
cmdconst char *Command name that was executed
valconst char *Value that was set
okboolTrue if command succeeded
errconst char *Error message if ok is false, NULL otherwise

hil_opcode_name

const char *hil_opcode_name(uint8_t op);

Source summary: Get the string name for an opcode.

Parameters

NameTypeSource description
opuint8_tOpcode value

Source return value: Opcode name string (e.g., "ADD", "PUSH32"), or "???" if unknown

hil_error_name

const char *hil_error_name(uint8_t code);

Source summary: Get the string name for a VM error code.

Parameters

NameTypeSource description
codeuint8_tError code (from zplc_vm_error_t)

Source return value: Error name string (e.g., "DIV_BY_ZERO"), or "UNKNOWN" if invalid

Types

NameKindSource summary
hil_mode_tEnumHIL debug output modes.

Constants and macros

None.

zplc_hal.h

ZPLC Hardware Abstraction Layer Interface

This header defines the contract between the ZPLC Core and the underlying platform. The Core NEVER calls hardware directly - all access goes through these functions. Each target platform (POSIX, Zephyr, WASM, Windows) provides its own implementation of this interface.

Source: firmware/lib/zplc_core/include/zplc_hal.h

Functions

zplc_hal_tick

uint32_t zplc_hal_tick(void);

Source summary: Get the current system tick in milliseconds.

This is the primary timekeeping function for the runtime scheduler. Must be monotonically increasing (no rollover handling required for at least 49 days with uint32_t).

Parameters

NameTypeSource description
None.

Source return value: Current tick count in milliseconds since system start.

Source notes:

  • Platform implementations: - POSIX: clock_gettime(CLOCK_MONOTONIC) - Zephyr: k_uptime_get() - WASM: performance.now()

zplc_hal_sleep

void zplc_hal_sleep(uint32_t ms);

Source summary: Sleep for the specified number of milliseconds.

Blocking sleep - use only for cycle timing, never in logic execution.

Parameters

NameTypeSource description
msuint32_tNumber of milliseconds to sleep.

Source notes:

  • Platform implementations: - POSIX: nanosleep() - Zephyr: k_msleep() - WASM: Atomics.wait() or async yield

zplc_hal_gpio_read

zplc_hal_result_t zplc_hal_gpio_read(uint8_t channel, uint8_t *value);

Source summary: Read a digital input channel.

Parameters

NameTypeSource description
channeluint8_tLogical channel number (0-based).
valueuint8_t *Pointer to store the read value (0 or 1).

Source return value: ZPLC_HAL_OK on success, error code otherwise.

zplc_hal_gpio_write

zplc_hal_result_t zplc_hal_gpio_write(uint8_t channel, uint8_t value);

Source summary: Write to a digital output channel.

Parameters

NameTypeSource description
channeluint8_tLogical channel number (0-based).
valueuint8_tValue to write (0 or 1).

Source return value: ZPLC_HAL_OK on success, error code otherwise.

zplc_hal_adc_read

zplc_hal_result_t zplc_hal_adc_read(uint8_t channel, uint16_t *value);

Source summary: Read an analog input channel.

Parameters

NameTypeSource description
channeluint8_tLogical channel number (0-based).
valueuint16_t *Pointer to store the read value (raw ADC counts or scaled).

Source return value: ZPLC_HAL_OK on success, error code otherwise.

zplc_hal_dac_write

zplc_hal_result_t zplc_hal_dac_write(uint8_t channel, uint16_t value);

Source summary: Write to an analog output channel (DAC).

Parameters

NameTypeSource description
channeluint8_tLogical channel number (0-based).
valueuint16_tValue to write (raw DAC counts or scaled).

Source return value: ZPLC_HAL_OK on success, error code otherwise.

zplc_hal_persist_save

zplc_hal_result_t zplc_hal_persist_save(const char *key, const void *data, size_t len);

Source summary: Save data to persistent storage.

Parameters

NameTypeSource description
keyconst char *Identifier string for the data block.
dataconst void *Pointer to data to save.
lensize_tLength of data in bytes.

Source return value: ZPLC_HAL_OK on success, error code otherwise.

zplc_hal_persist_load

zplc_hal_result_t zplc_hal_persist_load(const char *key, void *data, size_t len);

Source summary: Load data from persistent storage.

Parameters

NameTypeSource description
keyconst char *Identifier string for the data block.
datavoid *Buffer to load data into.
lensize_tMaximum length to read.

Source return value: ZPLC_HAL_OK on success, error code otherwise.

zplc_hal_persist_delete

zplc_hal_result_t zplc_hal_persist_delete(const char *key);

Source summary: Delete data from persistent storage.

Removes the specified key from persistent storage.

Parameters

NameTypeSource description
keyconst char *Identifier string for the data block to delete.

Source return value: ZPLC_HAL_OK on success, ZPLC_HAL_NOT_IMPL if key not found, error code otherwise.

zplc_hal_net_init

zplc_hal_result_t zplc_hal_net_init(void);

Source summary: Initialize the networking stack.

Parameters

NameTypeSource description
None.

Source return value: ZPLC_HAL_OK on success, error code otherwise.

zplc_hal_net_get_ip

zplc_hal_result_t zplc_hal_net_get_ip(char *buf, size_t len);

Source summary: Get the current IP address of the device.

Parameters

NameTypeSource description
bufchar *Buffer to store the IP address string (e.g., "192.168.1.100")
lensize_tMaximum length of the buffer

Source return value: ZPLC_HAL_OK on success, error code otherwise.

zplc_hal_dns_resolve

zplc_hal_result_t zplc_hal_dns_resolve(const char *hostname, char *ip_buf, size_t len);

Source summary: Resolve a hostname to an IP address.

Parameters

NameTypeSource description
hostnameconst char *Hostname string to resolve
ip_bufchar *Buffer to store the resolved IP address string
lensize_tMaximum length of the IP buffer

Source return value: ZPLC_HAL_OK on success, error code otherwise.

zplc_hal_mutex_create

zplc_hal_mutex_t zplc_hal_mutex_create(void);

Source summary: Create a new mutex.

Parameters

NameTypeSource description
None.

Source return value: Mutex handle on success, NULL on failure.

zplc_hal_mutex_lock

zplc_hal_result_t zplc_hal_mutex_lock(zplc_hal_mutex_t mutex);

Source summary: Lock a mutex. Blocks until available.

Parameters

NameTypeSource description
mutexzplc_hal_mutex_tMutex handle.

Source return value: ZPLC_HAL_OK on success, error code otherwise.

zplc_hal_mutex_unlock

zplc_hal_result_t zplc_hal_mutex_unlock(zplc_hal_mutex_t mutex);

Source summary: Unlock a mutex.

Parameters

NameTypeSource description
mutexzplc_hal_mutex_tMutex handle.

Source return value: ZPLC_HAL_OK on success, error code otherwise.

zplc_hal_socket_connect

zplc_hal_socket_t zplc_hal_socket_connect(const char *host, uint16_t port);

Source summary: Create a TCP socket and connect to a remote host.

Parameters

NameTypeSource description
hostconst char *Hostname or IP address string.
portuint16_tPort number.

Source return value: Socket handle on success, NULL on failure.

zplc_hal_socket_send

int32_t zplc_hal_socket_send(zplc_hal_socket_t sock, const void *data, size_t len);

Source summary: Send data over a socket.

Parameters

NameTypeSource description
sockzplc_hal_socket_tSocket handle.
dataconst void *Data buffer to send.
lensize_tLength of data.

Source return value: Number of bytes sent, or negative error code.

zplc_hal_socket_recv

int32_t zplc_hal_socket_recv(zplc_hal_socket_t sock, void *buf, size_t len);

Source summary: Receive data from a socket.

Parameters

NameTypeSource description
sockzplc_hal_socket_tSocket handle.
bufvoid *Buffer to receive into.
lensize_tMaximum bytes to receive.

Source return value: Number of bytes received, or negative error code.

zplc_hal_socket_close

zplc_hal_result_t zplc_hal_socket_close(zplc_hal_socket_t sock);

Source summary: Close a socket.

Parameters

NameTypeSource description
sockzplc_hal_socket_tSocket handle to close.

Source return value: ZPLC_HAL_OK on success, error code otherwise.

zplc_hal_log

void zplc_hal_log(const char *fmt, ...);

Source summary: Log a formatted message.

Printf-style logging for runtime diagnostics.

Parameters

NameTypeSource description
fmtconst char *Format string (printf-style).
...variadicVariable arguments.

Source notes:

  • Platform implementations: - POSIX: fprintf(stderr, ...) - Zephyr: printk() or LOG_INF() - WASM: console.log() via JS bridge

zplc_hal_init

zplc_hal_result_t zplc_hal_init(void);

Source summary: Initialize the HAL layer.

Must be called before any other HAL functions. Sets up hardware peripherals, timers, and communication channels.

Parameters

NameTypeSource description
None.

Source return value: ZPLC_HAL_OK on success, error code otherwise.

zplc_hal_shutdown

zplc_hal_result_t zplc_hal_shutdown(void);

Source summary: Shutdown the HAL layer.

Clean shutdown - close sockets, flush persistence, release resources.

Parameters

NameTypeSource description
None.

Source return value: ZPLC_HAL_OK on success, error code otherwise.

Types

NameKindSource summary
zplc_hal_result_tEnumHAL operation result codes
zplc_hal_socket_tTypedefOpaque socket handle
zplc_hal_mutex_tTypedefOpaque mutex handle

Constants and macros

None.

zplc_isa.h

ZPLC Virtual Machine Instruction Set Architecture Definitions

This header defines the binary format and instruction set for the ZPLC VM. It is the contract between the compiler (IDE) and runtime (VM). See docs/ISA.md for the complete specification.

Source: firmware/lib/zplc_core/include/zplc_isa.h

Functions

zplc_opcode_operand_size

static inline uint8_t zplc_opcode_operand_size(uint8_t opcode);

Source summary: Get the operand size for an opcode.

Parameters

NameTypeSource description
opcodeuint8_tThe opcode byte.

Source return value: Operand size in bytes (0, 1, 2, or 4).

zplc_opcode_instruction_size

static inline uint8_t zplc_opcode_instruction_size(uint8_t opcode);

Source summary: Get the total instruction size for an opcode.

Parameters

NameTypeSource description
opcodeuint8_tThe opcode byte.

Source return value: Total instruction size in bytes (1, 2, 3, or 5).

zplc_opcode_is_valid

static inline int zplc_opcode_is_valid(uint8_t opcode);

Source summary: Check if an opcode is valid.

Parameters

NameTypeSource description
opcodeuint8_tThe opcode byte.

Source return value: 1 if valid, 0 if invalid.

Types

NameKindSource summary
zplc_data_type_tEnumIEC 61131-3 data type identifiers.
zplc_opcode_tEnumVM instruction opcodes.
magicStruct.zplc file header (32 bytes).
zplc_file_flags_tEnumFile header flags.
typeStructSegment table entry (8 bytes).
zplc_segment_type_tEnumSegment types.
idStructTask definition (16 bytes).
zplc_task_type_tEnumTask types.
var_addrStructI/O map entry (8 bytes).
zplc_io_direction_tEnumI/O direction.
var_addrStructVariable tag entry (8 bytes). Used for mapping variables to communication protocols.
zplc_tag_id_tEnumTag identifiers.
zplc_vm_error_tEnumVM error codes.
zplc_vm_flags_tEnumVM status flags.
pcStructVM execution state.

Constants and macros

NameValueSource summary
ZPLC_MAGIC0x434C505AUMagic number for .zplc files.
ZPLC_VERSION_MAJOR1Current ISA major version
ZPLC_VERSION_MINOR0Current ISA minor version
ZPLC_MEM_IPI_BASE0x0000UBase address of Input Process Image
ZPLC_MEM_IPI_SIZE0x1000USize of Input Process Image (4 KB, fixed by spec)
ZPLC_MEM_OPI_BASE0x1000UBase address of Output Process Image
ZPLC_MEM_OPI_SIZE0x1000USize of Output Process Image (4 KB, fixed by spec)
ZPLC_MEM_WORK_BASE0x2000UBase address of Work Memory
ZPLC_MEM_WORK_SIZECONFIG_ZPLC_WORK_MEMORY_SIZE
ZPLC_MEM_WORK_SIZE0x2000U
ZPLC_MEM_RETAIN_BASE0x4000UBase address of Retentive Memory
ZPLC_MEM_RETAIN_SIZECONFIG_ZPLC_RETAIN_MEMORY_SIZE
ZPLC_MEM_RETAIN_SIZE0x1000U
ZPLC_MEM_CODE_BASE0x5000UBase address of Code Segment
ZPLC_MEM_CODE_SIZECONFIG_ZPLC_CODE_SIZE_MAX
ZPLC_MEM_CODE_SIZE0xB000U
ZPLC_MAX_TAGS64
ZPLC_STACK_MAX_DEPTHCONFIG_ZPLC_STACK_DEPTH
ZPLC_STACK_MAX_DEPTH256
ZPLC_CALL_STACK_MAXCONFIG_ZPLC_CALL_STACK_DEPTH
ZPLC_CALL_STACK_MAX32
ZPLC_MAX_BREAKPOINTSCONFIG_ZPLC_MAX_BREAKPOINTS
ZPLC_MAX_BREAKPOINTS16
ZPLC_SYS_REG_OFFSET0x0FF0UOffset within IPI for system registers (last 16 bytes)
ZPLC_SYS_FLAG_FIRST_SCAN0x01System flags: First scan bit (set on first cycle after start)
ZPLC_SYS_FLAG_WDG_WARN0x02System flags: Watchdog warning (cycle time exceeded 80% of interval)
ZPLC_SYS_FLAG_RUNNING0x04System flags: Scheduler is running
ZPLC_STRING_LEN_OFFSET0STRING memory layout.
ZPLC_STRING_CAP_OFFSET2
ZPLC_STRING_DATA_OFFSET4
ZPLC_STRING_DEFAULT_SIZE80
ZPLC_STRING_MAX_SIZE255
ZPLC_FILE_HEADER_SIZE32Expected size of file header
ZPLC_SEGMENT_ENTRY_SIZE8Expected size of segment entry
ZPLC_TASK_DEF_SIZE16Expected size of task definition
ZPLC_IOMAP_ENTRY_SIZE8Expected size of I/O map entry
ZPLC_TAG_ENTRY_SIZE8Expected size of tag entry

zplc_loader.h

ZPLC Binary File Loader

Handles loading of .zplc files, parsing headers/segments, and registering tasks with the scheduler.

Source: firmware/lib/zplc_core/include/zplc_loader.h

Functions

zplc_loader_load

int zplc_loader_load(const uint8_t *data, size_t len);

Source summary: Load a ZPLC binary file from memory buffer.

This function parses the header, loads the code segment into VM memory, and registers any defined tasks with the scheduler.

Parameters

NameTypeSource description
dataconst uint8_t *Pointer to the file data
lensize_tLength of the data in bytes

Source return value: 0 on success, negative error code on failure

Types

None.

Constants and macros

NameValueSource summary
ZPLC_FILE_MAGIC0x5A504C43
ZPLC_SEGMENT_TYPE_CODE1
ZPLC_SEGMENT_TYPE_TASK2
ZPLC_LOADER_OK0
ZPLC_LOADER_ERR_MAGIC-1
ZPLC_LOADER_ERR_VERSION-2
ZPLC_LOADER_ERR_SIZE-3
ZPLC_LOADER_ERR_NO_CODE-4
ZPLC_LOADER_ERR_MEMORY-5

zplc_scheduler.h

ZPLC Multitask Scheduler API

This header defines the API for the ZPLC multitask scheduler. The scheduler supports multiple PLC tasks with different intervals and priorities, following IEC 61131-3 task model. Architecture (Zephyr implementation): - Each task has a k_timer that fires at the configured interval - Timer callbacks submit work items to priority-based work queues - Work queue threads execute the actual PLC program cycles - Shared memory (IPI/OPI) is protected by a mutex

Source: firmware/lib/zplc_core/include/zplc_scheduler.h

Functions

zplc_sched_init

int zplc_sched_init(void);

Source summary: Initialize the scheduler.

Must be called before any other scheduler functions. Creates work queues and initializes synchronization primitives.

Parameters

NameTypeSource description
None.

Source return value: 0 on success, negative error code on failure

zplc_sched_shutdown

int zplc_sched_shutdown(void);

Source summary: Shutdown the scheduler.

Stops all tasks, releases resources.

Parameters

NameTypeSource description
None.

Source return value: 0 on success, negative error code on failure

zplc_sched_register_task

int zplc_sched_register_task(const zplc_task_def_t *def, const uint8_t *code, size_t code_size);

Source summary: Register a task with the scheduler.

Parameters

NameTypeSource description
defconst zplc_task_def_t *Task definition (from .zplc file or manual config)
codeconst uint8_t *Pointer to bytecode for this task
code_sizesize_tSize of bytecode

Source return value: Task handle (0-based index) on success, negative error code on failure

zplc_sched_load

int zplc_sched_load(const uint8_t *binary, size_t size);

Source summary: Load a multi-task .zplc binary and register all tasks.

This is the preferred way to load multi-task PLC programs. It parses the .zplc file, loads the shared code segment, and registers each task defined in the TASK segment. The function internally uses zplc_core_load_tasks() to parse the binary and then configures VMs with appropriate entry points.

Parameters

NameTypeSource description
binaryconst uint8_t *Pointer to .zplc file contents
sizesize_tSize of binary data

Source return value: Number of tasks loaded on success, negative error code on failure: -1: Scheduler not initialized -2: Invalid arguments -3: zplc_core_load_tasks() error (bad file format) -4: Task registration failed

zplc_sched_unregister_task

int zplc_sched_unregister_task(int task_id);

Source summary: Unregister a task.

Parameters

NameTypeSource description
task_idintTask handle returned by register_task

Source return value: 0 on success, negative error code on failure

zplc_sched_start

int zplc_sched_start(void);

Source summary: Start the scheduler.

Begins executing all registered tasks according to their intervals.

Parameters

NameTypeSource description
None.

Source return value: 0 on success, negative error code on failure

zplc_sched_stop

int zplc_sched_stop(void);

Source summary: Stop the scheduler.

Stops all tasks but keeps them registered.

Parameters

NameTypeSource description
None.

Source return value: 0 on success, negative error code on failure

zplc_sched_pause

int zplc_sched_pause(void);

Source summary: Pause the scheduler (for debugging).

Parameters

NameTypeSource description
None.

Source return value: 0 on success, negative error code on failure

zplc_sched_resume

int zplc_sched_resume(void);

Source summary: Resume the scheduler from pause.

Parameters

NameTypeSource description
None.

Source return value: 0 on success, negative error code on failure

zplc_sched_step

int zplc_sched_step(void);

Source summary: Execute exactly one cycle for each paused/ready task.

Used by the debugger when the scheduler is paused. Tasks remain paused after the stepped cycle unless a task enters error state.

Parameters

NameTypeSource description
None.

Source return value: 0 on success, negative error code on failure

zplc_sched_get_state

zplc_sched_state_t zplc_sched_get_state(void);

Source summary: Get scheduler state.

Parameters

NameTypeSource description
None.

Source return value: Current scheduler state

zplc_sched_get_stats

int zplc_sched_get_stats(zplc_sched_stats_t *stats);

Source summary: Get scheduler statistics.

Parameters

NameTypeSource description
statszplc_sched_stats_t *Pointer to stats structure to fill

Source return value: 0 on success, negative error code on failure

zplc_sched_get_task

int zplc_sched_get_task(int task_id, zplc_task_t *task);

Source summary: Get task information.

Parameters

NameTypeSource description
task_idintTask handle
taskzplc_task_t *Pointer to task structure to fill

Source return value: 0 on success, negative error code on failure

zplc_sched_get_task_count

int zplc_sched_get_task_count(void);

Source summary: Get task count.

Parameters

NameTypeSource description
None.

Source return value: Number of registered tasks

zplc_sched_get_vm_ptr

zplc_vm_t* zplc_sched_get_vm_ptr(int task_id);

Source summary: Get pointer to the VM instance for a task.

Parameters

NameTypeSource description
task_idintTask handle

Source return value: Pointer to VM instance, or NULL if task not found

zplc_sched_lock

int zplc_sched_lock(int timeout_ms);

Source summary: Lock shared memory for exclusive access.

Call this before reading/writing IPI/OPI from outside task context. Must be paired with zplc_sched_unlock().

Parameters

NameTypeSource description
timeout_msintMaximum time to wait (-1 = forever, 0 = try)

Source return value: 0 on success, -ETIMEDOUT on timeout, other negative on error

zplc_sched_unlock

int zplc_sched_unlock(void);

Source summary: Unlock shared memory.

Parameters

NameTypeSource description
None.

Source return value: 0 on success, negative error code on failure

Types

NameKindSource summary
zplc_task_state_tEnumTask runtime state.
cycle_countStructTask runtime statistics.
configStructTask runtime instance.
zplc_sched_state_tEnumScheduler runtime state.
total_cyclesStructScheduler statistics.

Constants and macros

NameValueSource summary
ZPLC_MAX_TASKSCONFIG_ZPLC_MAX_TASKS
ZPLC_MAX_TASKS8
ZPLC_MIN_INTERVAL_US100Minimum task interval in microseconds (100us)
ZPLC_MAX_INTERVAL_US3600000000ULMaximum task interval in microseconds (1 hour)