autocore-std 3.3.11

Standard library for AutoCore control programs - shared memory, IPC, and logging utilities
Documentation

autocore-std

Standard library for AutoCore control programs. Provides shared memory communication, IPC, logging, and IEC 61131-3 inspired function blocks.

Overview

autocore-std is the runtime library for control programs running alongside an AutoCore server. It handles:

  • Shared Memory Communication - Zero-copy data exchange with the server
  • Synchronization - Tick-based cyclic execution with proper memory barriers
  • UDP Logging - Non-blocking log delivery to the server console
  • Function Blocks - IEC 61131-3 inspired timers and edge triggers

Installation

Add to your Cargo.toml:

[dependencies]
autocore-std = "3.3"
log = "0.4"
anyhow = "1"

Quick Start

use autocore_std::{ControlProgram, ControlRunner, RunnerConfig};

// Import the generated global memory module
mod gm;
use gm::GlobalMemory;

struct MyProgram {
    // Your program state here
}

impl MyProgram {
    pub fn new() -> Self {
        Self {}
    }
}

impl ControlProgram for MyProgram {
    type Memory = GlobalMemory;

    fn initialize(&mut self, mem: &mut Self::Memory) {
        // Called once at startup
        log::info!("Control program initialized");
    }

    fn process_tick(&mut self, mem: &mut Self::Memory, cycle: u64) {
        // Called every scan cycle
        // Read inputs from mem, compute, write outputs to mem
    }
}

fn main() -> anyhow::Result<()> {
    let config = RunnerConfig::default();

    ControlRunner::new(MyProgram::new())
        .config(config)
        .run()
}

Or use the convenience macro:

autocore_std::autocore_main!(MyProgram, "autocore_shm", "tick");

Function Blocks

RTrig - Rising Edge Trigger

Detects false-to-true transitions.

use autocore_std::RTrig;

let mut trigger = RTrig::new();

trigger.call(false); // returns false
trigger.call(true);  // returns true (rising edge!)
trigger.call(true);  // returns false (no edge)
trigger.call(false); // returns false
trigger.call(true);  // returns true (rising edge!)

FTrig - Falling Edge Trigger

Detects true-to-false transitions.

use autocore_std::FTrig;

let mut trigger = FTrig::new();

trigger.call(true);  // returns false
trigger.call(false); // returns true (falling edge!)
trigger.call(false); // returns false (no edge)

TON - Timer On Delay

Output becomes true after input has been true for the preset duration.

use autocore_std::Ton;
use std::time::Duration;

let mut timer = Ton::new();

// In your process_tick:
let done = timer.call(start_condition, Duration::from_secs(5));

// Access elapsed time
println!("Elapsed: {:?}", timer.et);

Logging

Logs are sent via UDP to the AutoCore server for display in the console.

log::trace!("Detailed debug info");
log::debug!("Debug message");
log::info!("Informational message");
log::warn!("Warning message");
log::error!("Error message");

View logs with:

acctl logs --follow

Configuration

use autocore_std::{RunnerConfig, logger};
use log::LevelFilter;

let config = RunnerConfig {
    ipc_address: "127.0.0.1:9100".to_string(),
    module_name: "control".to_string(),
    shm_name: "autocore_cyclic".to_string(),
    tick_signal_name: "tick".to_string(),
    busy_signal_name: None,
    log_level: LevelFilter::Debug,
    log_udp_port: logger::DEFAULT_LOG_UDP_PORT,
};

Architecture

┌─────────────────────────────────────────────────────────────┐
│                    AutoCore Server                          │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────────────┐  │
│  │ Shared Mem  │  │ IPC Server  │  │ UDP Log Listener    │  │
│  │ (cyclic)    │  │ (setup)     │  │ (port 39101)        │  │
│  └──────┬──────┘  └──────┬──────┘  └──────────┬──────────┘  │
└─────────┼────────────────┼────────────────────┼─────────────┘
          │                │                    │
          │ memory map     │ layout query       │ UDP logs
          │                │                    │
┌─────────┼────────────────┼────────────────────┼─────────────┐
│         ▼                ▼                    ▲             │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────────────┐  │
│  │ Local Copy  │  │ IPC Client  │  │ UDP Logger          │  │
│  │ of Memory   │  │ (init only) │  │ (background thread) │  │
│  └──────┬──────┘  └─────────────┘  └─────────────────────┘  │
│         │                                     ▲             │
│         ▼                                     │             │
│  ┌────────────────────────────────────────────┴──────────┐  │
│  │              ControlRunner + Your Program             │  │
│  │  1. Wait for tick signal                              │  │
│  │  2. Read shared memory → local copy (acquire)         │  │
│  │  3. Execute process_tick()                            │  │
│  │  4. Write local copy → shared memory (release)        │  │
│  │  5. Signal completion (optional)                      │  │
│  └───────────────────────────────────────────────────────┘  │
│                     Control Program                         │
└─────────────────────────────────────────────────────────────┘

Memory Synchronization

The ControlRunner handles proper memory synchronization:

  1. Input Phase: Reads shared memory into a local buffer with an acquire fence
  2. Execute Phase: Your process_tick() runs on the local copy
  3. Output Phase: Writes local buffer back to shared memory with a release fence

This ensures:

  • Consistent snapshot of inputs at cycle start
  • Atomic commit of outputs at cycle end
  • Proper visibility across process boundaries

License

Proprietary - Licensed AutoCore Users Only

This software is licensed exclusively for use with validly licensed AutoCore Server installations. This library is used to control industrial equipment - improper use may result in equipment damage, personal injury, or death.

See the LICENSE file for complete terms.

For licensing inquiries: support@automateddesign.com