在 Rockchip 设备上查看 CPU、GPU、NPU、RGA 和视频编解码状态,主要会用到三类接口:sysfs、debugfs 和驱动提供的 /proc 节点。容器中还可以直接通过 /dev/rga 查询 RGA 驱动版本。

本文按“在哪里执行、通过什么接口、能得到什么信息”整理常用命令。示例路径来自 RK3588 开发机和旧固件设备;不同固件的节点可能不同,应先枚举再读取。

开发机信息于 2026 年 10 月 30 日读取,容器操作依据 2026 年 10 月 29 日的旧设备实测记录。两组记录来自不同设备。文中不包含真实 IP、账号、主机名、容器 ID 或内部目录。

几种方式如何选择

执行位置与方式

能获取的信息

前提

宿主机读取 sysfs

CPU/GPU/NPU 频率、调频策略、温度

对应驱动已暴露节点

宿主机读取 debugfs 和 proc

RGA/NPU 驱动版本与负载、MPP 状态

debugfs 已挂载,且当前用户有读取权限

容器内直接读取

容器中已可见的上述节点

节点没有被隐藏或屏蔽

容器内临时挂载 debugfs

RGA/NPU 版本和负载

已具备创建挂载命名空间及挂载 debugfs 的权限

容器内通过设备 ioctl 查询

RGA 内核驱动版本

/dev/rga 可访问,驱动支持查询接口

以下命令以查询为主,不调整频率、电压或业务配置。挂载 debugfs 的步骤会改变挂载状态,放在单独的小节中说明。

方式一 在宿主机读取 sysfs

CPU 频率和调频策略

先枚举全部 policy,不要固定只读 policy0 和 policy4:

for policy in /sys/devices/system/cpu/cpufreq/policy*; do
  [ -d "$policy" ] || continue
  printf '\n%s\n' "${policy##*/}"
  for item in related_cpus scaling_cur_freq scaling_governor; do
    printf '%s: ' "$item"
    cat "$policy/$item"
  done
done

开发机实测存在三组策略:

策略

关联 CPU

当时的频率读数

policy0

0、1、2、3

1608000 kHz,即 1608 MHz

policy4

4、5

408000 kHz,即 408 MHz

policy6

6、7

408000 kHz,即 408 MHz

scaling_cur_freq 的单位是 kHz,部分驱动返回最近请求的频率状态,不一定是硬件瞬时频率的直接测量值。Linux CPUFreq 文档

确定节点后,可以周期查看:

watch -n 2 cat /sys/devices/system/cpu/cpufreq/policy0/scaling_cur_freq

温度

读取温度时同时查看 type,确认传感器对应哪个模块:

for zone in /sys/class/thermal/thermal_zone*; do
  [ -d "$zone" ] || continue
  printf '%s ' "${zone##*/}"
  cat "$zone/type" "$zone/temp" | tr '\n' ' '
  printf '\n'
done

开发机中,thermal_zone1 是 bigcore0-thermal,GPU 对应 thermal_zone5,NPU 对应 thermal_zone6。不能把某个编号固定理解为 GPU 温度。

temp 单位为毫摄氏度,例如 33307 表示约 33.3 ℃。Linux thermal ABI

GPU、NPU 和 DDR 频率

先查看本机暴露了哪些 devfreq 设备:

ls /sys/class/devfreq/

本次开发机有 fb000000.gpu 和 fdab0000.npu,对应命令为:

# GPU 频率和调频策略
cat /sys/class/devfreq/fb000000.gpu/cur_freq
cat /sys/class/devfreq/fb000000.gpu/governor

# GPU 负载,该节点是否存在取决于驱动
cat /sys/class/devfreq/fb000000.gpu/load

# NPU 频率和调频策略
cat /sys/class/devfreq/fdab0000.npu/cur_freq
cat /sys/class/devfreq/fdab0000.npu/governor

实测 GPU 为 300000000 Hz,NPU 为 1000000000 Hz,分别对应 300 MHz 和 1000 MHz。GPU 负载输出为 0@300000000Hz,包含了频率信息。

如果设备暴露了 dmc,还可以查询 DDR:

# 仅适用于存在这些节点的固件
cat /sys/class/devfreq/dmc/cur_freq
cat /sys/class/devfreq/dmc/load

本次开发机没有 dmc 节点,不能用这两个命令获取 DDR 指标。查看内存容量可使用 cat /proc/meminfo,但内存容量不等于 DDR 带宽。

方式二 在宿主机读取 debugfs 和 proc

检查 debugfs 是否已挂载

findmnt -t debugfs

通常挂载点是 /sys/kernel/debug。如果确认尚未挂载,并且需要这些调试接口,可在宿主机执行:

sudo mount -t debugfs debugfs /sys/kernel/debug

该命令创建的挂载不会随着命令结束自动卸载。已有挂载时直接复用,不要重复挂载。

RGA 版本、负载和硬件能力

# 内核驱动版本
sudo cat /sys/kernel/debug/rkrga/driver_version

# 当前负载
sudo cat /sys/kernel/debug/rkrga/load

# 硬件能力,是否存在取决于固件
sudo cat /sys/kernel/debug/rkrga/hardware

# RGA 相关时钟
sudo sh -c 'grep rga /sys/kernel/debug/clk/clk_summary'

开发机的驱动版本读数为:

RGA multicore Device Driver: v1.3.10b

hardware 用于查看硬件支持范围,load 用于查看活动情况;负载为 0% 不表示硬件不可用。clk_summary 中有核心时钟和总线时钟,需要结合时钟名称识别。

NPU 版本、负载及电源状态

sudo cat /sys/kernel/debug/rknpu/version
sudo cat /sys/kernel/debug/rknpu/load
sudo cat /sys/kernel/debug/rknpu/power

