#!/usr/bin/env bash # workspace/run.sh — start softIOC + uopi for EPICS workspace testing # # Usage (from project root): # bash workspace/run.sh # # Requirements: # • EPICS Base installed (EPICS_BASE set, or auto-detected below) # • softIoc binary available # • uopi built with EPICS support (script builds it if missing) set -euo pipefail PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" WORKSPACE="$PROJECT_ROOT/workspace" BINARY="$PROJECT_ROOT/dist/uopi" # ── Locate EPICS Base ───────────────────────────────────────────────────────── if [ -z "${EPICS_BASE:-}" ]; then for candidate in \ /usr/lib/epics \ /usr/local/epics \ /opt/epics/base \ /opt/epics; do if [ -f "$candidate/include/cadef.h" ]; then export EPICS_BASE="$candidate" break fi done fi if [ -z "${EPICS_BASE:-}" ]; then echo "ERROR: EPICS_BASE is not set and could not be auto-detected." echo " export EPICS_BASE=/path/to/epics/base" exit 1 fi # Detect architecture EPICS_ARCH="${EPICS_ARCH:-$(ls "$EPICS_BASE/lib" | grep linux | head -1)}" if [ -z "$EPICS_ARCH" ]; then EPICS_ARCH="linux-x86_64" fi # ── Environment ─────────────────────────────────────────────────────────────── # Point CA exclusively at the local IOC — no broadcast scanning. export EPICS_CA_ADDR_LIST="127.0.0.1" export EPICS_CA_AUTO_ADDR_LIST="NO" # Ensure the EPICS shared libraries are found at runtime. export LD_LIBRARY_PATH="$EPICS_BASE/lib/$EPICS_ARCH${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}" # Make EPICS tools (softIoc, caget, caput…) available. export PATH="$EPICS_BASE/bin/$EPICS_ARCH:$PATH" # ── Locate softIoc ──────────────────────────────────────────────────────────── if ! command -v softIoc &>/dev/null; then echo "ERROR: softIoc not found in $EPICS_BASE/bin/$EPICS_ARCH or PATH." exit 1 fi # ── Build uopi ──────────────────────────────────────────────────────────────── echo "Building uopi with EPICS support..." cd "$PROJECT_ROOT" make backend-epics 2>&1 echo "" # ── Cleanup handler ─────────────────────────────────────────────────────────── PIDS=() cleanup() { echo "" echo "Shutting down..." for pid in "${PIDS[@]:-}"; do kill "$pid" 2>/dev/null || true done wait 2>/dev/null || true } trap cleanup EXIT INT TERM # ── Kill any stale softIOC from a previous run ──────────────────────────────── pkill -x softIoc 2>/dev/null || true # Give the OS a moment to release the CA port (5064/tcp+udp). sleep 0.3 # ── Start softIOC ───────────────────────────────────────────────────────────── echo "Starting softIOC..." softIoc -S -d "$WORKSPACE/softioc/uopi_test.db" \ >"$WORKSPACE/softioc.log" 2>&1 & IOC_PID=$! PIDS+=("$IOC_PID") # Wait for the IOC to accept Channel Access connections (up to 10 s). echo -n "Waiting for IOC to be ready" for i in $(seq 1 20); do if caget -w 1 UOPI:TICK >/dev/null 2>&1; then echo " OK" break fi echo -n "." sleep 0.5 if [ "$i" -eq 20 ]; then echo "" echo "ERROR: IOC did not become ready within 10 seconds." echo "Check $WORKSPACE/softioc.log for details." exit 1 fi done # ── Start uopi ──────────────────────────────────────────────────────────────── echo "Starting uopi (http://localhost:8080)..." echo " Open the browser, switch to Edit mode, load workspace/data/epics_test.xml" echo " or select it from the interface list in View mode." echo " Press Ctrl-C to stop." echo "" cd "$PROJECT_ROOT" "$BINARY" -config "$WORKSPACE/uopi.toml"