feat(powermgr): meow_powermgr 期0调研+期1骨架——功耗管理专项服务(POWER_MANAGER_DESIGN)

期0: POWER_HW_FACTS.md 真机只读取证——battery/无current_now(实时功率=derived+estimated
双轨)、无cpufreq(省电档无降频点)、背光量程0-101(非255)、rfkill可用、axp_battery为
幻影设备、无thermal zones、audiod STATE字段完备。

期1: patch_v2/meow_powermgr/ 单二进制双形态(meow_powermgr守护+meow_power CLI):
- svcd托管 trigger=boot/restart=on-fail;HibyOS只读降级(/tmp/meow_boot_mode!=meow
  只采样电池,不碰wlan0/bt/声卡,热切换)
- 权威充电链0-diff照抄svc_power(mp2731→fusb302→battery兜底)
- 电池深加工 state/cap/mV/health/续航估算(容量差分速率环 30s×240)
- 经验功耗模型(/usr/data/meow/power_model.conf 可调,内置默认全部标注待标定)
- IPC /usr/data/meow_pm.sock MSG_PM_QUERY(0x00D0)→MSG_PM_RESULT(0x00D1) JSON,
  subset位;meow_ipc.h 0x00D0-0x00D7 号段回填
- CLI status/estimate/model 落地(IPC优先+直读降级),history/top/events/policy 期2/3桩
- 宿主桩测试36+1例全过(MEOW_PS_DIR等假节点)+qemu-mipsel全过+真机对照svc_power
  battery口径一致(93%/4270mV);mipsel静态117KB(<200KB);-Wall -Wextra 0 warning
This commit is contained in:
MeowOS committed 2026-09-01 16:21:12 +08:00
1 parent 6a4d330a26
commit 250c9ae8b1
9 files changed
+1413

No files matched your search

