GPS内部授时

功能说明

基于隐溪科技的MI-12x4平台,在设备内部集成安装H1xGPS模组转接板后,可以实现高精度授时。该方案利用GPS模组的PPS(秒脉冲) 信号与 GPRMC(或 GNRMC) 报文协同工作,将系统时间同步至 UTC 标准时间。

  • PPS 信号:通过独立的 GPIO 引脚接入,提供纳秒级精度的整秒时间基准,负责校准系统时钟的频率偏差与秒级边界。

  • GPRMC / GNRMC 报文:通过 USB 串口输出,提供当前的 UTC 年月日时分秒信息,负责为 PPS 提供绝对时间框架。

分工逻辑:PPS 负责“定秒边界”,GNRMC 负责“定日期时间”,二者结合实现亚毫秒级的高精度系统授时,工作原理如下图所示

H1xGPS
├── PPS  GPIO  /dev/pps1 (纳秒级秒基准)
└── NMEA  /dev/ttyCH341USB0  gpsd  SHM(0) (提供UTC日期时间)
                                                                                                           chrony融合
                                                                                                          系统时钟同步

关键特性

  • 高精度授时:依托 PPS 硬件秒脉冲,系统时间稳态误差可控制在 ±500ns 以内

  • 多系统兼容:支持 GPS、北斗(BDS)、GLONASS 等多星座联合定位(表现为GNRMC输出)

  • 抗网络依赖:冷启动后可完全脱离网络,依靠 GPS 卫星信号独立完成时间同步

  • 工业级稳定性:采用设备树(Device Tree)固化 PPS-GPIO 配置,避免重启后引脚失效,确保长期运行可靠

配置说明

硬件连接与基础检查

小技巧

接线要求:GPS 模组的 PPS 引脚需通过跳线连接至设备载板上指定的GPIO引脚

确认串口与PPS设备

  1. 设备启动后,通过确认GPS模组所使用的USB串口节点创建正常

ls /dev/ttyCH341USB0
  1. 检查pps设备已经创建成功

ls /dev/pps1          
  1. 测试 PPS 信号

使用 ppstest 工具验证内核是否能稳定捕获秒脉冲。若输出中序列号(sequence)持续递增,说明 PPS 信号正常。

sudo ppstest /dev/pps1

或者直接使用gpsd的命令解析消息

工作正常的返回结果如下

root@tegra-ubuntu:/home/nvidia# sudo ppstest /dev/pps1
trying PPS source "/dev/pps1"
found PPS source "/dev/pps1"
ok, found 1 source(s), now start fetching data...
source 0 - assert 1783697267.999999593, sequence: 4095 - clear  0.000000000, sequence: 0
source 0 - assert 1783697268.999999536, sequence: 4096 - clear  0.000000000, sequence: 0
source 0 - assert 1783697269.999999799, sequence: 4097 - clear  0.000000000, sequence: 0
source 0 - assert 1783697271.000001182, sequence: 4098 - clear  0.000000000, sequence: 0
source 0 - assert 1783697272.000000325, sequence: 4099 - clear  0.000000000, sequence: 0
source 0 - assert 1783697273.000000492, sequence: 4100 - clear  0.000000000, sequence: 0
source 0 - assert 1783697273.999999731, sequence: 4101 - clear  0.000000000, sequence: 0
source 0 - assert 1783697275.000000762, sequence: 4102 - clear  0.000000000, sequence: 0
source 0 - assert 1783697276.000000097, sequence: 4103 - clear  0.000000000, sequence: 0
source 0 - assert 1783697276.999999784, sequence: 4104 - clear  0.000000000, sequence: 0
source 0 - assert 1783697278.000000142, sequence: 4105 - clear  0.000000000, sequence: 0

说明:

  • assert:表示PPS上升沿(脉冲到来)的精确时间戳

  • sequence:脉冲的序列号,每次加1,用于检查是否丢失脉冲

  • 您会看到每秒稳定地输出一行,这表明PPS信号已被成功捕获

