Skip to main content

Operation Model

This module defines the generic template class Operation<T> to describe asynchronous operations with completion feedback mechanisms. It supports three modes: Callback, Blocking, and Polling, and is designed to unify completion handling in embedded I/O operations.

ReadOperation / WriteOperation are aliases of Operation<ErrorCode> and are commonly used by I/O ports to report completion status via ErrorCode.

Operation Modes

OperationType

enum class OperationType : uint8_t {
CALLBACK, // Uses a callback function to handle completion
BLOCK, // Waits using a semaphore (blocking)
POLLING, // Uses a polling status variable
NONE // No completion handling
};

POLLING Status Enum

enum class OperationPollingStatus : uint8_t {
READY,
RUNNING,
DONE,
ERROR
};

Constructors

// Default constructor: type is NONE
Operation();

// Construct a blocking operation
Operation(Semaphore &sem, uint32_t timeout = UINT32_MAX);

// Construct a callback-based operation (T is the callback parameter type)
Operation(Callback<T> &cb);

// Construct a polling-based operation
Operation(OperationPollingStatus &status);

Operation can also be initialized from another Operation instance (copy/move semantics are equivalent to assignment).

Status Updates

template <typename Status>
void UpdateStatus(bool in_isr, Status&& status);

void MarkAsRunning();
  • UpdateStatus(...) triggers a callback, unblocks a waiter, or updates polling state depending on the operation type:
    • CALLBACK: calls cb.Run(in_isr, status), passing status as the completion value of type T.
    • BLOCK: calls Semaphore::PostFromCallback(in_isr) to unblock; the completion value is not part of the wake-up semantics.
    • POLLING: updates the OperationPollingStatus variable to DONE on success, otherwise ERROR. This rule is uniform for any T: by convention, a value of 0 means success (for example ErrorCode::OK == 0).
  • MarkAsRunning() sets the polling status to RUNNING if the type is POLLING.
  • If in_isr == true and the operation type is BLOCK, an assertion failure is triggered.
  • These functions are typically called by drivers/ports; users only need to select an OperationType and pass an Operation instance in.

Usage Examples

Blocking write with timeout

Semaphore sem;
WriteOperation op_block(sem, 100);
write_port(data, op_block);

Callback-based completion feedback

auto cb = Callback<ErrorCode>::Create([](bool in_isr, int context, ErrorCode ec) {
// Callback logic
}, 123); // Binds context value 123

ReadOperation op_cb(cb);
read_port(buffer, op_cb);

Polling to check for completion

auto status = LibXR::ReadOperation::OperationPollingStatus::READY;
ReadOperation op_poll(status);
read_port(buffer, op_poll);

// Later check if completed
if (status == LibXR::ReadOperation::OperationPollingStatus::DONE) {
// Completed successfully
} else if (status == LibXR::ReadOperation::OperationPollingStatus::ERROR) {
// Completed with an error
}

Operation is the foundation of LibXR's I/O operation mechanism, suitable for serial, network, timer, and other modules. It provides a unified way to manage completion behavior, ensuring safe use in both thread and interrupt contexts.