tin  1.5.9
tio

Purpose

tio is the portable I/O facade layer. It gives applications and adapters a small vocabulary for driver-shaped boundaries without coupling behavior definitions to peripheral registers, DMA descriptors, RTOS handles, or vendor HAL APIs.

Use tio for:

  • GPIO input and output concepts;
  • ADC sample contracts;
  • UART, SPI, I2C, CAN, and PWM facades;
  • async driver-shaped concepts;
  • small payload types that can become typed runtime events.

API Entry Points

  • tin/io.h for tin::io.
  • tio.h for the tio shorthand namespace alias.
  • tin::io::gpio_input, tin::io::gpio_output, tin::io::adc, tin::io::uart, tin::io::spi, tin::io::i2c, tin::io::can, and tin::io::pwm for driver facade constraints.
  • tin::io::digital_input_state, tin::io::adc_sample, tin::io::pwm_duty, tin::io::can_id, and tin::io::can_frame for small payload records.

Example: GPIO Facade

#include "tin/io.h"
struct EstopPin {
tin::io::level read() const;
};
static_assert(tin::io::gpio_input<EstopPin>);
struct EstopPressed {};
struct EstopReleased {};
template<typename Runtime>
void poll_estop(EstopPin const& pin, Runtime& runtime) {
if (pin.read() == tin::io::level::high) {
(void)runtime.send_event(EstopPressed{});
} else {
(void)runtime.send_event(EstopReleased{});
}
}
level
Definition: io.h:26
detail::runtime_impl< Definition, Policy, MachinePolicy > Runtime
Definition: runtime.h:531
Tin I/O facade compatibility header.

The pin type can be backed by a board HAL, Linux test double, simulator, or recorded replay source. The state machine only sees typed product events.

Example: ADC Facade To Bounded Channel

#include "tin/runtime.h"
#include "tin/io.h"
struct BatteryAdc {
tin::io::adc_sample read();
};
static_assert(tin::io::adc<BatteryAdc>);
void sample_battery(BatteryAdc& adc) {
(void)battery_samples.try_send(adc.read());
}
Definition: sync.h:507
bool try_send(T const &value)
Definition: sync.h:517
concept adc
Definition: io.h:106
Tin runtime-kernel facade.

The tio contract describes the device-facing shape. The tin channel owns the bounded handoff. A tsm machine can consume a translated event later.

Working With thal

tio and thal describe different sides of the same adapter boundary.

tio names the portable I/O shape that application code wants to depend on: GPIO reads, ADC samples, CAN frames, UART transfers, PWM duties, and similar driver-facing contracts. These interfaces should stay small enough to back with real hardware, simulators, replay files, and tests.

thal binds those shapes to a target. A thal adapter decides how the GPIO read happens on a specific board, which interrupt or thread wakes the runtime, how ticks are counted, and which compiler or OS constraints apply.

#include "tin/io.h"
#include "tin/runtime.h"
struct BoardEstopPin {
tin::io::level read() const;
};
static_assert(tin::io::gpio_input<BoardEstopPin>);
struct EstopPressed {};
template<typename Runtime>
void board_estop_interrupt(BoardEstopPin const& pin, Runtime& runtime) {
if (pin.read() == tin::io::level::high) {
(void)runtime.send_event(EstopPressed{});
}
}

In this shape, BoardEstopPin satisfies the tio GPIO contract. The interrupt hook, wake policy, and target profile belong to thal.