安装和配置gpsd

  1. 安装gpsd

apt update
apt install -y gpsd gpsd-clients
  1. 编辑配置文件

vim /etc/default/gpsd

输入内容如下;

START_DAEMON="true"
GPSD_OPTIONS="-n -G -b -s 115200"
DEVICES="/dev/ttyCH341USB0"
USBAUTO="false"
GPSD_SOCKET="/var/run/gpsd.sock"

注意

注意上述配置文件中的:

  • GPSD访问USB串口的波特率:115200需要参照H1xGPS模组的版本的当前的设置访问速率

  • -b 参数用于禁止 gpsd 自动探测波特率,防止频繁切换导致数据解析失败

  • DEVICES参数需指定正确的串口路径与波特率,并关闭自动扫描以避免冲突

  1. 验证 NMEA 输出

启动 gpsd 后,使用 cgps -s 或 gpspipe 查看解析结果。确保能看到有效的定位状态(如 3D FIX)和 UTC 时间。

gps-cgps

gpsd原生工具​查看NMEA的原始消息

gpspipe -w -n 10

或者使用更加直观的解析结果

cgps -s

时间同步服务配置

系统使用 chrony 融合 PPS 与 NMEA 数据,替代原有的 systemd-timesyncd。

  1. 安装chrony

sudo apt update
sudo apt install chrony
  1. chrony 配置

# 备份原配置
cp /etc/chrony/chrony.conf /etc/chrony/chrony.conf.bak

# 编辑新配置
vim /etc/chrony/chrony.conf

编辑 /etc/chrony/chrony.conf,添加以下参考时钟配置:

# ===== NTP 外网兜底(按需改地址)=====
server pool.ntp.org iburst
server time.google.com iburst

# GPS NMEA(通过gpsd写入SHM0)
refclock SHM 0 offset 0.0 delay 0.2 refid NMEA

# PPS(锁定NMEA的时间框架,避免跳变)
refclock PPS /dev/pps1 lock NMEA refid PPS precision 1e-9 poll 3 prefer

# 本地授时,无网络也可同步
local stratum 10

# GPS-only确保时间能更新
makestep 1.0 3

# 允许本机使用
allow 127.0.0.1

# 漂移记录
driftfile /var/lib/chrony/drift

# 日志
logdir /var/log/chrony
log measurements statistics tracking

配置说明:该配置优先选择PPS信号,若PPS信号不存在或丢失,会切换到NTP进行时间同步,如果PPS信号恢复,则切回到PPS

  1. 重新服务

重启并启用相关服务,确保开机自启。

systemctl restart gpsd
systemctl restart chrony
systemctl enable gpsd chrony

验证授时状态

通过以下命令确认系统是否已成功锁定 PPS 源:

  • 查看时间源

chronyc sources -v

若 PPS 行首显示 *,且 Last sample 偏移量在微秒级,说明 PPS 已成功驯服系统时钟。 alt text

  • 查看跟踪状态:

chronyc tracking

关注 Reference ID 应为 PPS,System time 偏差应趋近于 0。

nvidia@tegra-ubuntu:~$ chronyc tracking
Reference ID    : 50505300 (PPS)
Stratum         : 1
Ref time (UTC)  : Fri Jul 10 15:50:08 2026
System time     : 0.000000000 seconds fast of NTP time
Last offset     : -0.000000698 seconds
RMS offset      : 0.000000703 seconds
Frequency       : 29.148 ppm slow
Residual freq   : -0.019 ppm
Skew            : 0.029 ppm
Root delay      : 0.000000001 seconds
Root dispersion : 0.000013228 seconds
Update interval : 8.0 seconds
Leap status     : Normal
  • 查看统计信息:

chronyc sourcestats -v

若 PPS 行的 Offset 在 0ns 左右波动,Std Dev 小于 500ns,且 Frequency 趋近于 0.000 ppm,说明系统时钟已完全收敛。 alt text

无本地RTC电池的GPS-only系统授时

