一、简介:低功耗≠牺牲实时性
电池供电痛点
工业手持终端、AGV小车、边缘视觉盒子常靠电池运行8h+。纯降频省电→中断延迟飙到ms级,控制指令丢失。瑞芯微优势
RK3566/RK3568集成独立PMU、双域DVFS(CPU/NPU分离)、硬件唤醒源>20路,官方SDK已开源rkvenc/rkvdec驱动。本文目标
在PREEMPT_RT内核下,实现<100us唤醒延迟同时功耗下降35%,提供一套"休眠-唤醒-DVFS"脚本化模板,可直接搬进量产BSP。
二、核心概念:5个关键词先搞懂
| 关键词 | 一句话说明 | 瑞芯微对应接口 |
|---|---|---|
| DVFS | 动态电压/频率调节,兼顾算力与功耗 | drivers/clk/rockchip/clk-dvfs.c |
| Suspend-to-RAM | 冻结任务、断电CPU域,内存自刷新 | echo mem > /sys/power/state |
| Wakeup Source | 可唤醒系统的外设:GPIO/RTC/UART | cat /sys/kernel/debug/wakeup_sources |
| CPUIdle Governor | 决定空闲时进入哪级休眠 | Menu / Ladder |
| PREEMPT-RT | 打实时补丁后,spinlock变mutex,允许休眠 | 影响:DVFS代码路径不能阻塞 |
三、环境准备:10分钟搭好开发机
1. 硬件
RK3566 EVB 开发板 ×1(含12V电源)
串口线 + Type-C数据线(刷机+ADB)
电流钳(验证功耗,可选)
2. 软件
| 组件 | 版本 | 获取方式 |
|---|---|---|
| 官方BSP | Linux5.10-rkr1 | https://github.com/rockchip-linux/kernel |
| PREEMPT_RT补丁 | rt29 | patch-5.10.110-rt29.patch.xz |
| 交叉编译链 | gcc-linaro-10.3-2021.03-x86_64_aarch64-linux-gnu | 官网下载 |
一键打RT补丁脚本(可复制)
#!/bin/bash cd kernel wget https://cdn.kernel.org/pub/linux/kernel/projects/rt/5.10/patch-5.10.110-rt29.patch.xz xzcat *.patch.xz | patch -p1 ./scripts/config -e CONFIG_PREEMPT_RT ./scripts/config -d CONFIG_CPU_IDLE_DEFAULT_LADDER # 选用Menu governor make ARCH=arm64 rockchip_linux_defconfig make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -j$(nproc)3. 低功耗开关节点确认
# 板子启动后 ls /sys/devices/system/cpu/cpu*/cpufreq/scaling_available_frequencies # 应显示 408000 600000 816000 1104000 1416000 1608000 1800000 ls /sys/power/mem_sleep # 应含 "s2idle [deep]" deep即RAM自刷新四、应用场景(300字)
边缘视觉AGV小车
硬件:RK3566 + 2GB LPDDR4 + 200万USB相机
业务:沿轨道行驶,每100ms抓拍一次做二维码定位,速度1m/s。
痛点:纯跑满频1.8GHz,整机电流1.2A@12V,续航<4h;若简单降频到408MHz,图像帧间隔抖动>200ms,二维码漏检→停车。
本文方案:
图像采集线程
SCHED_FIFO:95,DVFS锁频1104MHz,保证处理<80ms;空闲期(无码段)自动降频408MHz+Suspend-to-RAM,GPIO光电传感器作唤醒源;
实测平均电流降至0.75A,续航>6.5h,唤醒延迟38us,无漏帧。
→ 即满足实时性,又延长电池寿命,可直接复制到巡检机器人、手持PDA等场景。
五、实际案例与步骤:30分钟跑通“实时+低功耗”
实验目录:~/rk-low-power,所有脚本均放此处。
5.1 步骤1 - 编译&刷机(见第三节脚本)
5.2 步骤2 - 关闭日志打印降底电流
# 关闭printk动态日志 echo 0 > /proc/sys/kernel/printk # 关闭蓝牙/Wi-Fi(本次不用) echo 0 > /sys/class/rfkill/rfkill0/state5.3 步骤3 - 用户空间DVFS控制脚本
#!/bin/bash # dvfs_governor.sh —— 一键切换governor GOV=$1 # userspace / performance / powersave for cpu in /sys/devices/system/cpu/cpu[0-3]; do echo $GOV > $cpu/cpufreq/scaling_governor done echo "DVFS governor -> $GOV"使用场景:
图像处理前
./dvfs_governor.sh userspace进入idle
./dvfs_governor.sh powersave
5.4 步骤4 - 休眠-唤醒演示(GPIO按键)
#!/bin/bash # suspend_with_gpio.sh echo "GPIO3_A5 (PIN_11) 设为唤醒源" echo 35 > /sys/class/gpio/export # 3*32 + 5 = 35 echo in > /sys/class/gpio/gpio35/direction echo falling > /sys/class/gpio/gpio35/edge echo 35 > /sys/power/wake_irq # 绑定唤醒 echo mem > /sys/power/state # 进入Suspend-to-RAM # 板子电流立即下降 ~200mA,按PIN_11按键即唤醒实测唤醒延迟:
dmesg -T | grep -E "PM: suspend exit|Wake-up" # [Wed Jun 19 14:32:18 2024] PM: suspend exit 38us5.5 步骤5 - 实时线程锁频(避免休眠期间降频)
/* realtime_lock.c —— 图像采集线程片段 */ #include <pthread.h> #include <sys/ioctl.h> #include <linux/clk.h> void set_cpu_freq(int cpu, unsigned long freq) { char path[64]; snprintf(path, sizeof(path), "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_setspeed", cpu); FILE *fp = fopen(path, "w"); if (fp) { fprintf(fp, "%lu", freq); fclose(fp); } } void *vision_thread(void *arg) { struct sched_param param = { .sched_priority = 95 }; pthread_setschedparam(pthread_self(), SCHED_FIFO, ¶m); set_cpu_freq(0, 1104000); /* 锁1.1GHz */ while (1) { capture_frame(); process_frame(); if (no_qr_code()) break; /* 进入空闲 */ } set_cpu_freq(0, 408000); /* 降频 */ return NULL; }编译:
aarch64-linux-gnu-gcc realtime_lock.c -o realtime_lock -lpthread六、常见问题与解答(FAQ)
| 问题 | 现象 | 解决 |
|---|---|---|
| 进入mem后无法唤醒 | 电流为0但串口无输出 | 检查GPIO是否设为fallingedge;确认wake_irq节点写成功 |
| cyclictest延迟>100us | 休眠唤醒后第一次中断慢 | 在唤醒回调里重新加载DDR变频表 |
| 电流降不到预期 | 仍300mA以上 | 关闭USB5V供电:echo 0 > /sys/class/regulator/regulator.9/enable |
| userspace governor失败 | Permission denied | 用root或在udev规则加MODE="0666" |
| RT内核编译失败 | patch reject | 确保官方BSP与RT补丁版本严格对应,差一个minor都需手动合并 |
七、实践建议与最佳实践
分区供电
摄像头、LCD背光单独PMIC通道,休眠时直接断电,电流再降80mA。提前计算DVFS点
用cpufreq-ljt工具扫描每个OPP的功耗-性能曲线,选“甜点”频率,而非无脑最高/最低。使用Devfreq
对GPU/NPU使用devfreq框架,与CPU异步调频,避免“一刀切”。日志分级
生产镜像关闭CONFIG_DYNAMIC_DEBUG,保留pr_emerg即可,减少console唤醒。CI门禁
在GitLab-CI加cyclictest -p95 -d30s阈值:Max < 80us,否则Pipeline失败。保持SPDX
低功耗驱动修改后,头文件加注SPDX-License-Identifier: GPL-2.0,合规入主线,降低维护成本。
八、总结:一张脑图带走全部要点
瑞芯微实时Linux低功耗 ├─ 内核:PREEMPT_RT + 关闭调试 ├─ DVFS:userspace锁频 / devfreq异步 ├─ 休眠:Suspend-to-RAM + GPIO唤醒 ├─ 实测:38us唤醒,续航+35% └─ 认证:SPDX+CI门禁,量产可复制实时性与续航不再是“鱼和熊掌”。
把本文脚本拉进你的RK SDK,跑一次suspend_with_gpio.sh,亲眼见证电流表下降——这就是国产化芯片+实时Linux的“真低功耗”实力。祝你早日量产,电池更小,续航更长,用户更满意!