Photonicat 2 MCU 通讯协议

来自Photonicat Wiki
C2h2留言 | 贡献2026年7月26日 (日) 17:42的版本 (Create: full Photonicat 2 MCU UART protocol (frame format, status frame field table, battery info v9, charge limit, fan/thermal, beep, OTA))
(差异) ←上一版本 | 最后版本 (差异) | 下一版本→ (差异)
跳转到导航 跳转到搜索

本页描述 Photonicat 2 主机(RK3576)与电源管理 MCU(Renesas RA2E1)之间的 串口通讯协议。协议同样适用于一代(RK3568),但一代的电压阈值是单节锂电语义, 详见下方"与一代的差异"。

相关页面:Photonicat 2 sysfs(内核已经把电源/RTC 数据导出成标准接口, 一般应用不需要自己解析本协议)、Photonicat 2 SOC 计算(状态帧里的 电量是怎么算出来的)、Photonicat 2 LED 指示灯Photonicat 2 提示音说明

先读这里:你可能不需要这个协议

绝大多数应用不应该直接收发本协议。主机侧已经有两层封装:

你想做的事 推荐用法
读电量/电压/电流/充电器状态 /sys/class/power_supply/*,见 Photonicat 2 sysfs
读写时间 hwclock / /dev/rtc(MCU 就是硬件 RTC)
风扇转速、温度 /sys/class/hwmon/*/sys/class/thermal/*
网页界面里的各种设置 pcat-manager 的 REST API,见 Photonicat 2 开发者 API
上面都覆盖不到的功能 才需要本页的协议

串口本身由内核驱动 photonicat-pm 和用户态守护进程 pcat-manager 占用。第三方程序直接抢串口会和它们冲突。

物理层

  • 串口,115200 波特率,8 数据位,无校验,1 停止位(8N1)
  • 主机侧设备:一代为 /dev/ttyS4;二代由设备树绑定给
 photonicat-pm 驱动(serdev),不再以裸 tty 暴露

帧格式

字节 字段 说明
0 起始位 固定 0xA5
1 源地址 见地址表
2 目的地址 见地址表
3–4 帧序号 小端 uint16,主动发送方每发一帧加一,溢出回零;应答沿用请求的帧序号
5–6 数据长度 小端 uint16,指"命令号 + 命令内容 + 是否需要回复"三段的总字节数
7–8 命令号 小端 uint16
9… 命令内容 变长,见各命令说明
倒数第 4 是否需要回复 1 = 需要应答,0 = 不需要
倒数第 3、2 CRC16 从字节 1 到"是否需要回复"为止的所有字节计算,小端
最后 1 结束位 固定 0x5A

一帧总长 = 数据长度 + 10。接收方据此校验,长度对不上直接丢弃。

地址表

含义
0x01 第一块 CPU 板(目前只有一块,主机固定用 0x01)
0x02 / 0x03 第二、三块 CPU 板(预留)
0x80 广播给所有 CPU 板
0x81 电源管理 MCU(RA2E1)
0xFE 广播给所有 RA2E1
0xFF 广播给系统内所有设备

命令号约定

奇数 = 请求,偶数 = 对应的应答(应答号 = 请求号 + 1)。这条规则贯穿整个 协议,MCU 内部就是按 命令号 % 2 来分发的。

命令一览

基础与版本

命令 方向 内容 说明
1 / 2 CPU → MCU 心跳。超过 1 分钟没有收到任何数据,MCU 会重启主机
3 / 4 CPU → MCU 应答含 8 字节字符串 读硬件版本,例如 NT2421A4
5 / 6 CPU → MCU 应答含 14 字节字符串 读软件版本,例如 RA2E1260726005
139 / 140 CPU → MCU —— 读硬件 ID
159 / 160 CPU → MCU —— 读 bootloader 版本号

状态上报(7)

MCU → CPU,周期性主动上报,是整个协议里最重要的一帧。数据长度 56。 下表偏移量以命令内容首字节为 0(即整帧的字节 9):

偏移 长度 字段 单位 / 说明
0 2 电池电压 mV,小端
2 2 充电器接口电压 mV,小端
4 2 输入 GPIO 状态 位域
6 2 输出 GPIO 状态 位域
8 8 系统时间 年(2) 月 日 时 分 秒 星期,各 1 字节
16 1 RTC 状态 0 正常,1 初始化异常,2 无秒中断,3 无分钟中断
17 1 板子温度 实际温度 = 本字节 − 100(℃)
18 2 电池电流 mA,有符号小端。正 = 放电,负 = 充电
20 2 剩余容量 mAh
22 1 电量 %(1–100,算法见 Photonicat 2 SOC 计算
23 4 当前能量 mWh,小端
27 4 满电能量 mWh,小端(学习值,可与标称对比看老化)
31 4 累计开机时长 秒,小端
35 4 加速度 X 1/16384 g,有符号小端
39 4 加速度 Y 同上
43 4 加速度 Z 同上
47 1 加速度数据就绪 非 0 表示有效
48 4 风扇转速 RPM,小端
52 1 充电状态 0 未充电,1 小电流充电,2 大电流充电,3 已充满

向后兼容:这一帧只在尾部追加字段,从不改动已有偏移。解析时应按 "长度至少为 N 才读第 N 个字段"的方式写,不要假设固定总长。

时间与定时开机

命令 方向 内容 说明
9 / 10 CPU → MCU 年(2) 月 日 时 分 秒,共 7 字节 设置 MCU 时间
11 / 12 CPU → MCU 见下 设置定时开机

定时开机每条 8 字节:年(2) 月 日 时 分 星期,再加 1 字节匹配掩码。 掩码 bit0 年、bit1 月、bit2 日、bit3 时、bit4 分、bit5 星期, 置 1 表示该项参与匹配。分匹配必须为 1,否则该条被忽略。 星期按位匹配,例如 0b00000101 表示周日和周二。 一次最多 6 条,覆盖之前的设置,故该段最长 48 字节。

关机与复位

命令 方向 内容 说明
13 / 14 MCU → CPU 1 字节关机事件 MCU 通知主机即将关机
15 / 16 CPU → MCU 主机请求关机
17 / 18 MCU → CPU MCU 通知主机复位

关机事件取值:0 按键强制关机,1 电池低电压关机,2 升级前关机,3 其他。

开机原因(27)

CPU → MCU 查询,应答 1 字节:

含义
1 按键开机
2 定时开机
3 车载模式:插入充电器开机
4 低电压关机后,插入充电器且电压满足条件开机
5 无电池开机
6 家庭模式:充电器电压满足条件开机

看门狗与电源策略

命令 方向 内容 说明
19 / 20 CPU → MCU 3 字节:开机超时、关机超时、喂狗超时(秒) 设置软件看门狗时间
21 / 22 CPU → MCU 1 字节 0 = 插充电器不自动开机,1 = 插充电器开机。(低电压关机的机器即使设 0 也会开机)
157 / 158 CPU → MCU 1 字节 硬件看门狗开关
161 / 162 CPU → MCU 1 字节 设置设备模式(车载 / 家庭等)

电压阈值(23)

CPU → MCU,18 字节,9 个 uint16 小端。二代为 2S 电池组,单位 mV, 数值是整包电压:

  1. 电压高指示阈值
  2. 电压中指示阈值
  3. 电压低指示阈值
  4. 插充电器开机电压
  5. 充电器在位判定电压
  6. 充电器不在时关机电池阈值
  7. 工作中低电压提示阈值
  8. 大电流充电电压阈值
  9. 开机后持续 15 分钟判定满电的电压阈值

超出默认值 ±1000 mV 的设置视为无效,MCU 会退回默认值。

注意:一代文档里的 3850 / 3700 / 3600 等是单节数值。二代是 2S, 默认值不同(例如低电告警 6500、强制关机 6300),不要照搬一代的数字。 各阈值的实际效果见 Photonicat 2 LED 指示灯

温度阈值(145)

CPU → MCU,2 字节:

  • 第 1 字节:主机断电温度(℃),有效范围 55–80,默认 75
  • 第 2 字节:充电指示灯关闭温度(℃),有效范围 50–60,默认 53

超范围返回错误,不生效。温度过高触发断电时会播放提示音, 见 Photonicat 2 提示音说明

风扇

命令 方向 内容 说明
147 / 148 CPU → MCU 1 字节占空比(0–100) 主机直接接管风扇。一旦下发,MCU 内部的温控 PID 不再控制风扇;超过 100 返回错误
151 / 152 CPU → MCU 目标温度 设置风扇 PID 的目标温度,默认 47 ℃
153 / 154 CPU → MCU —— 读取当前目标温度

未被主机接管时,MCU 用增量式 PID 控制风扇:目标温度 47 ℃, 充电时占空比上限 85 %,纯电池运行时上限 40 %。

指示灯与声音

命令 方向 内容 说明
25 / 26 CPU → MCU 6 字节 设置网络指示灯:高电平时长(2)、低电平时长(2)、变换次数(2),时长单位 10 ms,次数 0 表示一直闪
155 / 156 CPU → MCU 1 字节 声光模式:0x00 全关,0x01 关声音开灯光,0x02 开声音关灯光,0x03 全开;传 0xFF 为查询当前值
163 / 164 CPU → MCU 见下 播放自定义蜂鸣器序列

自定义蜂鸣器序列(163)载荷格式:

 [步进 1][步进 2]…[步进 N][循环模式 1 字节]

每个步进 4 字节:频率 uint16 小端(Hz,0 = 休止)+ 时长 uint16 小端(ms)。 循环模式 0 = 播放一次,1 = 循环。时长为 0 会被当作 1 ms。 声音被关闭时该命令不执行。内置提示音见 Photonicat 2 提示音说明

电池与充电

命令 方向 内容 说明
165 / 166 CPU → MCU 1 字节百分比 设置充电上限,有效范围 50–100,100 = 不限制。超范围返回错误
167 / 168 CPU → MCU 应答 1 字节 读取当前充电上限
169 / 170 CPU → MCU 应答见下 读取电池详细信息
141 / 142 CPU → MCU 1 字节 已废弃,保留解析以兼容老主机,行为等同空操作

充电上限自固件 RA2E1260726005 起持久化在 MCU 侧,复位和 OTA 后不丢失。 到达上限后 MCU 断开充电 MOSFET,回落约 2 % 后恢复充电。

电池信息(169)应答格式

应答是逐版本向尾部追加的结构,当前长度 59 字节。偏移以应答的命令内容 首字节为 0,全部小端:

偏移 长度 字段 说明
0 2 学习到的满容量 mAh
2 2 循环次数 ——
4 2 标称满容量 mAh
6 1 标志位 bit0 = 容量为学习值,bit1 = 学习窗口进行中
7 2 内阻 mΩ,整包串联值,归一到 25 ℃
9 4 累计开机秒数 ——
13 2 电池中点电压 mV(2P2S 中心抽头)
15 2 内部 SOC ×10,显示修饰前
17 1 学习到的显示空点 %,0 = 未学习
18 2 显示变换 a ×1000
20 2 显示变换 b ×100,有符号
22 2 充电电流增益 ×1000
24 2 电流微调 a ×1000
26 2 电流微调 b mA,有符号
28 2 估算剩余容量 mAh
30 4 累计消耗能量 mWh
34 4 累计充入能量 mWh
38 1 协议版本号 当前 9
39 1 电池健康度 %,0xFF = 尚未学习
40 2 预计可用时间 分钟,0xFFFF = 非稳定放电
42 2 预计充满时间 分钟,0xFFFF = 非稳定充电
44 1 库仑计在用温度 ℃,有符号
45 1 低温空点上移 ×10 %,常温 = 0
46 2 内阻温度倍率 k(T) ×1000,25 ℃ = 1000
48 1 回路寄生电阻 mΩ(线缆+接插件+MOSFET)。电芯本体内阻 = 偏移 7 的值 − 本值
49 4 MCU 总运行秒数 自 MCU 复位起,看门狗/异常复位会清零
53 4 距上次休眠唤醒秒数 从未休眠则等于总运行秒数
57 2 进入待机次数 饱和计数

偏移 38 之前的版本靠应答长度区分(≥7、≥13、≥15、≥28、≥38…); 从版本 9 起有显式版本号字段,建议新代码优先读它。这些字段的物理含义见 Photonicat 2 SOC 计算

抬腕唤醒(149)

MCU → CPU 主动上报抬腕/移动事件。对应 sysfs 的 /sys/kernel/photonicat-pm/movement_trigger

MCU 固件升级

这一组命令由 pcat-manager 的升级工具使用,不建议手工调用—— 中断升级流程可能使 MCU 无法启动。正常升级方式见 Photonicat 2 MCU 手动更新

命令 说明
129 / 130 请求进入升级模式
203 / 204 开始 OTA
205 / 206 传送版本号
207 / 208 OTA 结束
209 / 210 回报"已收到结束"
211 / 212 传输 OTA 数据
213 / 214 接收就绪
215 / 216 长度校验正确
217 / 218、219 / 220 新区域拷贝到备份区 / 拷贝完成
221 / 222、223 / 224 擦除 SPI 最新区 / 备份区

错误上报(201)

MCU → CPU,用于上报解析或执行错误。

与一代的差异

  • 一代主机是 RK3568,二代是 RK3576
  • 一代是单节锂电,命令 23 的阈值是单节电压(3850 / 3700 / 3600 等);
 二代是 2S 电池组,同样的字段是整包电压(约为一代的两倍)
  • 一代只有命令 1–28;二代在 129 以上扩展了 ID、风扇、温度、声光、
 电池信息、充电上限等
  • 一代靠 pcat-manager 的 socket 对外提供数据;二代已集成进内核,
 推荐直接读 sysfs,见 Photonicat 2 sysfs

参考实现

  • 主机侧用户态:pcat-manager src/pmu-manager.c
  • 主机侧内核:photonicat-pm(power_supply + RTC)
  • 一代参考:rockchip_rk3568_pcat_manager