std-rs
Pure Rust port of the EPICS std synApps module — standard records and device support widely used in beamline IOCs at synchrotron and accelerator facilities.
No C dependencies. Just cargo build.
Repository: https://github.com/epics-rs/epics-rs
Overview
The std module is a foundational synApps package providing PID feedback control, rate-limited outputs, formatted timestamps, sequence programs, and dozens of beamline utility databases. It's used as a base layer by virtually every synApps IOC.
std-rs ports the C synApps std module to native Rust, including the three core records (epid, throttle, timestamp), four device support implementations, native Rust async replacements for two SNL state machines (delayDo, femto), and 85 database templates ready to load with dbLoadRecords.
Features
Records
| Record | Description | Value |
|---|---|---|
| epid | Extended PID feedback controller (PID + MaxMin modes) | Double |
| throttle | Rate-limited output with drive limits and sync input | Double |
| timestamp | Wall-clock timestamp with format selection | String |
epid Record
Extended PID controller with two modes:
- PID mode — full Kp/Ki/Kd PID with anti-windup, output deadband, bumpless turn-on, hysteresis-based alarms
- MaxMin mode — supervisory tracking that drives the output toward observed setpoint extremes
- Pre-process actions read INP (controlled value) and STPL (setpoint) links before each cycle
device_did_computeflag lets device support replace the built-in PID with hardware-accelerated computation- Output deadband (ODEL) prevents output oscillation
- Closed-loop / open-loop / supervisory modes via FBON
throttle Record
Rate-limiting output forwarder:
- Reads input link (INP) and writes to output link (OUT)
- Rate limit RMAX (units/sec)
- Minimum delay RMIN between writes
- SYNC input for forced re-sync to current INP value
- Async delayed reprocess via
ReprocessAfteraction
timestamp Record
Wall-clock timestamp string with 11 format options:
- ISO 8601, EPICS standard, custom strftime patterns
- Output to OUT link or read directly via VAL
- Periodic update via device support (Time of Day driver)
Device Support
| Driver | Used For | Description |
|---|---|---|
| Epid Soft | epid | Synchronous PID computation each scan cycle |
| Epid Async Soft | epid | Trigger-driven async PID with callback completion |
| Fast Epid | epid | Interrupt-driven 1 kHz+ PID loop with high-rate readback |
| Time of Day | timestamp | Periodic wall-clock update via interval timer |
| Sec Past Epoch | longin | Unix epoch seconds counter |
SNL Programs (Native Rust async)
The synApps std module ships with two SNL (State Notation Language) state machines that std-rs reimplements as native Rust async tasks:
- femto — Femto FEMTO amplifier gain control state machine. Manages cascaded transimpedance amplifier gain selection with auto-ranging based on signal level.
- delayDo — Generic delayed action state machine. Triggers a write after a configurable delay, with abort/restart support.
Both run as tokio::spawn'd tasks with select! for event/timeout multiplexing — no SNL compiler needed.
Database Templates (85+ bundled in db/)
- PID — sync_pid_control, async_pid_control, fast_pid_control with autosave .req files
- Femto — DLPCA-200, DHPCA-100, DDPCA-300 amplifier presets
- Generic state — countDownTimer, alarmClock, autoShutter, genTweak, genericState (numeric/string/aux variants)
- Sequence — 4step, auto_4step (4-position state machines)
- all_com — common asyn record templates for serial port count 0/4/8/...88
- delayDo — generic delayed action sequencer
Autosave Request Files
Each database template ships with a paired .req file for automatic save/restore via epics-base-rs autosave.
Architecture
std-rs/
├── src/
│ ├── lib.rs # public API + std_record_factories()
│ ├── records/
│ │ ├── epid.rs # EpidRecord (PID + MaxMin)
│ │ ├── throttle.rs # ThrottleRecord (rate-limited output)
│ │ └── timestamp.rs # TimestampRecord (formatted wall clock)
│ ├── device_support/
│ │ ├── epid_soft.rs # synchronous PID device support
│ │ ├── epid_soft_callback.rs # async trigger-based variant
│ │ ├── epid_fast.rs # 1 kHz+ interrupt-driven PID
│ │ └── time_of_day.rs # periodic timestamp update
│ └── snl/
│ ├── delay_do.rs # delayDo state machine
│ └── femto.rs # Femto amplifier control
├── db/ # 85 database templates + .req files
└── ui/ # PyDM screens
Usage
[]
= { = "0.8", = ["std"] }
Register All Record Types
use IocApplication;
use run_ca_ioc;
use std_record_factories;
async
Load a PID Loop
# Set up a PID feedback loop
# Watch the controlled variable converge
Testing
Test coverage: PID computation correctness, anti-windup, output deadband, MaxMin tracking, throttle rate limiting, sync input behavior, timestamp format generation, delayDo state transitions, femto auto-ranging.
Dependencies
- epics-base-rs — Record trait, DeviceSupport, ProcessAction
- asyn-rs — port driver (used by Femto cascaded amplifier)
- chrono — timestamp formatting
- epics-macros-rs —
#[derive(EpicsRecord)]
Requirements
- Rust 1.85+ (edition 2024)
License
See Also
- EPICS std module — original C synApps source
- synApps documentation — beamline IOC reference