更新音频调试日志和修复脚本,添加 HDMI 监控工具

This commit is contained in:
Jack
2026-05-21 11:22:17 +08:00
parent e8073bc448
commit bd5a3e81d9
77 changed files with 15716 additions and 31339 deletions

View File

@@ -0,0 +1,172 @@
#!/usr/bin/env bash
set -euo pipefail
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
LOG_DIR="${REPO_ROOT}/_logs"
SOF_BIN_ROOT="${SOF_BIN_ROOT:-/var/tmp/sof-bin-upgrade/sof-bin-2025.12.2}"
SOF_LOGGER="${SOF_LOGGER:-${SOF_BIN_ROOT}/tools/sof-logger}"
SOF_LDC_DEFAULT="${SOF_LDC_DEFAULT:-${SOF_BIN_ROOT}/sof/sof-cml.ldc}"
mkdir -p "${LOG_DIR}"
ts="$(date +%Y%m%d_%H%M%S)"
start_ts_human="$(date '+%F %T')"
sof_log="${LOG_DIR}/sof-logger_${ts}.log"
kernel_log="${LOG_DIR}/kernel_sof_ipc_${ts}.log"
pipewire_log="${LOG_DIR}/user_pipewire_${ts}.log"
sof_debug_snapshot="${LOG_DIR}/sof-debugfs_${ts}.txt"
echo "[INFO] repo=${REPO_ROOT}"
echo "[INFO] log_dir=${LOG_DIR}"
echo "[INFO] start_ts=${start_ts_human}"
echo
if [[ "${EUID}" -ne 0 ]]; then
echo "[ERROR] 请用 sudo 运行sudo bash scripts/sof-trace-capture.sh" >&2
exit 1
fi
echo "[STEP] 1) 确保 debugfs 已挂载 (/sys/kernel/debug)"
if ! mountpoint -q /sys/kernel/debug; then
mount -t debugfs none /sys/kernel/debug
fi
if [[ ! -d /sys/kernel/debug ]]; then
echo "[ERROR] /sys/kernel/debug 不存在?" >&2
exit 1
fi
echo "[INFO] debugfs: OK"
echo
echo "[STEP] 2) 检查 sof-logger 工具"
if [[ ! -x "${SOF_LOGGER}" ]]; then
echo "[ERROR] 找不到可执行的 sof-logger" >&2
echo " ${SOF_LOGGER}" >&2
echo " 可通过环境变量覆盖SOF_BIN_ROOT 或 SOF_LOGGER" >&2
exit 1
fi
echo "[INFO] sof-logger=${SOF_LOGGER}"
echo
echo "[STEP] 2.1) 确认 SOF dictionary (.ldc)"
SOF_LDC="${SOF_LDC:-${SOF_LDC_DEFAULT}}"
if [[ ! -e "${SOF_LDC}" ]]; then
echo "[ERROR] 未找到 SOF .ldc 文件:" >&2
echo " ${SOF_LDC}" >&2
echo " 可通过环境变量覆盖SOF_LDC" >&2
exit 1
fi
echo "[INFO] SOF_LDC=${SOF_LDC}"
echo
echo "[STEP] 2.2) 确认 debugfs 下的 SOF trace 节点"
# We expect one of these to exist when SOF is running.
SOF_TRACE_NODE=""
SOF_TRACE_MODE=""
for p in /sys/kernel/debug/sof/trace /sys/kernel/debug/sof/etrace; do
if [[ -e "$p" ]]; then
SOF_TRACE_NODE="$p"
if [[ "$p" == */trace ]]; then
SOF_TRACE_MODE="trace"
else
SOF_TRACE_MODE="etrace"
fi
break
fi
done
if [[ -z "${SOF_TRACE_NODE}" ]]; then
echo "[ERROR] 未找到 /sys/kernel/debug/sof/{trace,etrace}(可能权限或内核配置问题)" >&2
echo " 你可以先用 root 查看ls -la /sys/kernel/debug/sof" >&2
exit 1
fi
echo "[INFO] SOF_TRACE_NODE=${SOF_TRACE_NODE}"
echo "[INFO] SOF_TRACE_MODE=${SOF_TRACE_MODE}"
echo
echo "[STEP] 2.3) 记录 SOF debugfs 快照(用于后续定位)"
{
echo "=== snapshot ts=${start_ts_human} ==="
echo "SOF_TRACE_NODE=${SOF_TRACE_NODE}"
echo "SOF_TRACE_MODE=${SOF_TRACE_MODE}"
echo
echo "## ls -la /sys/kernel/debug/sof"
ls -la /sys/kernel/debug/sof 2>&1 || true
echo
for f in fw_version dsp_state ipc4_fw_status ipc4_bldr_status; do
if [[ -e "/sys/kernel/debug/sof/${f}" ]]; then
echo "## cat /sys/kernel/debug/sof/${f}"
cat "/sys/kernel/debug/sof/${f}" 2>&1 || true
echo
fi
done
} > "${sof_debug_snapshot}" 2>&1 || true
echo "[DONE] sof debugfs snapshot: ${sof_debug_snapshot}"
cleanup() {
echo
echo "[STEP] 4) 收集日志窗口 (since ${start_ts_human})"
# Kernel: capture SOF/ASoC/HDMI related lines since start
journalctl -k -b --since "${start_ts_human}" --no-pager 2>/dev/null | \
grep -nE 'sof-audio|snd_sof|sof_ipc3_pcm_hw_params|ipc tx error|STREAM_PCM_PARAMS|ASoC error|set_hw_params|HDMI[0-9]|pcm[0-9]+' \
> "${kernel_log}" || true
# User PipeWire: capture since start
journalctl --user -u pipewire -b --since "${start_ts_human}" --no-pager 2>/dev/null \
> "${pipewire_log}" || true
echo "[DONE] sof-logger: ${sof_log}"
echo "[DONE] kernel window: ${kernel_log}"
echo "[DONE] pipewire window: ${pipewire_log}"
echo
echo "[NEXT] 请把这三份日志发我分析:"
echo " - ${sof_log}"
echo " - ${kernel_log}"
echo " - ${pipewire_log}"
}
trap cleanup INT TERM EXIT
echo
echo "[STEP] 3) 开始抓取 SOF trace前台运行按 Ctrl+C 结束并收集窗口日志)"
echo "[ACTION] 现在请在另一个终端复现一次问题(例如触发 HDMI pcm2 的播放/切换)。"
echo
echo "[INFO] capturing to: ${sof_log}"
echo
# sof-logger 参数说明(关键):
# -l: 传入 .ldc dictionary不是输出文件
# -t: 选择 DMA trace stream会强制读取 /sys/kernel/debug/sof/trace
# -i/-o: 将输入流解码输出到文件
echo "[INFO] NOTE: etrace 通常是“读完当前缓冲就退出”,所以这里使用循环追加,直到 Ctrl+C。"
echo
touch "${sof_log}"
echo "=== sof-trace-capture start ${start_ts_human} ===" >> "${sof_log}"
capture_once() {
local tmp="${LOG_DIR}/.sof-logger_${ts}.tmp"
rm -f "${tmp}"
if [[ "${SOF_TRACE_MODE}" == "trace" ]]; then
"${SOF_LOGGER}" -l "${SOF_LDC}" -t -i "${SOF_TRACE_NODE}" -o "${tmp}" || true
else
# etrace mailbox: do NOT pass -t, otherwise sof-logger will try /sys/kernel/debug/sof/trace
"${SOF_LOGGER}" -l "${SOF_LDC}" -i "${SOF_TRACE_NODE}" -o "${tmp}" || true
fi
if [[ -s "${tmp}" ]]; then
{
echo
echo "=== sof-logger chunk @ $(date '+%F %T') ==="
cat "${tmp}"
} >> "${sof_log}"
fi
rm -f "${tmp}"
}
while true; do
capture_once
sleep 0.2
done