时间同步已经完成

This commit is contained in:
2026-08-28 16:42:44 +08:00
parent 615a9b13e9
commit 4e9ac0d9c3
20 changed files with 771 additions and 1282 deletions

75
test/time_sync_server.py Normal file
View File

@@ -0,0 +1,75 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
本地时间同步服务PC -> MCU 板子)
功能:
周期性把本机PC的本地时间通过 TCP 推送到 STM32 板子。
板子端在 timeSyncTask 中以 TCP Server 方式监听端口,收到后调用
sys_clock_set_unix() 更新系统墙钟并写回 SD2506 RTC使板子时间 == 你电脑的时间。
协议(板子端实现见 App/time_sync.c 的 time_sync_handle_conn
字节 0..3 : 魔术字 "TIME" (0x54 0x49 0x4D 0x45)
字节 4..7 : 本地 Unix 时间戳uint32大端主机字节序转换后由板子分解
用法:
python time_sync_server.py # 默认推送到 192.168.1.100:8888
python time_sync_server.py 192.168.1.100 # 指定板子 IP
python time_sync_server.py 192.168.1.100 9000 3 # 指定端口与间隔(秒)
按 Ctrl+C 停止。
"""
import socket
import struct
import sys
import time
DEFAULT_MCU_IP = "192.168.1.100"
DEFAULT_PORT = 8888
DEFAULT_INTERVAL = 5.0
def main():
mcu_ip = sys.argv[1] if len(sys.argv) > 1 else DEFAULT_MCU_IP
port = int(sys.argv[2]) if len(sys.argv) > 2 else DEFAULT_PORT
interval = float(sys.argv[3]) if len(sys.argv) > 3 else DEFAULT_INTERVAL
print("[time_sync] 本地时间推送服务已启动TCP 客户端)")
print(f" 目标板子 : {mcu_ip}:{port}")
print(f" 推送间隔 : {interval}s")
print(f" 协议帧 : 'TIME' + uint32(BE) 本地 Unix 时间戳")
print("[time_sync] 按 Ctrl+C 停止")
print("-" * 48)
while True:
try:
# 本地 wall-clock 的 epoch与电脑显示一致板子按本地时间分解
local_epoch = int(time.mktime(time.localtime()))
pkt = b"TIME" + struct.pack(">I", local_epoch)
with socket.create_connection((mcu_ip, port), timeout=5) as sock:
sock.sendall(pkt)
# 关键:发送后保持连接打开,等板子读完再关。
# 若立即 closeCH395F 收到 FIN 会丢弃接收缓冲里尚未被板子读出的
# 8 字节时间包,导致板子 net_recv 看到 CLOSED 而无数据、时间同步失败。
# 这里 recv 直到板子主动关闭EOF或 2s 超时,确保板子先读到数据。
sock.settimeout(2.0)
try:
sock.recv(64)
except (socket.timeout, OSError):
pass
now_str = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
print(f"[{time.strftime('%H:%M:%S')}] -> {now_str} (epoch={local_epoch})")
except OSError as e:
print(f"[{time.strftime('%H:%M:%S')}] 连接/发送失败: {e}")
time.sleep(interval)
if __name__ == "__main__":
try:
main()
except KeyboardInterrupt:
print("\n[time_sync] 已停止")