开发机实际读取到的版本和负载为:

RKNPU driver: v0.9.8
NPU load:  Core0:  0%, Core1:  0%, Core2:  0%,

power 等附加节点是否提供,以当前驱动为准。需要持续观察负载时,可使用:

sudo watch -n 2 cat /sys/kernel/debug/rknpu/load

MPP 视频编解码状态

MPP 驱动通常从 /proc/mpp_service 暴露信息,具体文件随固件而变:

# 驱动版本与会话信息,先确认节点是否存在
ls /proc/mpp_service/
cat /proc/mpp_service/version
cat /proc/mpp_service/sessions-summary

# 两个解码核心的累计任务计数
cat /proc/mpp_service/rkvdec-core0/task_count
cat /proc/mpp_service/rkvdec-core1/task_count

开发机和旧设备均可读取上述解码任务计数,但均没有 /proc/mpp_service/load。节点缺失应记录为“不可用”。

相邻采样的 task_count 增量可以用来观察任务是否增长。旧设备记录中 core0 每秒约增加 75,这不是 75% 利用率,也不能直接当作 75 FPS。sessions-summary 中的帧率字段也应先确认驱动定义。

方式三 在容器中直接读取已有节点

容器共享宿主机内核,但不一定能看到宿主机所有的 /sys、/proc 和设备节点。先进入容器检查,不需要一开始就修改容器配置。

下面的容器名是占位符,执行前替换为实际名称:

# 在宿主机执行
container_name='your-container'
sudo docker exec -it -u 0 "$container_name" sh

进入容器后,先检查节点可见性:

ls /sys/devices/system/cpu/cpufreq/
ls /sys/class/devfreq/
ls /sys/class/thermal/
ls -l /dev/rga
ls /sys/kernel/debug/rkrga/
ls /sys/kernel/debug/rknpu/
ls /proc/mpp_service/

已经可见的节点,可以直接使用前面相同的 cat 命令。容器内以 root 执行时,通常不需要再加 sudo;root 身份本身并不能解除所有容器访问限制。

也可以不进入交互终端,从宿主机执行单次查询:

container_name='your-container'
sudo docker exec -u 0 "$container_name" \
  cat /sys/kernel/debug/rkrga/driver_version

sudo docker exec -u 0 "$container_name" \
  cat /sys/kernel/debug/rknpu/load

这种写法仍然是在容器内部读取。如果宿主机能读、容器报文件不存在,应继续检查容器中的挂载和节点可见性。

方式四 在容器的临时命名空间挂载 debugfs

旧设备记录中,容器起初看不到 RGA 的 debugfs 文件,在临时挂载 debugfs 后可以读取版本和负载。该环境已具备所需权限,普通受限容器不一定能使用这种方式。

在容器内执行:

# 适用于尚未挂载 debugfs、且具备相关权限的容器
unshare --mount --propagation private sh -c '
  mount -t debugfs debugfs /sys/kernel/debug || exit 1
  cat /sys/kernel/debug/rkrga/driver_version
  cat /sys/kernel/debug/rkrga/load
  cat /sys/kernel/debug/rknpu/load
'

命令创建一个私有挂载命名空间,在其中挂载并读取数据;该命名空间不再被进程或其他引用持有后,挂载随之释放。它不会把挂载自动加入原有业务进程的命名空间。

需要连续采样时,在同一个命名空间内挂载一次,再循环读取:

unshare --mount --propagation private sh -c '
  mount -t debugfs debugfs /sys/kernel/debug || exit 1
  while :; do
    date "+%F %T"
    cat /sys/kernel/debug/rkrga/load
    cat /sys/kernel/debug/rknpu/load
    sleep 2
  done
'

按 Ctrl+C 结束。如果提示 Operation not permitted,说明当前环境不允许对应操作;可以改在宿主机读取。本文不要求为查询开启特权容器。

debugfs 暴露的是内核调试接口,不是宿主机普通目录。它的负载数据通常反映整台设备,不能直接视为当前容器的独占使用率。RGA 统计实现、RKNPU 统计实现

方式五 通过设备 ioctl 查询 RGA 驱动版本

如果只需要获取 RGA 内核驱动版本,而且容器中已经能够访问 /dev/rga,可以由现有程序通过 ioctl 查询,不依赖 debugfs 挂载。

调用顺序是:

open("/dev/rga", O_RDWR)
  → ioctl(fd, RGA_IOC_GET_DRVIER_VERSION, &version)
  → 读取 major、minor、revision 和版本字符串
  → close(fd)

应使用目标 SDK 提供的结构体和宏定义。接口标识的原始拼写就是 RGA_IOC_GET_DRVIER_VERSION。Rockchip RGA 接口定义

旧设备的容器内实测结果为:

ioctl return: 1
driver version: 1.2.10

成功返回值可以是 1,判断调用失败应使用 ret < 0,不能把所有非零返回都当成错误。cat /dev/rga 不能代替这个 ioctl 查询。Rockchip RGA 查询实现

如果要查询的是用户态库,可使用 librga 提供的版本查询接口,例如 querystring(RGA_VERSION)。旧记录中它返回 API 1.10.5_[1],与内核驱动的 1.2.10 是两类版本信息。

读取结果时保留这几条说明

  • 频率、温度和负载都是采样时的读数,不能用单个数值判断整体性能。

  • 节点不存在、权限不足与负载为 0 是不同结果,应分别记录。

  • debugfs 输出可能包含会话和进程信息;分享时只摘录需要的版本、频率和负载,不直接发布整份原始日志。

  • 持续观察可先使用 1–5 秒间隔,并复用已有挂载;读取也有少量开销,实际周期还包含命令执行时间。