Skip to content

Commit daa3980

Browse files
committed
lib_sensors: add DT-free helper library for discovery and test runners
- add lib_sensors.sh helpers to: - gate on ADSP remoteproc state and firmware presence - dump ssc_sensor_info inventory to file (avoid huge stdout) - parse AVAILABLE=true sensor TYPE list - run see_workhorse / ssc_drva_test with progress + log-based PASS/FAIL parsing - keep ShellCheck clean and deterministic argv handling Signed-off-by: Srikanth Muppandam <smuppand@qti.qualcomm.com>
1 parent 3725379 commit daa3980

1 file changed

Lines changed: 254 additions & 0 deletions

File tree

Runner/utils/lib_sensors.sh

Lines changed: 254 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,254 @@
1+
#!/bin/sh
2+
# Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
3+
# SPDX-License-Identifier: BSD-3-Clause-Clear
4+
# Sensor helpers (DT-free): discovery via ssc_sensor_info, run see_workhorse/ssc_drva_test, parse PASS/FAIL.
5+
6+
# Global outputs set by sensors_check_adsp_remoteproc()
7+
SENSORS_ADSP_FW=""
8+
SENSORS_ADSP_RPROC_PATH=""
9+
SENSORS_ADSP_STATE=""
10+
11+
sensors__trim_ws() {
12+
# usage: sensors__trim_ws " abc " -> prints "abc"
13+
# shellcheck disable=SC2001
14+
echo "$1" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//'
15+
}
16+
17+
# Append a line to a newline-separated list if it doesn't already exist.
18+
# usage: new_list="$(sensors_append_unique_line "$list" "accel")"
19+
sensors_append_unique_line() {
20+
list="$1"
21+
line="$2"
22+
23+
[ -z "$line" ] && { printf '%s\n' "$list"; return 0; }
24+
25+
if [ -z "$list" ]; then
26+
printf '%s\n' "$line"
27+
return 0
28+
fi
29+
30+
printf '%s\n' "$list" | grep -Fxq "$line" 2>/dev/null && {
31+
printf '%s\n' "$list"
32+
return 0
33+
}
34+
35+
printf '%s\n%s\n' "$list" "$line"
36+
}
37+
38+
sensors__firmware_exists_quick() {
39+
fw="$1"
40+
[ -z "$fw" ] && return 1
41+
# quick/cheap checks only (avoid heavy find):
42+
[ -f "/lib/firmware/$fw" ] && return 0
43+
[ -f "/lib/firmware/qcom/$fw" ] && return 0
44+
[ -f "/lib/firmware/qcom/qcs6490/$fw" ] && return 0
45+
[ -f "/vendor/firmware/$fw" ] && return 0
46+
[ -f "/vendor/firmware_mnt/image/$fw" ] && return 0
47+
return 1
48+
}
49+
50+
# Return codes:
51+
# 0 = running
52+
# 1 = remoteproc found but not running
53+
# 2 = remoteproc not running and firmware missing
54+
# 3 = remoteproc not found (by firmware mapping)
55+
sensors_check_adsp_remoteproc() {
56+
fw="${1:-adsp.mbn}"
57+
58+
# NOTE: these are intentionally "output variables" for the caller (run.sh)
59+
# shellcheck disable=SC2034
60+
SENSORS_ADSP_FW="$fw"
61+
# shellcheck disable=SC2034
62+
SENSORS_ADSP_RPROC_PATH=""
63+
SENSORS_ADSP_STATE=""
64+
65+
if ! command -v get_remoteproc_path_by_firmware >/dev/null 2>&1; then
66+
return 3
67+
fi
68+
69+
rpath="$(get_remoteproc_path_by_firmware "$fw" 2>/dev/null || true)"
70+
if [ -z "$rpath" ] || [ ! -d "$rpath" ]; then
71+
return 3
72+
fi
73+
74+
# shellcheck disable=SC2034
75+
SENSORS_ADSP_RPROC_PATH="$rpath"
76+
77+
if command -v get_remoteproc_state >/dev/null 2>&1; then
78+
SENSORS_ADSP_STATE="$(get_remoteproc_state "$rpath" 2>/dev/null || true)"
79+
SENSORS_ADSP_STATE="$(sensors__trim_ws "$SENSORS_ADSP_STATE")"
80+
else
81+
if [ -r "$rpath/state" ]; then
82+
SENSORS_ADSP_STATE="$(cat "$rpath/state" 2>/dev/null || true)"
83+
SENSORS_ADSP_STATE="$(sensors__trim_ws "$SENSORS_ADSP_STATE")"
84+
fi
85+
fi
86+
87+
[ "$SENSORS_ADSP_STATE" = "running" ] && return 0
88+
89+
if sensors__firmware_exists_quick "$fw"; then
90+
return 1
91+
fi
92+
return 2
93+
}
94+
95+
sensors_dump_ssc_sensor_info() {
96+
out_file="$1"
97+
: >"$out_file" 2>/dev/null || true
98+
ssc_sensor_info >"$out_file" 2>&1
99+
return $?
100+
}
101+
102+
sensors_types_from_ssc_file() {
103+
f="$1"
104+
[ -r "$f" ] || return 1
105+
106+
awk '
107+
function trim(s) { sub(/^[ \t\r\n]+/, "", s); sub(/[ \t\r\n]+$/, "", s); return s }
108+
/^TYPE[[:space:]]*=/ {
109+
type = $0
110+
sub(/^TYPE[[:space:]]*=[[:space:]]*/, "", type)
111+
type = trim(type)
112+
}
113+
/^AVAILABLE[[:space:]]*=/ {
114+
avail = $0
115+
sub(/^AVAILABLE[[:space:]]*=[[:space:]]*/, "", avail)
116+
avail = trim(avail)
117+
}
118+
/^PHYSICAL_SENSOR[[:space:]]*=/ {
119+
phys = $0
120+
sub(/^PHYSICAL_SENSOR[[:space:]]*=[[:space:]]*/, "", phys)
121+
phys = trim(phys)
122+
}
123+
/^$/ {
124+
if (type != "" && avail == "true") {
125+
if (phys == "" || phys == "true") print type
126+
}
127+
type=""; avail=""; phys=""
128+
}
129+
END {
130+
if (type != "" && avail == "true") {
131+
if (phys == "" || phys == "true") print type
132+
}
133+
}
134+
' "$f" 2>/dev/null | sort -u
135+
}
136+
137+
sensors_type_present() {
138+
types_nl="$1"
139+
needle="$2"
140+
printf '%s\n' "$types_nl" | grep -Fxq "$needle" 2>/dev/null
141+
}
142+
143+
# Run a command in background, redirect all output to logfile, and print a heartbeat.
144+
# sensors_run_cmd_with_progress <logfile> <label> <duration_sec> <heartbeat_sec> -- <cmd...>
145+
sensors_run_cmd_with_progress() {
146+
logf="$1"
147+
label="$2"
148+
dur="$3"
149+
hb="$4"
150+
shift 4
151+
152+
[ "${1:-}" = "--" ] || return 2
153+
shift
154+
155+
: >"$logf" 2>/dev/null || true
156+
157+
"$@" >"$logf" 2>&1 &
158+
pid=$!
159+
160+
elapsed=0
161+
pad="${SENSORS_TIMEOUT_PAD_SECS:-15}"
162+
case "$dur" in ""|*[!0-9]*) dur=10 ;; esac
163+
case "$hb" in ""|*[!0-9]*) hb=5 ;; esac
164+
timeout=$((dur + pad))
165+
166+
log_info "$label started (log: $logf)"
167+
168+
while kill -0 "$pid" 2>/dev/null; do
169+
if [ "$elapsed" -ge "$timeout" ]; then
170+
log_error "$label TIMEOUT after ${elapsed}s (killing pid $pid). Log: $logf"
171+
kill "$pid" 2>/dev/null || true
172+
sleep 1
173+
kill -9 "$pid" 2>/dev/null || true
174+
break
175+
fi
176+
177+
# Sleep in small steps so we don't oversleep after the cmd already finished
178+
step=1
179+
while [ "$step" -le "$hb" ]; do
180+
sleep 1 2>/dev/null || true
181+
kill -0 "$pid" 2>/dev/null || break
182+
step=$((step + 1))
183+
done
184+
185+
kill -0 "$pid" 2>/dev/null || break
186+
elapsed=$((elapsed + hb))
187+
log_info "$label running... ${elapsed}/${dur}s (log: $logf)"
188+
done
189+
190+
wait "$pid" 2>/dev/null
191+
return $?
192+
}
193+
194+
sensors_see_workhorse_passed() {
195+
logf="$1"
196+
[ -r "$logf" ] || return 1
197+
198+
# Decide verdict by the *last* PASS/FAIL marker in the log.
199+
# This handles duplicate PASS lines and any earlier noise.
200+
last="$(grep -E '^(PASS|FAIL)[[:space:]]+see_workhorse' "$logf" 2>/dev/null | tail -n 1 | awk '{print $1}')"
201+
202+
if [ "$last" = "PASS" ]; then
203+
return 0
204+
fi
205+
if [ "$last" = "FAIL" ]; then
206+
return 1
207+
fi
208+
209+
# Fallback if no explicit markers found:
210+
# consider non-empty log as "likely ran", but you can make this stricter if needed.
211+
[ -s "$logf" ] && return 0
212+
return 1
213+
}
214+
215+
sensors_run_see_workhorse() {
216+
sensor="$1"
217+
duration="$2"
218+
outdir="$3"
219+
hb="${4:-5}"
220+
disp="${SENSORS_DISPLAY_EVENTS:-1}"
221+
222+
logf="$outdir/see_workhorse_${sensor}.log"
223+
label="see_workhorse(${sensor})"
224+
225+
sensors_run_cmd_with_progress "$logf" "$label" "$duration" "$hb" -- \
226+
see_workhorse -sensor="$sensor" -sample_rate=max -duration="$duration" -display_events="$disp"
227+
228+
sensors_see_workhorse_passed "$logf"
229+
return $?
230+
}
231+
232+
sensors_run_ssc_drva_test() {
233+
sensor="$1"
234+
duration="$2"
235+
outdir="$3"
236+
hb="${4:-5}"
237+
238+
command -v ssc_drva_test >/dev/null 2>&1 || return 2
239+
240+
logf="$outdir/ssc_drva_test_${sensor}.log"
241+
label="ssc_drva_test(${sensor})"
242+
243+
set -- ssc_drva_test -sensor="$sensor" -duration="$duration" -sample_rate=-1
244+
if [ "$sensor" = "accel" ] && [ -n "${SENSORS_DRVA_NUM_SAMPLES:-}" ]; then
245+
set -- "$@" -num_samples="${SENSORS_DRVA_NUM_SAMPLES}"
246+
fi
247+
248+
sensors_run_cmd_with_progress "$logf" "$label" "$duration" "$hb" -- "$@"
249+
rc=$?
250+
251+
grep -q '^FAIL' "$logf" 2>/dev/null && return 1
252+
[ "$rc" -eq 0 ] && return 0
253+
return 1
254+
}

0 commit comments

Comments
 (0)