| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249 |
- #!/bin/bash
- # SPDX-License-Identifier: GPL-2.0
- # Copyright 2021-2022 NXP
- REQUIRE_ISOCHRON=${REQUIRE_ISOCHRON:=yes}
- REQUIRE_LINUXPTP=${REQUIRE_LINUXPTP:=yes}
- # Tunables
- UTC_TAI_OFFSET=37
- ISOCHRON_CPU=1
- if [[ "$REQUIRE_ISOCHRON" = "yes" ]]; then
- # https://github.com/vladimiroltean/tsn-scripts
- # WARNING: isochron versions pre-1.0 are unstable,
- # always use the latest version
- require_command isochron
- fi
- if [[ "$REQUIRE_LINUXPTP" = "yes" ]]; then
- require_command phc2sys
- require_command ptp4l
- fi
- phc2sys_start()
- {
- local uds_address=$1
- local extra_args=""
- if ! [ -z "${uds_address}" ]; then
- extra_args="${extra_args} -z ${uds_address}"
- fi
- phc2sys_log="$(mktemp)"
- chrt -f 10 phc2sys -m \
- -a -rr \
- --step_threshold 0.00002 \
- --first_step_threshold 0.00002 \
- ${extra_args} \
- > "${phc2sys_log}" 2>&1 &
- phc2sys_pid=$!
- echo "phc2sys logs to ${phc2sys_log} and has pid ${phc2sys_pid}"
- sleep 1
- }
- phc2sys_stop()
- {
- { kill ${phc2sys_pid} && wait ${phc2sys_pid}; } 2> /dev/null
- rm "${phc2sys_log}" 2> /dev/null
- }
- # Replace space separators from interface list with underscores
- if_names_to_label()
- {
- local if_name_list="$1"
- echo "${if_name_list/ /_}"
- }
- ptp4l_start()
- {
- local if_names="$1"
- local slave_only=$2
- local uds_address=$3
- local log="ptp4l_log_$(if_names_to_label ${if_names})"
- local pid="ptp4l_pid_$(if_names_to_label ${if_names})"
- local extra_args=""
- for if_name in ${if_names}; do
- extra_args="${extra_args} -i ${if_name}"
- done
- if [ "${slave_only}" = true ]; then
- extra_args="${extra_args} -s"
- fi
- # declare dynamic variables ptp4l_log_${if_name} and ptp4l_pid_${if_name}
- # as global, so that they can be referenced later
- declare -g "${log}=$(mktemp)"
- chrt -f 10 ptp4l -m -2 -P \
- --step_threshold 0.00002 \
- --first_step_threshold 0.00002 \
- --tx_timestamp_timeout 100 \
- --uds_address="${uds_address}" \
- ${extra_args} \
- > "${!log}" 2>&1 &
- declare -g "${pid}=$!"
- echo "ptp4l for interfaces ${if_names} logs to ${!log} and has pid ${!pid}"
- sleep 1
- }
- ptp4l_stop()
- {
- local if_names="$1"
- local log="ptp4l_log_$(if_names_to_label ${if_names})"
- local pid="ptp4l_pid_$(if_names_to_label ${if_names})"
- { kill ${!pid} && wait ${!pid}; } 2> /dev/null
- rm "${!log}" 2> /dev/null
- }
- cpufreq_max()
- {
- local cpu=$1
- local freq="cpu${cpu}_freq"
- local governor="cpu${cpu}_governor"
- # Kernel may be compiled with CONFIG_CPU_FREQ disabled
- if ! [ -d /sys/bus/cpu/devices/cpu${cpu}/cpufreq ]; then
- return
- fi
- # declare dynamic variables cpu${cpu}_freq and cpu${cpu}_governor as
- # global, so they can be referenced later
- declare -g "${freq}=$(cat /sys/bus/cpu/devices/cpu${cpu}/cpufreq/scaling_min_freq)"
- declare -g "${governor}=$(cat /sys/bus/cpu/devices/cpu${cpu}/cpufreq/scaling_governor)"
- cat /sys/bus/cpu/devices/cpu${cpu}/cpufreq/scaling_max_freq > \
- /sys/bus/cpu/devices/cpu${cpu}/cpufreq/scaling_min_freq
- echo -n "performance" > \
- /sys/bus/cpu/devices/cpu${cpu}/cpufreq/scaling_governor
- }
- cpufreq_restore()
- {
- local cpu=$1
- local freq="cpu${cpu}_freq"
- local governor="cpu${cpu}_governor"
- if ! [ -d /sys/bus/cpu/devices/cpu${cpu}/cpufreq ]; then
- return
- fi
- echo "${!freq}" > /sys/bus/cpu/devices/cpu${cpu}/cpufreq/scaling_min_freq
- echo -n "${!governor}" > \
- /sys/bus/cpu/devices/cpu${cpu}/cpufreq/scaling_governor
- }
- isochron_recv_start()
- {
- local if_name=$1
- local uds=$2
- local stats_port=$3
- local extra_args=$4
- local pid="isochron_pid_${stats_port}"
- if ! [ -z "${uds}" ]; then
- extra_args="${extra_args} --unix-domain-socket ${uds}"
- fi
- isochron rcv \
- --interface ${if_name} \
- --sched-priority 98 \
- --sched-fifo \
- --utc-tai-offset ${UTC_TAI_OFFSET} \
- --stats-port ${stats_port} \
- --quiet \
- ${extra_args} & \
- declare -g "${pid}=$!"
- sleep 1
- }
- isochron_recv_stop()
- {
- local stats_port=$1
- local pid="isochron_pid_${stats_port}"
- { kill ${!pid} && wait ${!pid}; } 2> /dev/null
- }
- isochron_do()
- {
- local sender_if_name=$1; shift
- local receiver_if_name=$1; shift
- local sender_uds=$1; shift
- local receiver_uds=$1; shift
- local base_time=$1; shift
- local cycle_time=$1; shift
- local shift_time=$1; shift
- local num_pkts=$1; shift
- local vid=$1; shift
- local priority=$1; shift
- local dst_ip=$1; shift
- local isochron_dat=$1; shift
- local extra_args=""
- local receiver_extra_args=""
- local vrf="$(master_name_get ${sender_if_name})"
- local use_l2="true"
- if ! [ -z "${dst_ip}" ]; then
- use_l2="false"
- fi
- if ! [ -z "${vrf}" ]; then
- dst_ip="${dst_ip}%${vrf}"
- fi
- if ! [ -z "${vid}" ]; then
- vid="--vid=${vid}"
- fi
- if [ -z "${receiver_uds}" ]; then
- extra_args="${extra_args} --omit-remote-sync"
- fi
- if ! [ -z "${shift_time}" ]; then
- extra_args="${extra_args} --shift-time=${shift_time}"
- fi
- if [ "${use_l2}" = "true" ]; then
- extra_args="${extra_args} --l2 --etype=0xdead ${vid}"
- receiver_extra_args="--l2 --etype=0xdead"
- else
- extra_args="${extra_args} --l4 --ip-destination=${dst_ip}"
- receiver_extra_args="--l4"
- fi
- cpufreq_max ${ISOCHRON_CPU}
- isochron_recv_start "${h2}" "${receiver_uds}" 5000 "${receiver_extra_args}"
- isochron send \
- --interface ${sender_if_name} \
- --unix-domain-socket ${sender_uds} \
- --priority ${priority} \
- --base-time ${base_time} \
- --cycle-time ${cycle_time} \
- --num-frames ${num_pkts} \
- --frame-size 64 \
- --txtime \
- --utc-tai-offset ${UTC_TAI_OFFSET} \
- --cpu-mask $((1 << ${ISOCHRON_CPU})) \
- --sched-fifo \
- --sched-priority 98 \
- --client 127.0.0.1 \
- --sync-threshold 5000 \
- --output-file ${isochron_dat} \
- ${extra_args} \
- --quiet
- isochron_recv_stop 5000
- cpufreq_restore ${ISOCHRON_CPU}
- }
|