Config IO

Component Type: Input

Status: Implemented

Overview

CIOConfig is a special-purpose IO used to read one configuration item on one or more bound objects. When the descriptor marks the ConfigIO as writable, dawnpy also marks the selected target configuration item as read-write.

It acts as a proxy between normal IO access and getObjConfig() / setObjConfig() on the target objects.

Implementation

Implemented behavior:

  • CIOConfig is always readable and writable.

  • Notifications are not supported.

  • Batch mode is not supported.

  • getDataSize() and getDataDim() are derived from target objectCfg metadata (DTYPE + size in words).

  • Config payload is interpreted as target objectCfg DTYPE, not hardcoded uint32_t.

  • Current limitation: int64/uint64/double config payloads are not supported in ConfigIO conversion and limit validation paths.

Binding behavior:

  • config.objid_ref selects the target configuration ID.

  • objid_ref_alloc is used internally in the generated descriptor to allocate the object IDs that this Config IO will bind to.

  • At runtime, bound objects are attached through bind().

Read and write behavior:

  • getData() reads the selected config value from the first bound object.

  • setData() writes the same selected config value to all bound objects.

  • Default behavior is immediate apply: a successful ConfigIO write commits runtime configuration in the same operation.

  • When CONFIG_DAWN_IO_LIMITS is enabled and ConfigIO has common IO limits configured (IO_CFG_LIMIT_MIN/MAX/STEP), it validates incoming writes before forwarding data to bound object configs.

  • This allows one ConfigIO per config item to define item-specific runtime limits while keeping target objects unchanged.

  • For multi-dimensional config payloads, limits use per-element word arrays (same word size as the target config payload). Validation is applied element-by-element when limit array size matches payload size.

  • Access permissions are enforced by the target config item. A read-only target can be read, but write will fail.

  • dawnpy sets the target config item’s RW bit only when a writable ConfigIO exposes that exact field. Other config fields remain read-only by default.

  • If no object is bound, access fails.

Configuration

Kconfig

  • CONFIG_DAWN_IO_CONFIG: enables the Config IO.

YAML

ios:
  - id: cfgio1
    type: config
    dtype: uint32
    rw: true
    config:
      objid_ref: dummy1

Supported fields:

  • config.objid_ref: target object reference

  • config.objcfg_ref: target config field in referenced object

  • rw: when true on a ConfigIO object, grants runtime write access to the referenced target config field. On non-ConfigIO objects, rw does not grant configuration write access.

  • config.offset: (optional) uint32 word offset within the config field. When set, getData/setData operate on a sub-range starting at this word offset. Defaults to 0 (full field).

  • config.size: (optional) number of uint32 words exposed. When set together with offset, only size words are read/written. Defaults to 0 (use the full config field size).

When both offset and size are omitted or zero, the Config IO operates on the entire target config field (backward-compatible behavior).

When offset and size are specified, read operations return only the requested sub-range. Write operations perform a read-modify-write: the full config field is read from the target, the sub-range is patched with the incoming data, and the patched field is written back. This preserves other fields within the same config item.

Example: expose individual dwell times from a sequencer states table:

ios:
  - id: cfg_dwell_off
    type: config
    dtype: uint32
    rw: false
    config:
      objid_ref: blinky_seq1
      objcfg_ref: states
      offset: 1   # skip state[0].value
      size: 1     # expose only state[0].dwell_us

  - id: cfg_dwell_on
    type: config
    dtype: uint32
    rw: false
    config:
      objid_ref: blinky_seq1
      objcfg_ref: states
      offset: 3   # skip state[0](value+dwell) + state[1].value
      size: 1     # expose only state[1].dwell_us

dawnpy resolves the target config ID and handles allocation/binding details.

External Control

ControlIO: not supported.

TriggerIO: not supported.

Brainstorming & Future Ideas

  • support for read-only-once and write-only-once ? does it make sense ?

  • to read limits from device we have to read descriptor and decode it

  • A staged write-back model may be useful when many config values must be changed together.

  • A future extension can add an optional descriptor-level apply_trigger mode (stage on write, commit on trigger). Default behavior should remain immediate apply when no trigger mode is configured.

  • A future design may need an explicit “write to memory” or “commit” step.

  • It is still open how to handle many config objects at once without forcing one shared read-back value.

Diagrams

component CDescriptor {
   component obj1Descriptor
}

component AnyIO {
   component CObject {
        component CDescObject
   }
}

component ConfigIO {
  component Limits
}

ConfigIO -> CDescObject : setConfig
ConfigIO <- CDescObject : getConfig

CDescObject <-> obj1Descriptor : BoundTo

Doxygen