#!/usr/bin/env bash set -euo pipefail usage() { cat <<'USAGE' Usage: sudo script/ethercat/start_ethercat.sh [iface] [ethercat_dev] [start_wait_sec] Any pure numeric argument is treated as start_wait_sec. Example: sudo script/ethercat/start_ethercat.sh eno1 sudo script/ethercat/start_ethercat.sh 10 sudo script/ethercat/start_ethercat.sh eno1 10 sudo script/ethercat/start_ethercat.sh eno1 /dev/EtherCAT1 sudo script/ethercat/start_ethercat.sh eno1 /dev/EtherCAT0 10 sudo script/ethercat/start_ethercat.sh eno1 10 /dev/EtherCAT0 Environment: DEVICE_MODULES=generic IgH device module list. IGH_ROOT=... Override bundled IgH install path. ETHERCAT_CONF=... Override ethercatctl config path. ETHERCAT_DEV=/dev/EtherCAT0 Override EtherCAT character device node. ETHERCAT_GROUP=plugdev Group allowed to access the character device. START_WAIT_SEC=5 Seconds to wait for link/slave discovery. USAGE } if [[ "${1:-}" == "-h" || "${1:-}" == "--help" ]]; then usage exit 0 fi if [[ "$(id -u)" -ne 0 ]]; then echo "error: please run with sudo." >&2 exit 1 fi IFACE="${IFACE:-eno1}" ETHERCAT_DEV="${ETHERCAT_DEV:-/dev/EtherCAT0}" ETHERCAT_GROUP="${ETHERCAT_GROUP:-plugdev}" START_WAIT_SEC="${START_WAIT_SEC:-5}" NON_NUMERIC_ARG_COUNT=0 for arg in "$@"; do if [[ "${arg}" =~ ^[0-9]+$ ]]; then START_WAIT_SEC="${arg}" continue fi case "${NON_NUMERIC_ARG_COUNT}" in 0) IFACE="${arg}" ;; 1) ETHERCAT_DEV="${arg}" ;; *) echo "error: unexpected argument: ${arg}" >&2 usage >&2 exit 1 ;; esac NON_NUMERIC_ARG_COUNT=$((NON_NUMERIC_ARG_COUNT + 1)) done SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" REPO_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)" IGH_ROOT="${IGH_ROOT:-${REPO_ROOT}/dependency/x86/third_party/ethercat/v1.7.0}" DEVICE_MODULES="${DEVICE_MODULES:-generic}" ETHERCAT_CONF="${ETHERCAT_CONF:-${IGH_ROOT}/etc/ethercat.conf}" ETHERCATCTL="${IGH_ROOT}/sbin/ethercatctl" ETHERCAT="${IGH_ROOT}/bin/ethercat" if [[ ! -d "/sys/class/net/${IFACE}" ]]; then echo "error: network interface '${IFACE}' does not exist." >&2 exit 1 fi if [[ ! -x "${ETHERCATCTL}" ]]; then echo "error: ethercatctl not found: ${ETHERCATCTL}" >&2 exit 1 fi if [[ ! -x "${ETHERCAT}" ]]; then echo "error: ethercat command not found: ${ETHERCAT}" >&2 exit 1 fi MAC="$(cat "/sys/class/net/${IFACE}/address")" echo "EtherCAT interface: ${IFACE}" echo "EtherCAT MAC: ${MAC}" echo "EtherCAT device: ${ETHERCAT_DEV}" echo "IgH root: ${IGH_ROOT}" echo "IgH config: ${ETHERCAT_CONF}" echo "Device modules: ${DEVICE_MODULES}" echo "Start wait: ${START_WAIT_SEC}s" mkdir -p "$(dirname "${ETHERCAT_CONF}")" if [[ -f "${ETHERCAT_CONF}" ]]; then echo "Stopping existing EtherCAT master with current config..." "${ETHERCATCTL}" -c "${ETHERCAT_CONF}" stop >/dev/null 2>&1 || true sleep 1 fi cat >"${ETHERCAT_CONF}" </dev/null 2>&1; then nmcli device disconnect "${IFACE}" >/dev/null 2>&1 || true fi ip addr flush dev "${IFACE}" ip link set "${IFACE}" up "${ETHERCATCTL}" -c "${ETHERCAT_CONF}" start if [[ -e "${ETHERCAT_DEV}" ]]; then chgrp "${ETHERCAT_GROUP}" "${ETHERCAT_DEV}" chmod 660 "${ETHERCAT_DEV}" else echo "warning: ${ETHERCAT_DEV} not found; skip chmod. Check with: ls -l /dev/EtherCAT*" >&2 fi for ((i = 0; i < START_WAIT_SEC; ++i)); do if "${ETHERCAT}" slaves 2>/dev/null | grep -qE '^[0-9]+[[:space:]]'; then break fi sleep 1 done "${ETHERCAT}" master "${ETHERCAT}" slaves || true