在设备没有安装RTC电池做硬时钟的情况下,仅依赖GPS进行设备授时。 在系统启动后的初期未获得GPS有效时间时,系统恢复到初始的1970的值,当GPS信号有效且获得GPRMC时间后,系统被正确授时

Last login: Thu Jan  1 00:00:43 1970
nvidia@tegra-ubuntu:~$ date
Thu Jan  1 12:00:55 AM UTC 1970
nvidia@tegra-ubuntu:~$ date
Thu Jan  1 12:00:57 AM UTC 1970
nvidia@tegra-ubuntu:~$ date
Thu Jan  1 12:00:59 AM UTC 1970
nvidia@tegra-ubuntu:~$ date
Thu Jan  1 12:01:00 AM UTC 1970
nvidia@tegra-ubuntu:~$ sudo su
[sudo] password for nvidia:
root@tegra-ubuntu:/home/nvidia# cat /etc/chrony/chrony.conf
# GPS NMEA(通过gpsd写入SHM0)
refclock SHM 0 offset 0.0 delay 0.2 refid NMEA

# PPS(锁定NMEA的时间框架,避免跳变)
refclock PPS /dev/pps1 lock NMEA refid PPS precision 1e-9 poll 3

# 本地授时,无网络也可同步
local stratum 10

# GPS-only确保时间能更新
makestep 1.0 3

# 允许本机使用
allow 127.0.0.1

# 漂移记录
driftfile /var/lib/chrony/drift

# 日志
logdir /var/log/chrony
log measurements statistics tracking
root@tegra-ubuntu:/home/nvidia# date
Mon Jul 13 12:03:15 PM UTC 2026
root@tegra-ubuntu:/home/nvidia# date
Mon Jul 13 12:03:21 PM UTC 2026
root@tegra-ubuntu:/home/nvidia#

常见问题

Q1 cutecom 无法打开串口,提示设备忙

  • 原因:gpsd 服务在后台占用了 /dev/ttyCH341USB0,Linux 串口不支持多进程同时读写。

  • 解决:调试前临时停止 gpsd 释放串口:sudo systemctl stop gpsd。调试完毕后记得重启服务。

Q2 cgps无数据,但串口有原始输出

  • 原因:最常见为波特率不匹配(如 GPS 模组为 115200,但 gpsd 默认按 9600 读取)。其次可能是 NMEA 语句不完整(如缺少 GGA 语句)或串口权限不足。

  • 解决:检查并统一波特率配置;确保模组输出包含有效定位(Status: A)的 RMC 和 GGA 语句;检查 /dev/ttyCH341USB0 的读写权限。

Q3 ppstest 无输出或超时

  • 原因:PPS 信号未接入、GPIO 引脚配置错误、设备树未生效或驱动未加载。

  • 解决:在检查GPS天线连接以及pps1设备节点已创建的情况下,检查pps1的中断判断系统是否接收到了来自GPS模块发出的PPS信号

root@tegra-ubuntu:/home/nvidia# cat /proc/interrupts | grep -i pps
222:       5965    0     0      0      0      0  c2f0000.gpio  19 Edge      pps.-1

正常情况下,我们可以观察到PPS的中断数量按照每秒递增

Q4 chrony 中 PPS 显示 ? 或 ~

  • 原因:NMEA 时间框架不可用,导致 PPS 无法完成首次锁定。通常是 GPS 尚未定位成功,或 NMEA 数据未通过 gpsd 写入 SHM。

  • 解决:将 GPS 天线移至室外空旷处,等待定位状态变为有效(A);使用 gpspipe 确认 gpsd 能正常解析到时间。

Q5 系统时间偶尔跳变

  • 原因:若设备连接了网络,系统可能同时尝试同步网络 NTP 服务器,导致时间源冲突。

  • 解决:在无网络环境下,此现象不应发生。若有网络需求,建议在 chrony.conf 中合理配置网络源的层级(stratum),确保 PPS(Stratum 1)优先级最高