blob: b91bcd8008a9930529e6235c3a5d45e04740cf6b (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
|
#!/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}
}
|