Files
H100PowerManger/scripts/sync-board-time.sh
T
zjk 5b8f0b1421 锂电池改用 BCU-MBMS CAN 协议按节点解析 + bcu_node 解析数据落库 + 板卡对时脚本
- pCCU/CanBms:按《04KT38电池BCU-MBMS通信(CAN)定义》重写解码,
  BmsStatus 单状态模型改为 BcuNodeStatus 多节点模型(0x10XX00YY,
  节点地址 01~36h),支持 0x0000 电压/电流/SOC/告警码、0x0001 单体
  电压、0x0002 单体温度、0x0003 继电器、0x0006 绝缘/端口电压、
  0x0010 告警位(附录1 中文码表)六类报文
- 平均单体温度偏移修正:协议文档 BYTE5 写"偏移0"有误,实测固件与
  最高/最低一致均带 -40℃ 偏移(实车 0x10020002 原始 68/69 减 40 后
  为 28/29℃,落在最低28~最高30区间内,按文档直读则超出物理范围)
- pCCU/DbStore:新增 bcu_node 解析数据表,锂电池 BMS 报文每帧落一行
  节点合成状态(原 comm_log 仅原始帧,BMS/CAN 帧此前不落 pCCU 库),
  buildReport 增加 BMS 记录数
- 快照/网页:BCU 按节点分组展示(告警位解析中文含义、数据 age),
  PM 状态报文锂电池/应急电池卡片
- pPowerManger:新增 iport 本地输入端口配置(UDP bind 延迟到
  OnStartUp 读取配置后执行,保证 iport/ccuhost/ccuport 生效),
  各 mission 文件补充注释
- test:CAN BCU 解码用例按新协议/新偏移更新(实车抓包 + 文档示例值),
  133 项全部通过
- docs:删除旧 BMS 协议(xlsx/20230324docx),归档 04KT38 BCU-MBMS
  CAN 定义、配电控制器通信协议 20260824、配电系统 CAN 通讯协议
- scripts:新增 sync-board-time.sh,223 板卡(RK3588)时间校正
  (本机为基准 + RTT 折半补偿对时,尽力写 RTC,支持 status/--time)
2026-09-01 12:58:33 +08:00

