媒体子系统中的调试和跟踪

本文档用作媒体子系统中调试设备驱动程序以及从用户空间调试这些驱动程序的起点和查找点。

通用调试建议

有关一般建议,请参阅通用建议文档

以下各节将向您展示一些可用的工具。

dev_debug 模块参数

每个视频设备都提供一个 dev_debug 参数,允许您进一步了解后台的 IOCTL。

# cat /sys/class/video4linux/video3/name
rkvdec
# echo 0xff > /sys/class/video4linux/video3/dev_debug
# dmesg -wH
[...] videodev: v4l2_open: video3: open (0)
[  +0.000036] video3: VIDIOC_QUERYCAP: driver=rkvdec, card=rkvdec,
bus=platform:rkvdec, version=0x00060900, capabilities=0x84204000,
device_caps=0x04204000

有关完整文档,请参阅视频设备调试

dev_dbg() / v4l2_dbg()

两个调试打印语句,专门用于设备和 v4l2 子系统,除非它们对调查具有长期价值,否则避免将它们添加到最终提交中。

有关一般概述,请参阅printk() 和朋友 指南。

  • 两者之间的区别?

    • v4l2_dbg() 在底层使用 v4l2_printk(),后者进一步直接使用 printk(),因此它不能被动态调试定位

    • dev_dbg() 可以被动态调试定位

    • v4l2_dbg() 具有更具体的媒体子系统前缀格式,而 dev_dbg 仅突出显示驱动程序名称和日志位置

动态调试

一种将调试输出精简到您需要的方法。

有关一般建议,请参阅动态调试 指南。

这是一个示例,启用文件中所有可用的 pr_debug()

$ alias ddcmd='echo $* > /proc/dynamic_debug/control'
$ ddcmd '-p; file v4l2-h264.c +p'
$ grep =p /proc/dynamic_debug/control
 drivers/media/v4l2-core/v4l2-h264.c:372 [v4l2_h264]print_ref_list_b =p
 "ref_pic_list_b%u (cur_poc %u%c) %s"
 drivers/media/v4l2-core/v4l2-h264.c:333 [v4l2_h264]print_ref_list_p =p
 "ref_pic_list_p (cur_poc %u%c) %s\n"

Ftrace

一个内部内核跟踪器,可以跟踪静态预定义的事件、函数调用等。对于调试无需更改内核的问题以及了解子系统的行为非常有用。

有关一般建议,请参阅Ftrace 指南。

DebugFS

此工具允许您将驱动程序的内部值转储或修改到自定义文件系统中的文件中。

有关一般建议,请参阅DebugFS 指南。

Perf & 替代方案

用于测量运行系统上的各种统计数据以诊断问题的工具。

有关一般建议,请参阅Perf & 替代方案 指南。

媒体设备示例

收集解码作业的统计数据:(此示例是在使用 fluster 测试套件 的 rkvdec 编解码器驱动程序的 RK3399 SoC 上)

 perf stat -d python3 fluster.py run -d GStreamer-H.264-V4L2SL-Gst1.0 -ts
 JVT-AVC_V1 -tv AUD_MW_E -j1
 ...
 Performance counter stats for 'python3 fluster.py run -d
 GStreamer-H.264-V4L2SL-Gst1.0 -ts JVT-AVC_V1 -tv AUD_MW_E -j1 -v':

        7794.23 msec task-clock:u                     #    0.697 CPUs utilized
              0      context-switches:u               #    0.000 /sec
              0      cpu-migrations:u                 #    0.000 /sec
          11901      page-faults:u                    #    1.527 K/sec
      882671556      cycles:u                         #    0.113 GHz                         (95.79%)
      711708695      instructions:u                   #    0.81  insn per cycle              (95.79%)
       10581935      branches:u                       #    1.358 M/sec                       (15.13%)
        6871144      branch-misses:u                  #   64.93% of all branches             (95.79%)
      281716547      L1-dcache-loads:u                #   36.144 M/sec                       (95.79%)
        9019581      L1-dcache-load-misses:u          #    3.20% of all L1-dcache accesses   (95.79%)
<not supported>      LLC-loads:u
<not supported>      LLC-load-misses:u

   11.180830431 seconds time elapsed

    1.502318000 seconds user
    6.377221000 seconds sys

事件和指标的可用性取决于您正在运行的系统。

错误检查和崩溃分析

各种内核配置选项,以提高 Linux 内核的错误检测能力,但会降低性能。

有关一般建议,请参阅KASAN、UBSAN、lockdep 和其他错误检查器 指南。

使用 v4l2-compliance 进行驱动程序验证

为了验证驱动程序是否符合 v4l2 API,使用 v4l2-compliance 工具,该工具是 v4l_utils 的一部分,后者是一套用于处理媒体子系统的用户空间工具。

要查看详细的媒体拓扑(并检查它),请使用

v4l2-compliance -M /dev/mediaX --verbose

您还可以对媒体拓扑中引用的所有设备运行完整的合规性检查,方法是

v4l2-compliance -m /dev/mediaX

调试接收视频的问题

在驱动程序中实现 vidioc_log_status:这可以将当前状态记录到内核日志。它由 v4l2-ctl --log-status 调用。对于调试接收视频(TV/S-Video/HDMI 等)的问题非常有用,因为视频信号是外部的(因此不可预测)。对于摄像头传感器输入不太有用,因为您可以控制摄像头传感器的工作方式。

通常您可以只分配默认值

.vidioc_log_status  = v4l2_ctrl_log_status,

但您也可以创建自己的回调来创建自定义状态日志。

您可以在 cobalt 驱动程序中找到一个示例 (drivers/media/pci/cobalt/cobalt-v4l2.c)。

版权所有 ©2024 : Collabora