Back to home page

OSCL-LXR

 
 

    


0001 #!/bin/bash
0002 # SPDX-License-Identifier: GPL-2.0
0003 # Copyright 2021-2022 NXP
0004 
0005 REQUIRE_ISOCHRON=${REQUIRE_ISOCHRON:=yes}
0006 REQUIRE_LINUXPTP=${REQUIRE_LINUXPTP:=yes}
0007 
0008 # Tunables
0009 UTC_TAI_OFFSET=37
0010 ISOCHRON_CPU=1
0011 
0012 if [[ "$REQUIRE_ISOCHRON" = "yes" ]]; then
0013         # https://github.com/vladimiroltean/tsn-scripts
0014         # WARNING: isochron versions pre-1.0 are unstable,
0015         # always use the latest version
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         # declare dynamic variables ptp4l_log_${if_name} and ptp4l_pid_${if_name}
0070         # as global, so that they can be referenced later
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         # Kernel may be compiled with CONFIG_CPU_FREQ disabled
0105         if ! [ -d /sys/bus/cpu/devices/cpu${cpu}/cpufreq ]; then
0106                 return
0107         fi
0108 
0109         # declare dynamic variables cpu${cpu}_freq and cpu${cpu}_governor as
0110         # global, so they can be referenced later
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 }