cmvr-es/script/ethercat/start_ethercat.sh

137 lines
3.6 KiB
Bash
Executable File

#!/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}" <<EOF
MASTER0_DEVICE="${MAC}"
DEVICE_MODULES="${DEVICE_MODULES}"
UPDOWN_INTERFACES="${IFACE}"
EOF
if command -v nmcli >/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