查看“︁Photonicat 2 MCU 通讯协议”︁的源代码
←
Photonicat 2 MCU 通讯协议
跳转到导航
跳转到搜索
因为以下原因,您没有权限编辑该页面:
您请求的操作仅限属于该用户组的用户执行:
用户
您可以查看和复制此页面的源代码。
本页描述 '''Photonicat 2''' 主机(RK3576)与电源管理 MCU(Renesas RA2E1)之间的 串口通讯协议。协议同样适用于一代(RK3568),但一代的电压阈值是单节锂电语义, 详见下方"与一代的差异"。 相关页面:[[Photonicat 2 sysfs]](内核已经把电源/RTC 数据导出成标准接口, 一般应用'''不需要'''自己解析本协议)、[[Photonicat 2 SOC 计算]](状态帧里的 电量是怎么算出来的)、[[Photonicat 2 LED 指示灯]]、[[Photonicat 2 提示音说明]]。 == 先读这里:你可能不需要这个协议 == 绝大多数应用不应该直接收发本协议。主机侧已经有两层封装: {| class="wikitable" ! 你想做的事 !! 推荐用法 |- | 读电量/电压/电流/充电器状态 || <code>/sys/class/power_supply/*</code>,见 [[Photonicat 2 sysfs]] |- | 读写时间 || <code>hwclock</code> / <code>/dev/rtc</code>(MCU 就是硬件 RTC) |- | 风扇转速、温度 || <code>/sys/class/hwmon/*</code>、<code>/sys/class/thermal/*</code> |- | 网页界面里的各种设置 || pcat-manager 的 REST API,见 [[Photonicat 2 开发者 API]] |- | 上面都覆盖不到的功能 || 才需要本页的协议 |} 串口本身由内核驱动 <code>photonicat-pm</code> 和用户态守护进程 '''pcat-manager''' 占用。第三方程序直接抢串口会和它们冲突。 == 物理层 == * 串口,'''115200''' 波特率,8 数据位,无校验,1 停止位(8N1) * 主机侧设备:一代为 <code>/dev/ttyS4</code>;二代由设备树绑定给 <code>photonicat-pm</code> 驱动(serdev),不再以裸 tty 暴露 == 帧格式 == {| class="wikitable" ! 字节 !! 字段 !! 说明 |- | 0 || 起始位 || 固定 '''0xA5''' |- | 1 || 源地址 || 见地址表 |- | 2 || 目的地址 || 见地址表 |- | 3–4 || 帧序号 || 小端 uint16,主动发送方每发一帧加一,溢出回零;应答沿用请求的帧序号 |- | 5–6 || 数据长度 || 小端 uint16,指"命令号 + 命令内容 + 是否需要回复"三段的总字节数 |- | 7–8 || 命令号 || 小端 uint16 |- | 9… || 命令内容 || 变长,见各命令说明 |- | 倒数第 4 || 是否需要回复 || 1 = 需要应答,0 = 不需要 |- | 倒数第 3、2 || CRC16 || 对'''从字节 1 到"是否需要回复"为止'''的所有字节计算,小端 |- | 最后 1 || 结束位 || 固定 '''0x5A''' |} 一帧总长 = 数据长度 + 10。接收方据此校验,长度对不上直接丢弃。 === 地址表 === {| class="wikitable" ! 值 !! 含义 |- | 0x01 || 第一块 CPU 板(目前只有一块,主机固定用 0x01) |- | 0x02 / 0x03 || 第二、三块 CPU 板(预留) |- | 0x80 || 广播给所有 CPU 板 |- | 0x81 || 电源管理 MCU(RA2E1) |- | 0xFE || 广播给所有 RA2E1 |- | 0xFF || 广播给系统内所有设备 |} === 命令号约定 === '''奇数 = 请求,偶数 = 对应的应答'''(应答号 = 请求号 + 1)。这条规则贯穿整个 协议,MCU 内部就是按 <code>命令号 % 2</code> 来分发的。 == 命令一览 == === 基础与版本 === {| class="wikitable" ! 命令 !! 方向 !! 内容 !! 说明 |- | '''1''' / 2 || CPU → MCU || 无 || 心跳。超过 1 分钟没有收到任何数据,MCU 会重启主机 |- | '''3''' / 4 || CPU → MCU || 应答含 8 字节字符串 || 读硬件版本,例如 <code>NT2421A4</code> |- | '''5''' / 6 || CPU → MCU || 应答含 14 字节字符串 || 读软件版本,例如 <code>RA2E1260726005</code> |- | '''139''' / 140 || CPU → MCU || —— || 读硬件 ID |- | '''159''' / 160 || CPU → MCU || —— || 读 bootloader 版本号 |} === 状态上报(7) === '''MCU → CPU''',周期性主动上报,是整个协议里最重要的一帧。数据长度 56。 下表偏移量以'''命令内容'''首字节为 0(即整帧的字节 9): {| class="wikitable" ! 偏移 !! 长度 !! 字段 !! 单位 / 说明 |- | 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 个字段"的方式写,不要假设固定总长。 === 时间与定时开机 === {| class="wikitable" ! 命令 !! 方向 !! 内容 !! 说明 |- | '''9''' / 10 || CPU → MCU || 年(2) 月 日 时 分 秒,共 7 字节 || 设置 MCU 时间 |- | '''11''' / 12 || CPU → MCU || 见下 || 设置定时开机 |} 定时开机每条 8 字节:年(2) 月 日 时 分 星期,再加 1 字节匹配掩码。 掩码 bit0 年、bit1 月、bit2 日、bit3 时、bit4 分、bit5 星期, 置 1 表示该项参与匹配。'''分匹配必须为 1''',否则该条被忽略。 星期按位匹配,例如 <code>0b00000101</code> 表示周日和周二。 一次最多 6 条,覆盖之前的设置,故该段最长 48 字节。 === 关机与复位 === {| class="wikitable" ! 命令 !! 方向 !! 内容 !! 说明 |- | '''13''' / 14 || MCU → CPU || 1 字节关机事件 || MCU 通知主机即将关机 |- | '''15''' / 16 || CPU → MCU || 无 || 主机请求关机 |- | '''17''' / 18 || MCU → CPU || 无 || MCU 通知主机复位 |} 关机事件取值:0 按键强制关机,1 电池低电压关机,2 升级前关机,3 其他。 === 开机原因(27) === CPU → MCU 查询,应答 1 字节: {| class="wikitable" ! 值 !! 含义 |- | 1 || 按键开机 |- | 2 || 定时开机 |- | 3 || 车载模式:插入充电器开机 |- | 4 || 低电压关机后,插入充电器且电压满足条件开机 |- | 5 || 无电池开机 |- | 6 || 家庭模式:充电器电压满足条件开机 |} === 看门狗与电源策略 === {| class="wikitable" ! 命令 !! 方向 !! 内容 !! 说明 |- | '''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, 数值是'''整包'''电压: # 电压高指示阈值 # 电压中指示阈值 # 电压低指示阈值 # 插充电器开机电压 # 充电器在位判定电压 # 充电器不在时关机电池阈值 # 工作中低电压提示阈值 # 大电流充电电压阈值 # 开机后持续 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 提示音说明]]。 === 风扇 === {| class="wikitable" ! 命令 !! 方向 !! 内容 !! 说明 |- | '''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 %。 === 指示灯与声音 === {| class="wikitable" ! 命令 !! 方向 !! 内容 !! 说明 |- | '''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 提示音说明]]。 === 电池与充电 === {| class="wikitable" ! 命令 !! 方向 !! 内容 !! 说明 |- | '''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,全部小端: {| class="wikitable" ! 偏移 !! 长度 !! 字段 !! 说明 |- | 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 的 <code>/sys/kernel/photonicat-pm/movement_trigger</code>。 === MCU 固件升级 === 这一组命令由 pcat-manager 的升级工具使用,'''不建议手工调用'''—— 中断升级流程可能使 MCU 无法启动。正常升级方式见 [[Photonicat 2 MCU 手动更新]]。 {| class="wikitable" ! 命令 !! 说明 |- | '''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 <code>src/pmu-manager.c</code> * 主机侧内核:<code>photonicat-pm</code>(power_supply + RTC) * 一代参考:[https://github.com/photonicat/rockchip_rk3568_pcat_manager/blob/master/src/pmu-manager.c rockchip_rk3568_pcat_manager]
返回
Photonicat 2 MCU 通讯协议
。
导航菜单
个人工具
登录
命名空间
页面
讨论
大陆简体
查看
阅读
查看源代码
查看历史
更多
搜索
导航
首页
最近更改
随机页面
MediaWiki帮助
特殊页面
工具
链入页面
相关更改
页面信息