+101
View File
@@ -0,0 +1,101 @@
# POWER_HW_FACTS — meow_powermgr 期 0 真机只读调研结论
> 调研时间:2026-09-01 15:43(设备 10.78.193.50,uptime 1:48,`/tmp/meow_boot_mode`=meow,固件 0.7.89+)。
> 方式:全部只读(ls/cat/sysfs 读),未写任何节点、未碰进程、未重启。
> 对照基准:`meow_svc_power battery` = `battery=94%(Discharging) 4275mV`。
## 0. 两个决定形态的关键结论(必读)
| 问题 | 结论 | 影响 |
|---|---|---|
| `battery/current_now` 存在吗? | **不存在**。battery/ 全集无 current_now/charge_now/charge_full/charge_full_design/cycle_count/temp | 实时功率**不可能 measured**;走「容量差分 derived」+「经验模型 estimated」双轨(设计 §3.3 第三档)。健康度(charge_full/design)**不可算**,只能透传 `health` 字符串 |
| `cpufreq` 存在吗? | **不存在**(`/sys/devices/system/cpu/cpu0/cpufreq/` No such file;单核 cpu0) | 省电档**无降频控制点**;CPU 功耗项只能按 util×满载系数估算,无可控项(设计 §5.1 CPU 行降级为「仅观测」) |
## 1. §7 清单逐项结论
### 项 1:battery/ 全集
```
capacity=94 health=Good present=1 status=Discharging(会撒谎,勿用)
technology=Li-ion voltage_now=4275000(µV) time_to_empty_now=8191
```
- `time_to_empty_now=8191`(=0x1FFF)为**恒定哨兵值**,不随负载变化 → 不可用,勿报。
- 无 temp 节点 → 电池温度报 null(充电器温度见项 2 可替代参考)。
### 项 2:mp2731-charger/(权威充电态 + 充电功率可算)
```
status=Discharging(权威源,设计 §3.1 已实测) online=0 temp=300(=30.0°C)
current_now=0(µA,放电时恒 0;充电时=充电电流) constant_charge_current=0/_max=4520000
constant_charge_voltage=4200000/_max=4670000 charge_term_current=120000
input_current_now=100000 input_current_limited=2000000 input_suspend=0
input_voltage_settled=2280000 charge_control_limit=3000000 charge_full=0(无效)
real_type=USB typec_power_role=sink step_charging_enabled=1
```
- **充电功率可估**:`constant_charge_voltage × current_now / 1e6`(充电中 current_now 非 0,待插电实测确认非 0 时刻的值域)。
- `charge_type` 节点不存在(清单原问的 charge_type 无)。
### 项 3:fusb302 / ac / usb / axp_battery
- `fusb302-typec-source/`:online✓(插线检测兜底)、voltage_now、current_max(PD 档位相关,本次=0)。
- `ac/`:online=0;voltage_now=4600/current_now=1200 为**静态默认值**(online=0 时不变),仅 online 位可用。
- `usb/`:online=0;current_now=780 静态默认。仅 online/present 位可用。
- **`axp_battery/`:幻影设备(不可用)**——capacity=0、voltage_now=0、current_now=200000 **三次采样(间隔 5s)恒定不变** → 非实时电量计,是 AXP 遗留驱动的死数据。唯一有用信息:`energy_full_design=1600` + `voltage_max_design=4350000/min=3400000`——可作**标称容量参考**(1600mAh 级,与 R3 Pro II 官方 1600mAh 电池吻合;诚实标注:单位/口径未经证实,仅作续航估算的默认标称容量,可经 power_model.conf `nominal_mah` 覆盖)。
### 项 4:cpufreq —— **不存在**(见 §0)
### 项 5:rfkill —— **存在且可用**
```
rfkill0: type=bluetooth state=1 soft=0 hard=0
rfkill1: type=wlan state=1 soft=0 hard=0
rfkill2: type=wlan state=1 soft=0 hard=0
rfkill3: type=bluetooth state=1 soft=0 hard=0
```
- 4 个 rfkill(2×wlan + 2×bluetooth,两个同类型并存——WiFi/BT combo 芯片双接口特征)。
- **软关断控制点存在**(写 soft=1,本次未写只读 state)→ 期 3 策略层可用「rfkill soft block」替代 `ip link down`/`hciconfig down`(更省电)。**红线不变:策略层不直接 poke sysfs,需经 svc_power 类动作通道或新增授权写点,期 3 定案。**
### 项 6:背光节点全集
```
max_brightness=101 brightness=0 actual_brightness=0 bl_power=0 type=raw
```
- **⚠️ 量程是 0-101,不是设计 §3.2 假定的 0-255** → 功耗表背光分档按 0-101 归一(亮度%=brightness/101×100 再分档)。POWER_MANAGER_DESIGN §3.2 表「0-255」需修正为「0-101(R3 Pro II 实测)」。
- 调查时刻 brightness=0(设备息屏中)→ **息屏态可用 actual_brightness==0 判定**(fb0/blank 读取为空串——驱动未实现 read,不可用)。
### 项 7/8:CPU 满载/背光/WiFi 标定实验
- 本期 0 未执行:容量差分法需分钟级窗口 + 逐项对照(亮屏定档/stress 满载/WiFi 传输),且设备无 current_now 真值可借 → **留待用户在场配合的标定窗口**(每次实验 ≥10min)。
- 方法已备:capacity 差分(94%→x%)÷ Δt × nominal_mah × 平均电压 = 平均功率;基线=息屏 WiFi 关联空闲。
- 在标定完成前,一切 mW 数字均为**占位经验值**(设计 §10 诚实标注不变)。
### 项 9:WiFi 状态/计数器
- `wpa_cli status` ✓:`wpa_state=COMPLETED`、bssid/freq/ssid/ip_address 全有(关联态可判)。
- `/proc/net/dev` wlan0 收发计数器 ✓(bytes/packets 递增)→ 传输态由增量判,可行。
- wpa_cli 无直接 scan 计数;扫网风暴可用 `wpa_cli scan_results` 时间戳或 wpa 日志——期 2 再定,标记**待验**。
### 项 10:蓝牙
- `hciconfig hci0` ✓(Type: Primary Bus: UART,当前 DOWN,RX/TX 计数器有)。
- `/sys/class/bluetooth/hci0/` ✓ → up/down + 连接数可判(连接数走 `hciconfig -a` 或 /sys 下 device 枚举,期 2 细化)。
### 项 11:audiod MSG_AUDIO_STATE
- `meow_audio status` 实测:`active=0 app=- sid=0 rate=44100 ch=2 fmt=- written=... played=... underrun=1 dropped=0 stall=0 txdrop=0 paused=0 route_mode=auto port=4 vol=44`。
- **字段完备**:active(流活跃)/route/port/vol 全有 → 音频链功耗项输入够用(无流≈静态 / 播放≈DAC+FPGA 档)。
### 项 12:thermal zones —— **不存在**
- `/sys/class/thermal/` 目录本身不存在;`/sys/class/hwmon/` 也不存在。
- 唯一温度源:`mp2731-charger/temp`=300(30.0°C,充电器芯片温度,非电池/SoC)。
- → 「异常发热」辅助信号**无热源可用**,期 2 异常检测规则不含温度维度(或仅用充电器温度粗参考)。
## 2. 对设计文档的回填修正
1. **§3.2 背光量程 0-255 → 0-101**(max_brightness 实测)。
2. **§3.3 实时功率**:current_now 路径(measured)**整层不可达**——v1 只有 derived(容量差分)+ estimated(经验模型)。UI 必须带 confidence 标注(设计已要求,此处确认强制执行)。
3. **§3.1 健康度**:charge_full/design 不存在 → health 输出透传 `health` 字符串(Good),不输出百分比。
4. **§3.1 续航估算**:以容量差分平均速率(%/min)为准;nominal_mah 默认 1600(axp energy_full_design 旁证,待标定)。
5. **§5.1 CPU 行**:无 cpufreq → 「降频」行为项删除,CPU 仅观测。
6. **§5.1 WiFi/BT 行**:rfkill soft block 可用作控制点候选(期 3 定案,v1 不动)。
7. **息屏判定**:fb0/blank 不可读 → 用 `backlight_pwm0/actual_brightness==0` 代理(期 1 采纳)。
8. **充电功率**:mp2731 `current_now`(µA) + `constant_charge_voltage`(µV) 可估充电功率(插电态待实测值域)。
## 3. 遗留 / 待验
- [ ] 插电态复测 mp2731 current_now/constant_charge_current 非零值域(充电功率估算校准)。
- [ ] 标定实验(项 7/8):需用户在场,≥10min/项 × 约 5 项。
- [ ] axp energy_full_design=1600 的单位口径(mAh? mWh?)——与官方 1600mAh 规格吻合但未经驱动源码证实。
- [ ] wpa 扫网频率计数法(期 2)。
- [ ] 时间校准对照:无 current_now,derived 功率的时间分辨率受 capacity 1% 粒度限制(1600mAh×1%=16mAh,~5-15min 才跳 1%)→ 续航估算 v1 精度受限,UI 需标注。
+31
View File
@@ -92,6 +92,15 @@ enum {
MSG_AUDIO_STATE = 0x00C8, /* ↓ 状态快照文本(NUL 结尾;当前流/参数/帧数/underrun/路由/音量) */
MSG_AUDIO_ROUTE = 0x00C9, /* ↑ 手动路由(u32 port:0=auto 2=3.5 3=4.4;调试/面板用) */
MSG_AUDIO_VOLUME = 0x00CA, /* ↑ 音量(i32 pct:-1=查询 0-100=设置;v1 透传写 DAC numid=1/2) */
/* ---- meow_powermgr 功耗管理服务(devdocs/plan/POWER_MANAGER_DESIGN.md §6.1):0x00D0-0x00D7 ----
* 语义:功耗维度的查看/分析/管理(svc_power 管动作、svc_perf 管性能,powermgr 管功耗)。
* 独立 socket /usr/data/meow_pm.sock(--sock/MEOW_PM_SOCK 覆盖)。鉴权分级同 svc_power:
* QUERY/HISTORY/EVENTS=读级任意调用者;POLICY_SET=动作级(期 3 落地时接 SO_PEERCRED 同源代码)。 */
MSG_PM_QUERY = 0x00D0, /* ↑ 功耗聚合查询(m_pm_query_t{subset}:PM_SUBSET_* 位;0=全部) */
MSG_PM_RESULT = 0x00D1, /* ↓ 聚合 JSON(电池深加工/功耗估算/分解/策略,形状对齐 §3/§4.1) */
/* 0x00D2 MSG_PM_POLICY_GET / 0x00D3 MSG_PM_POLICY_SET —— 期 3(profile/低电阈值读改,SET 动作级鉴权)
* 0x00D4 MSG_PM_HISTORY(u32 hours)/ 0x00D5 MSG_PM_HISTORY_RESULT(统计 JSON)—— 期 2
* 0x00D6 MSG_PM_EVENTS / 0x00D7 MSG_PM_EVENTS_RESULT(异常耗电事件清单)—— 期 2 */
MSG_SYS = 0x00F0 /* ↓ 系统事件(守护关闭/服务死亡/播放器状态) */
};
@@ -341,6 +350,28 @@ typedef struct m_power_status {
char msg[96]; /* 结果/状态文本 */
} m_power_status_t;
/* ---- meow_powermgr 功耗管理(POWER_MANAGER_DESIGN §6.1;服务端 meow_powermgr)---- */
/* MSG_PM_QUERY 子集位(0=全部) */
#define PM_SUBSET_BATTERY (1u << 0) /* 电池深加工:state/pct/mv/health/续航估算 */
#define PM_SUBSET_ESTIMATE (1u << 1) /* 当前功耗估算:est_mw + confidence(estimated/derived) */
#define PM_SUBSET_BREAKDOWN (1u << 2) /* 功耗分解:各子系统分量(§3.2 经验模型,系数待标定) */
#define PM_SUBSET_POLICY (1u << 3) /* 策略档位快照(期 3;期 1 恒 null) */
/* MSG_PM_QUERY ↑:功耗聚合查询 */
typedef struct m_pm_query {
uint32_t subset; /* 0=全部;PM_SUBSET_* 组合 */
} m_pm_query_t; /* 4 B */
/* MSG_PM_RESULT ↓:聚合 JSON(payload 为 NUL 结尾 JSON 文本,同 m_perf_result_t 口径) */
typedef struct m_pm_result {
uint32_t code; /* MEOW_OK / MEOW_ERR_* */
uint32_t subset; /* 回显请求 subset */
uint16_t json_len; /* json 有效字节(不含 NUL) */
uint16_t pad;
char json[MEOW_IPC_MAX - 12]; /* 聚合 JSON(§3/§4.1 形状) */
} m_pm_result_t;
/* ---- amsd 控制(AMSD_DESIGN §4.2)---- */
/* MSG_AMS_START →:请求 launcher 拉起某 App。app_id=包名(权威);activity 空=裸启动
+31
View File
@@ -0,0 +1,31 @@
#!/bin/bash
# build_powermgr.sh — meow_powermgr 交叉编译(mipsel 静态)+ 宿主编译可选。
#
# 目标:R3 Pro II / MeowOS(mipsel-linux-muslsf,静态)。powermgr 仅 POSIX + Linux 基接口
# (复用 meow_ipc.h 帧格式,无 launcher 依赖),单文件满足「固件内、不入卡」(<200KB 阈值)。
# 单一二进制双形态:/usr/bin/meow_powermgr(svcd 空参=守护)+ /usr/bin/meow_power(CLI,同一份
# 文件两次安装,argv[0] basename 分形态;fw_content.conf 两行同 src)。
#
# 用法:
# ./build_powermgr.sh # 交叉编译 → patch_v2/meow_powermgr/meow_powermgr(mipsel 静态)
# ./build_powermgr.sh host # 宿主编译 → patch_v2/meow_powermgr/meow_powermgr_host
set -e
cd "$(dirname "$0")"
ROOT="$HOME/Project/R3ProII"
CC="$ROOT/.tools/zig-mipsel-cc"
I_HDR="$ROOT/patch_v2/meow_launcherd" # meow_ipc.h(帧/MSG_PM_*/PM_SUBSET_*/m_pm_*)
if [ "$1" = "host" ]; then
HOST_CC="${CC_HOST:-cc}"
"$HOST_CC" -Os -Wall -Wextra -I"$I_HDR" meow_powermgr.c -o meow_powermgr_host
echo "== host build =="
ls -la meow_powermgr_host
file meow_powermgr_host
exit 0
fi
"$CC" -Os -Wall -Wextra -static -I"$I_HDR" meow_powermgr.c -o meow_powermgr
echo "== meow_powermgr (mipsel static) =="
ls -la meow_powermgr
md5sum meow_powermgr
file meow_powermgr
Binary file not shown.
File diff suppressed because it is too large. Load diff
Binary file not shown.
@@ -0,0 +1,15 @@
# meow_powermgr 板载服务配置(svcd 托管;由 S89meow_svcd 首启预置到 /usr/data/meow/services.d/)
#
# trigger=boot(用户定案 2026-09-01,POWER_MANAGER_DESIGN §附 1):开机即常驻,历史覆盖 boot 全程。
# HibyOS 只读降级在进程内门控:/tmp/meow_boot_mode != meow(含开机早期文件缺失)→ 只采样电池,
# 绝不施策略/不碰 wlan0/bt/声卡;文件落地为 meow 后下一采样拍自动转全功能(热切换,无需重启)。
# 与 audiod 的 trigger=manual+exit(0) 门控不同:功耗服务读侧天然无害,HibyOS 下挂只读采样器零干扰。
# restart=on-fail:崩溃只丢内存采样环(续航估算缓存),svcd 退避重拉,不级联(FRAMEWORK §10)。
exec=/usr/bin/meow_powermgr
args=
enabled=1
restart=on-fail
backoff_ms=2000
max_restart=5
trigger=boot
cap=
+162
View File
@@ -0,0 +1,162 @@
#!/bin/bash
# test_powermgr.sh — meow_powermgr 宿主桩测试(假 sysfs/procfs 节点,MEOW_*_DIR env 覆盖)。
# 用法:./test_powermgr.sh [host二进制路径](默认 ./meow_powermgr_host;可传 mipsel 二进制 + QEMU 前缀)
# QEMU="qemu-mipsel" ./test_powermgr.sh ./meow_powermgr # qemu 验证
set -u
cd "$(dirname "$0")"
BIN="${1:-./meow_powermgr_host}"
Q="${QEMU:-}"
T=$(mktemp -d /tmp/pmtest.XXXXXX)
trap 'kill $DPID 2>/dev/null; rm -rf "$T"' EXIT
PASS=0; FAIL=0
ck() { # ck <名> <期望子串> <实际>
if echo "$3" | grep -qF "$2"; then PASS=$((PASS+1)); echo "PASS $1";
else FAIL=$((FAIL+1)); echo "FAIL $1: 期望含 [$2] 实际=[$3]"; fi
}
# ---- 搭假节点 ----
PS="$T/ps"; BL="$T/bl"; NET="$T/net"; RF="$T/rfkill"; BT="$T/bt"
mkdir -p "$PS/battery" "$PS/mp2731-charger" "$PS/fusb302-typec-source" "$PS/ac" \
"$BL" "$NET/wlan0" "$RF/rfkill0" "$BT"
echo 94 > "$PS/battery/capacity"
echo Discharging > "$PS/battery/status"
echo 4275000 > "$PS/battery/voltage_now"
echo Good > "$PS/battery/health"
echo Li-ion > "$PS/battery/technology"
echo Discharging > "$PS/mp2731-charger/status" # 权威链
echo 300 > "$PS/mp2731-charger/temp"
echo 0 > "$PS/fusb302-typec-source/online"
echo 0 > "$PS/ac/online"
echo 101 > "$BL/max_brightness" # R3 Pro II 实测量程 0-101
echo 50 > "$BL/actual_brightness" # 中档(49%)
echo 50 > "$BL/brightness"
echo up > "$NET/wlan0/operstate"
echo bluetooth > "$RF/rfkill0/type"
echo 1 > "$RF/rfkill0/soft" # BT 被 soft 块 → off
cat > "$T/netdev" <<'EOF'
Inter-| Receive | Transmit
face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed
wlan0: 1000000 1000 0 0 0 0 0 0 2000000 1000 0 0 0 0 0 0
EOF
echo "cpu 100 0 100 800 0 0 0 0 0 0" > "$T/proc_stat"
echo meow > "$T/boot_mode"
ENVS="MEOW_PS_DIR=$PS MEOW_BL_DIR=$BL MEOW_NET_DIR=$NET MEOW_RFKILL_DIR=$RF MEOW_BT_DIR=$BT
MEOW_NETDEV=$T/netdev MEOW_PROC_STAT=$T/proc_stat MEOW_BOOT_MODE=$T/boot_mode
MEOW_PM_MODEL=$T/model.conf MEOW_AUDIO_SOCK=$T/no_audio.sock MEOW_PM_SOCK=$T/pm.sock"
ln -sf "$(readlink -f "$BIN")" "$T/meow_power" # argv[0] 双形态
# ---- T1: 守护直读(无守护 → 降级直读) ----
OUT=$(env $ENVS $Q "$T/meow_power" status 2>/dev/null)
ck T1a "state=Discharging cap=94%" "$OUT"
echo "$OUT" | grep -q "mv=4275" && { PASS=$((PASS+1)); echo "PASS T1b mv"; } || { FAIL=$((FAIL+1)); echo "FAIL T1b: $OUT"; }
ck T1c "health=Good" "$OUT"
ck T1d "charger_temp=30.0C" "$OUT"
ck T1e "rate=null" "$OUT"
ck T1f "src=direct" "$OUT"
# ---- T2: 起守护,IPC 路径 ----
env $ENVS MEOW_PM_SAMPLE_SEC=1 MEOW_PM_MIN_SPAN_SEC=2 $Q "$BIN" --sock "$T/pm.sock" >"$T/daemon.log" 2>&1 &
DPID=$!
for i in $(seq 1 30); do [ -S "$T/pm.sock" ] && break; sleep 0.2; done
[ -S "$T/pm.sock" ] || { echo "FAIL T0: daemon socket 未出现"; cat "$T/daemon.log"; exit 1; }
PASS=$((PASS+1)); echo "PASS T0 daemon up"
OUT=$(env $ENVS $Q "$T/meow_power" status 2>/dev/null)
ck T2a "src=daemon" "$OUT"
ck T2b "cap=94%" "$OUT"
ck T2c "mode=meow" "$OUT"
# ---- T3: 容量差分速率(94→93,span≥2s)→ rate/est_left=derived ----
echo 93 > "$PS/battery/capacity"
sleep 4
OUT=$(env $ENVS $Q "$T/meow_power" status 2>/dev/null)
ck T3a "conf=derived" "$OUT"
ck T3b "est_left=" "$OUT"
echo "$OUT" | grep -q "rate=-" && { PASS=$((PASS+1)); echo "PASS T3c 放电速率为负"; } || { FAIL=$((FAIL+1)); echo "FAIL T3c: $OUT"; }
# ---- T4: estimate(模型合成;中档背光+面板+wifi idle+bt off+audio unknown) ----
OUT=$(env $ENVS $Q "$T/meow_power" estimate 2>/dev/null)
ck T4a "confidence=estimated" "$OUT"
ck T4b "待真机标定" "$OUT"
ck T4c "backlight=450" "$OUT" # 49% → 中档 450
ck T4d "panel=80" "$OUT"
ck T4e "bt=0(off)" "$OUT" # rfkill soft=1 → off
ck T4f "audio=0(unknown)" "$OUT" # 无 audiod → unknown 0mW
# est_mw = 300(base)+450+80+200(wifi idle)+0+0+cpu(0,静态proc_stat)=1030
ck T4g "est_mw=1030" "$OUT"
# ---- T5: wifi 传输档(netdev 增量 >4096/拍 → tx=600) ----
sed -i 's/wlan0: 1000000/wlan0: 1999999/; s/ 2000000 / 2999999 /' "$T/netdev"
sleep 3
OUT=$(env $ENVS $Q "$T/meow_power" estimate 2>/dev/null)
ck T5a "wifi=600(tx)" "$OUT"
# ---- T6: 息屏(actual_brightness=0)→ 背光/面板归零 ----
echo 0 > "$BL/actual_brightness"
OUT=$(env $ENVS $Q "$T/meow_power" estimate 2>/dev/null)
ck T6a "backlight=0" "$OUT"
ck T6b "panel=0" "$OUT"
echo 50 > "$BL/actual_brightness"
# ---- T7: 模型 conf 覆盖 ----
printf '# test\nbaseline_mw=999\nwifi_idle_mw=111\n' > "$T/model.conf"
OUT=$(env $ENVS $Q "$T/meow_power" model 2>/dev/null)
ck T7a "baseline_mw=999" "$OUT"
ck T7b "wifi_idle_mw=111" "$OUT"
ck T7c "bl_high_mw=900" "$OUT" # 未覆盖键留默认
rm -f "$T/model.conf"
# ---- T8: HibyOS 只读降级(不施估算;电池仍可读) ----
echo hiby > "$T/boot_mode"
sleep 2 # 等守护下一拍热切换
OUT=$(env $ENVS $Q "$T/meow_power" estimate 2>/dev/null)
ck T8a "HibyOS 只读模式" "$OUT"
OUT=$(env $ENVS $Q "$T/meow_power" status 2>/dev/null)
ck T8b "cap=93%" "$OUT" # 只读模式电池采样不受影响
ck T8c "mode=readonly" "$OUT"
echo meow > "$T/boot_mode"
sleep 2
OUT=$(env $ENVS $Q "$T/meow_power" estimate 2>/dev/null)
ck T8d "est_mw=" "$OUT" # 热切换回全功能
# ---- T9: CLI 桩(期 2/3) ----
OUT=$(env $ENVS $Q "$T/meow_power" history 2>&1); RC=$?
ck T9a "期 2" "$OUT"
[ $RC -eq 1 ] && { PASS=$((PASS+1)); echo "PASS T9b rc=1"; } || { FAIL=$((FAIL+1)); echo "FAIL T9b rc=$RC"; }
OUT=$(env $ENVS $Q "$T/meow_power" policy 2>&1)
ck T9c "期 3" "$OUT"
# ---- T10: meow_powermgr 名直调子命令也走 CLI ----
OUT=$(env $ENVS $Q "$BIN" model 2>/dev/null)
ck T10a "nominal_mah=1600" "$OUT"
# ---- T11: 守护停 → CLI 自动降级直读不崩 ----
kill $DPID 2>/dev/null; wait $DPID 2>/dev/null; DPID=""
sleep 1
OUT=$(env $ENVS $Q "$T/meow_power" status 2>/dev/null)
ck T11a "src=direct" "$OUT"
ck T11b "cap=93%" "$OUT"
# ---- T12: audiod 在场时音频链分量(真 audiod 二进制当桩:无 HELLO 直接 QUERY 协议) ----
AUDIOD_BIN=../meow_audiod/meow_audiod_host
[ -n "$Q" ] && AUDIOD_BIN=../meow_audiod/meow_audiod
if [ -x "$AUDIOD_BIN" ]; then
env MEOW_AUDIO_FORCE=1 MEOW_AUDIO_SOCK="$T/audio.sock" MEOW_AUDIO_OUT="$T/a.wav" \
MEOW_AUDIO_SINK=null $Q "$AUDIOD_BIN" --sock "$T/audio.sock" >"$T/audiod.log" 2>&1 &
APID=$!
for i in $(seq 1 30); do [ -S "$T/audio.sock" ] && break; sleep 0.2; done
env $ENVS MEOW_AUDIO_SOCK="$T/audio.sock" MEOW_PM_SAMPLE_SEC=1 MEOW_PM_MIN_SPAN_SEC=2 \
MEOW_PM_SOCK="$T/pm2.sock" $Q "$BIN" --sock "$T/pm2.sock" >"$T/daemon2.log" 2>&1 &
DPID=$!
for i in $(seq 1 30); do [ -S "$T/pm2.sock" ] && break; sleep 0.2; done
OUT=$(env $ENVS MEOW_AUDIO_SOCK="$T/audio.sock" MEOW_PM_SOCK="$T/pm2.sock" $Q "$T/meow_power" estimate 2>/dev/null)
ck T12a "audio=50(idle)" "$OUT" # audiod 在场无流 → 静态档 50
kill $DPID $APID 2>/dev/null; wait 2>/dev/null; DPID=""
else
echo "SKIP T12 (无 audiod 二进制 $AUDIOD_BIN)"
fi
echo "=============================="
echo "PASS=$PASS FAIL=$FAIL"
[ $FAIL -eq 0 ]
+2
View File
@@ -40,6 +40,8 @@ patch_v2/meow_crash/meow_crash|/usr/bin/meow_crash|62781084445e82351bcadbdadbe4c
patch_v2/meow_svc_perf/meow_svc_perf|/usr/bin/meow_svc_perf|7ea196de9d59ab8cbd1e26edb7762772|性能专项服务 M2.75(net_json 补 network 闭合括号,修 /api/system JSON 解析失败)
patch_v2/meow_audiod/meow_audiod|/usr/bin/meow_audiod|176c840d80c3e1161df0cb769185520d|独占音频守护 M2.97(+DAC 数字域电平表 rms/peak + 1s 监控日志 audio_monitor_<bootts>.log)
patch_v2/meow_audiod/meow_audio|/usr/bin/meow_audio|891ab26475ef9e9931bf9147d265dce4|audiod 用户侧 CLI M2.97(+monitor 实时电平表/文本电平条;status 补 rms/peak)
patch_v2/meow_powermgr/meow_powermgr|/usr/bin/meow_powermgr|469dddb74de424f7b9bc9c1ef597d69d|功耗管理专项服务期1(POWER_MANAGER_DESIGN:trigger=boot+HibyOS只读降级;权威充电链复用;经验模型待标定;IPC 0x00D0/D1)
patch_v2/meow_powermgr/meow_powermgr|/usr/bin/meow_power|469dddb74de424f7b9bc9c1ef597d69d|meow_powermgr 的 CLI 形态(同二进制双形态,argv[0]=meow_power 即 CLI:status/estimate/model,history/top/events/policy 期2/3桩)
# ---- 开机 init 脚本(etc/init.d,数字决定启动顺序,按文件名自然序)----
patch_v2/meow_sysui/S70meow_sysui|/etc/init.d/S70meow_sysui|e435affcb56499e5229728c6ae2524b9|sysui 自启 M2.85(launcher.conf enabled=1+迁移)