0001
0002
0003
0004
0005 REQUIRE_ISOCHRON=${REQUIRE_ISOCHRON:=yes}
0006 REQUIRE_LINUXPTP=${REQUIRE_LINUXPTP:=yes}
0007
0008
0009 UTC_TAI_OFFSET=37
0010 ISOCHRON_CPU=1
0011
0012 if [[ "$REQUIRE_ISOCHRON" = "yes" ]]; then
0013
0014
0015
0016 require_command isochron
0017 fi
0018 if [[ "$REQUIRE_LINUXPTP" = "yes" ]]; then
0019 require_command phc2sys
0020 require_command ptp4l
0021 fi
0022
0023 phc2sys_start()
0024 {
0025 local if_name=$1
0026 local uds_address=$2
0027 local extra_args=""
0028
0029 if ! [ -z "${uds_address}" ]; then
0030 extra_args="${extra_args} -z ${uds_address}"
0031 fi
0032
0033 phc2sys_log="$(mktemp)"
0034
0035 chrt -f 10 phc2sys -m \
0036 -c ${if_name} \
0037 -s CLOCK_REALTIME \
0038 -O ${UTC_TAI_OFFSET} \
0039 --step_threshold 0.00002 \
0040 --first_step_threshold 0.00002 \
0041 ${extra_args} \
0042 > "${phc2sys_log}" 2>&1 &
0043 phc2sys_pid=$!
0044
0045 echo "phc2sys logs to ${phc2sys_log} and has pid ${phc2sys_pid}"
0046
0047 sleep 1
0048 }
0049
0050 phc2sys_stop()
0051 {
0052 { kill ${phc2sys_pid} && wait ${phc2sys_pid}; } 2> /dev/null
0053 rm "${phc2sys_log}" 2> /dev/null
0054 }
0055
0056 ptp4l_start()
0057 {
0058 local if_name=$1
0059 local slave_only=$2
0060 local uds_address=$3
0061 local log="ptp4l_log_${if_name}"
0062 local pid="ptp4l_pid_${if_name}"
0063 local extra_args=""
0064
0065 if [ "${slave_only}" = true ]; then
0066 extra_args="${extra_args} -s"
0067 fi
0068
0069
0070
0071 declare -g "${log}=$(mktemp)"
0072
0073 chrt -f 10 ptp4l -m -2 -P \
0074 -i ${if_name} \
0075 --step_threshold 0.00002 \
0076 --first_step_threshold 0.00002 \
0077 --tx_timestamp_timeout 100 \
0078 --uds_address="${uds_address}" \
0079 ${extra_args} \
0080 > "${!log}" 2>&1 &
0081 declare -g "${pid}=$!"
0082
0083 echo "ptp4l for interface ${if_name} logs to ${!log} and has pid ${!pid}"
0084
0085 sleep 1
0086 }
0087
0088 ptp4l_stop()
0089 {
0090 local if_name=$1
0091 local log="ptp4l_log_${if_name}"
0092 local pid="ptp4l_pid_${if_name}"
0093
0094 { kill ${!pid} && wait ${!pid}; } 2> /dev/null
0095 rm "${!log}" 2> /dev/null
0096 }
0097
0098 cpufreq_max()
0099 {
0100 local cpu=$1
0101 local freq="cpu${cpu}_freq"
0102 local governor="cpu${cpu}_governor"
0103
0104
0105 if ! [ -d /sys/bus/cpu/devices/cpu${cpu}/cpufreq ]; then
0106 return
0107 fi
0108
0109
0110
0111 declare -g "${freq}=$(cat /sys/bus/cpu/devices/cpu${cpu}/cpufreq/scaling_min_freq)"
0112 declare -g "${governor}=$(cat /sys/bus/cpu/devices/cpu${cpu}/cpufreq/scaling_governor)"
0113
0114 cat /sys/bus/cpu/devices/cpu${cpu}/cpufreq/scaling_max_freq > \
0115 /sys/bus/cpu/devices/cpu${cpu}/cpufreq/scaling_min_freq
0116 echo -n "performance" > \
0117 /sys/bus/cpu/devices/cpu${cpu}/cpufreq/scaling_governor
0118 }
0119
0120 cpufreq_restore()
0121 {
0122 local cpu=$1
0123 local freq="cpu${cpu}_freq"
0124 local governor="cpu${cpu}_governor"
0125
0126 if ! [ -d /sys/bus/cpu/devices/cpu${cpu}/cpufreq ]; then
0127 return
0128 fi
0129
0130 echo "${!freq}" > /sys/bus/cpu/devices/cpu${cpu}/cpufreq/scaling_min_freq
0131 echo -n "${!governor}" > \
0132 /sys/bus/cpu/devices/cpu${cpu}/cpufreq/scaling_governor
0133 }
0134
0135 isochron_recv_start()
0136 {
0137 local if_name=$1
0138 local uds=$2
0139 local extra_args=$3
0140
0141 if ! [ -z "${uds}" ]; then
0142 extra_args="--unix-domain-socket ${uds}"
0143 fi
0144
0145 isochron rcv \
0146 --interface ${if_name} \
0147 --sched-priority 98 \
0148 --sched-fifo \
0149 --utc-tai-offset ${UTC_TAI_OFFSET} \
0150 --quiet \
0151 ${extra_args} & \
0152 isochron_pid=$!
0153
0154 sleep 1
0155 }
0156
0157 isochron_recv_stop()
0158 {
0159 { kill ${isochron_pid} && wait ${isochron_pid}; } 2> /dev/null
0160 }
0161
0162 isochron_do()
0163 {
0164 local sender_if_name=$1; shift
0165 local receiver_if_name=$1; shift
0166 local sender_uds=$1; shift
0167 local receiver_uds=$1; shift
0168 local base_time=$1; shift
0169 local cycle_time=$1; shift
0170 local shift_time=$1; shift
0171 local num_pkts=$1; shift
0172 local vid=$1; shift
0173 local priority=$1; shift
0174 local dst_ip=$1; shift
0175 local isochron_dat=$1; shift
0176 local extra_args=""
0177 local receiver_extra_args=""
0178 local vrf="$(master_name_get ${sender_if_name})"
0179 local use_l2="true"
0180
0181 if ! [ -z "${dst_ip}" ]; then
0182 use_l2="false"
0183 fi
0184
0185 if ! [ -z "${vrf}" ]; then
0186 dst_ip="${dst_ip}%${vrf}"
0187 fi
0188
0189 if ! [ -z "${vid}" ]; then
0190 vid="--vid=${vid}"
0191 fi
0192
0193 if [ -z "${receiver_uds}" ]; then
0194 extra_args="${extra_args} --omit-remote-sync"
0195 fi
0196
0197 if ! [ -z "${shift_time}" ]; then
0198 extra_args="${extra_args} --shift-time=${shift_time}"
0199 fi
0200
0201 if [ "${use_l2}" = "true" ]; then
0202 extra_args="${extra_args} --l2 --etype=0xdead ${vid}"
0203 receiver_extra_args="--l2 --etype=0xdead"
0204 else
0205 extra_args="${extra_args} --l4 --ip-destination=${dst_ip}"
0206 receiver_extra_args="--l4"
0207 fi
0208
0209 cpufreq_max ${ISOCHRON_CPU}
0210
0211 isochron_recv_start "${h2}" "${receiver_uds}" "${receiver_extra_args}"
0212
0213 isochron send \
0214 --interface ${sender_if_name} \
0215 --unix-domain-socket ${sender_uds} \
0216 --priority ${priority} \
0217 --base-time ${base_time} \
0218 --cycle-time ${cycle_time} \
0219 --num-frames ${num_pkts} \
0220 --frame-size 64 \
0221 --txtime \
0222 --utc-tai-offset ${UTC_TAI_OFFSET} \
0223 --cpu-mask $((1 << ${ISOCHRON_CPU})) \
0224 --sched-fifo \
0225 --sched-priority 98 \
0226 --client 127.0.0.1 \
0227 --sync-threshold 5000 \
0228 --output-file ${isochron_dat} \
0229 ${extra_args} \
0230 --quiet
0231
0232 isochron_recv_stop
0233
0234 cpufreq_restore ${ISOCHRON_CPU}
0235 }