177 lines
6.7 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
#=======================================================================
# FILE: scripts/sync-board-time.sh
# DESC: 校正 223 板卡(RK3588,默认 192.168.0.223)的系统时间:以
# 本机时间(或 --time 指定时间)为基准,经 SSH 设置板卡系统时
# 钟,并尽力写入硬件时钟 (RTC)。板卡网络隔离无 NTP,用本脚本对时。
#
# 用法:
# ./scripts/sync-board-time.sh # 用本机时间校正板卡
# ./scripts/sync-board-time.sh status # 只查看时间与偏差
# ./scripts/sync-board-time.sh --time "2026-09-01 12:00:00"
# # 用指定时间校正(本地时区)
#
# 参数:
# --host <ip> 目标主机(默认 192.168.0.223)
# --user <user> 登录用户(默认 root)
# --time <str> 手动指定基准时间(date 可解析的格式,按本地时区解释)
# --keep-ntp 不执行 timedatectl set-ntp false
# --no-rtc 不写硬件时钟(跳过 hwclock --systohc)
# -h, --help 显示帮助
#
# 说明:
# - 需要 root 登录与免密 SSH(deploy.sh setup-ssh)。
# - 对时经 SSH 往返时延 (RTT) 折半补偿,精度约 ±0.1s(受网络抖动影响)。
# - 板卡若无可用 RTC,hwclock 失败仅告警;重启后时间可能回跳。
# - 对时会调整系统时钟,运行中的服务日志时间戳会跳变,属正常现象。
#=======================================================================
set -uo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
HOST="192.168.0.223"
USER="root"
SET_TIME=""
KEEP_NTP=0
NO_RTC=0
info() { printf '\033[1;36m[time]\033[0m %s\n' "$*"; }
ok() { printf '\033[1;32m[time]\033[0m %s\n' "$*"; }
warn() { printf '\033[1;33m[time]\033[0m %s\n' "$*"; }
err() { printf '\033[1;31m[time]\033[0m %s\n' "$*"; }
usage() {
sed -n '2,26p' "${BASH_SOURCE[0]}" | sed 's/^# \{0,1\}//'
exit 0
}
#-------------------------------------------------------------------
# 参数解析
#-------------------------------------------------------------------
ACTION=""
while [ $# -gt 0 ]; do
case "$1" in
--host) [ $# -ge 2 ] || { err "--host 需要参数"; exit 1; }; HOST="$2"; shift 2 ;;
--user) [ $# -ge 2 ] || { err "--user 需要参数"; exit 1; }; USER="$2"; shift 2 ;;
--time) [ $# -ge 2 ] || { err "--time 需要参数"; exit 1; }; SET_TIME="$2"; shift 2 ;;
--keep-ntp) KEEP_NTP=1; shift ;;
--no-rtc) NO_RTC=1; shift ;;
status|help|-h|--help) ACTION="$1"; shift ;;
"") shift ;;
*) err "未知参数: $1(见 help)"; exit 1 ;;
esac
done
[ -n "${ACTION}" ] || ACTION="sync"
SSH_TARGET="${USER}@${HOST}"
SSH="ssh -o BatchMode=yes -o ConnectTimeout=5"
#-------------------------------------------------------------------
# 读取板卡时间并测 RTT
# 输出: "<epoch>|<板卡可读时间> <t0> <t1>"(t0/t1 为本机采样时刻)
#-------------------------------------------------------------------
read_board_time() {
local t0 t1 out
t0="$(date +%s.%N)"
out="$(${SSH} "${SSH_TARGET}" 'date "+%s.%N|%F %T %Z"' 2>/dev/null)" || {
err "无法免密 SSH 到 ${SSH_TARGET}(先执行: ./scripts/deploy.sh setup-ssh)" >&2
return 1
}
t1="$(date +%s.%N)"
printf '%s %.3f %.3f\n' "${out}" "${t0}" "${t1}"
}
# 从 read_board_time 输出解析: set -- <out> 后取 $1/$2/$3
parse_board_time() {
B_EPOCH="${1%%|*}"
B_DATE="${1#*|}"
T0="$2"
T1="$3"
MID="$(awk -v t0="${T0}" -v t1="${T1}" 'BEGIN{printf "%.3f", t0 + (t1-t0)/2}')"
DIFF="$(awk -v b="${B_EPOCH}" -v m="${MID}" 'BEGIN{printf "%+.3f", b - m}')"
}
#-------------------------------------------------------------------
# 命令: status
#-------------------------------------------------------------------
cmd_status() {
local out
out="$(read_board_time)" || return 1
parse_board_time ${out}
local rtt
rtt="$(awk -v t0="${T0}" -v t1="${T1}" 'BEGIN{printf "%.3f", t1-t0}')"
printf '本机时间: %s (RTT %.3fs)\n' "$(date -d "@${MID}" '+%F %T')" "${rtt}"
printf '板卡时间: %s\n' "${B_DATE}"
printf '偏差: 板卡比本机快 %s 秒\n' "${DIFF}"
}
#-------------------------------------------------------------------
# 命令: sync(默认)
#-------------------------------------------------------------------
cmd_sync() {
local out target board_reply
# 前置检查:SSH 连通 + 板卡 root 权限
out="$(read_board_time)" || return 1
parse_board_time ${out}
if ! ${SSH} "${SSH_TARGET}" '[ "$(id -u)" = 0 ]' 2>/dev/null; then
err "板卡登录用户需要 root 权限(当前 --user ${USER})"
return 1
fi
ok "SSH 连接正常: ${SSH_TARGET}"
info "当前偏差: 板卡比本机快 ${DIFF} 秒"
# 关闭 NTP 自动同步(板卡网络隔离本就无 NTP 源,防止干扰手动对时)
if [ "${KEEP_NTP}" = "0" ]; then
info "关闭板卡 NTP 自动同步 (timedatectl set-ntp false) ..."
${SSH} "${SSH_TARGET}" "command -v timedatectl >/dev/null 2>&1 && timedatectl set-ntp false || true"
fi
# 计算目标时间:手动指定值直接用;否则取本机时间 + RTT/2 补偿
if [ -n "${SET_TIME}" ]; then
target="$(date -d "${SET_TIME}" '+%s.%N' 2>/dev/null)" || {
err "无法解析时间: ${SET_TIME}"; return 1;
}
info "基准时间(手动): ${SET_TIME}"
else
local t2
t2="$(date +%s.%N)"
target="$(awk -v t2="${t2}" -v t0="${T0}" -v t1="${T1}" 'BEGIN{printf "%.3f", t2 + (t1-t0)/2}')"
info "基准时间(本机 + RTT/2 补偿)"
fi
info "设置板卡系统时间 -> $(date -d "@${target}" '+%F %T') ..."
board_reply="$(${SSH} "${SSH_TARGET}" "date -s @${target} 2>&1")" || {
err "date -s 失败: ${board_reply}"
return 1
}
ok "板卡返回: ${board_reply}"
# 写硬件时钟(无 RTC 时仅告警)
if [ "${NO_RTC}" = "0" ]; then
info "同步硬件时钟 (hwclock --systohc) ..."
if ${SSH} "${SSH_TARGET}" "hwclock --systohc" 2>/dev/null; then
ok "RTC 已同步"
else
warn "hwclock 失败(板卡可能无 RTC 或驱动未加载),重启后时间可能回跳"
fi
fi
# 校验
out="$(read_board_time)" || return 1
parse_board_time ${out}
info "校正后偏差: 板卡比本机快 ${DIFF} 秒"
ok "板卡时间: ${B_DATE}"
}
#-------------------------------------------------------------------
# 命令入口
#-------------------------------------------------------------------
case "${ACTION}" in
sync) cmd_sync ;;
status) cmd_status ;;
help|-h|--help) usage ;;
*) usage ;;
esac