在电力自动化、轨道交通等工业控制场景中,嵌入式系统对时间同步精度要求极为严苛,通常需要将误差控制在1毫秒以内。这要求设备不仅需要可靠的外部对时机制,其本地时钟系统也必须具备良好的保持精度能力。因此,一套高效的校时方案至关重要。
常见的高精度时间源主要包括以下几种,实际应用中需根据场景的精度要求与实施条件进行选择:
- NTP服务器:通过网络协议获取时间。
- IRIG-B信号:通过专用接口接收来自时间服务器的IRIG-B时间码。
- GPS模块:通过串口接收GPS卫星发送的时间信息。
- 本地RTC:读取板载实时时钟芯片的时间。
一个典型的基于英创ESM7400工控主板的时钟系统构成如下图所示,它集成了多种时间源接口与本地RTC增强方案。

ESM7400高精度时钟系统连接示意图
英创工控主板的标准RTC方案已能满足一般应用。若对本地时钟的长期稳定性有更高要求,可如图中所示,外接RX-8025T等高精度温补时钟芯片,以获得更优的时间保持性能。
整个嵌入式系统的时间同步流程遵循一套严谨的逻辑,其典型流程如下图所示。

嵌入式系统时间同步典型流程图
英创工控主板通过软硬件协同,提供了保障系统时间精度的一系列方法,最高可实现系统时间与基准源的误差小于1毫秒。实现高精度的前提是具备可靠的基准时间信号源,如PPS、IRIG-B、NTP或GPS。
下面以ESM7400为例,阐述保持系统时间精度的基本软件流程:
- 系统启动初始化:上电后,首先从板载RTC芯片读取时间,用于初始化操作系统时间。
- 首次时间校准:应用程序启动后,主动从可用的高精度时间源(IRIG-B、NTP或GPS)获取标准时间,对系统时间进行一次有效校准。
- 持续微调同步:开启PPS秒脉冲同步线程,进行持续的高精度时间微调,可将精度提升至50微秒以内。此线程需持续运行。
- 回写RTC:定期(如每日1-2次)将校准后的精准系统时间回写至板载RTC,确保RTC自身时间的准确性。
- 执行应用任务:在稳定的高精度时间基础上,运行其他工业控制任务。
一、使用IRIG-B信号获取标准时间
ESM7400内核已集成IRIG-B解码驱动,简化了开发。使用时需将IRIG-B信号接入主板的GPIO15引脚。驱动提供了便捷的接口,示例代码如下:
#define IRIG_B_SET_SYSTIME 0x00
#define IRIG_B_SET_RTCTIME 0x01
int ret, i1, fd;
struct tm t;
fd = open("/dev/irig-b", O_RDWR); // 打开IRIG-B解码设备
i1 = IRIG_B_SET_SYSTIME; // 设置:获取IRIG-B时间并同步到系统时间
write(fd, &i1, sizeof(int));
i1 = IRIG_B_SET_RTCTIME; // 设置:获取IRIG-B时间并同步到外部RTC芯片(rtc0)
write(fd, &i1, sizeof(int));
ret = read(fd, &t, sizeof(struct tm)); // 仅读取IRIG-B时间数据
if(ret == 0)
printf("time:%d-%d-%d %d:%d:%d\n", t.tm_year, t.tm_mon, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec);
else
printf("irig-b get time failed!\n");

对于NTP与GPS协议,内核未提供专用驱动,需要在应用层实现协议解析。常见的公共NTP服务器地址有:
- 中国国家授时中心:
114.118.7.161
- 阿里云NTP:
118.31.3.89
二、使用PPS秒脉冲实现高精度同步
ESM7400内核内置了GPIO-PPS驱动,支持通过PPS(秒脉冲)信号实现极高精度的秒级同步,理论精度可达30微秒以内。PPS信号需接入GPIO8引脚。
该驱动的核心功能是提供精确的硬件时间戳并上报事件,实际的时间校正需要应用程序调用adjtimex()系统调用来完成。这涉及到对Linux系统时间机制的深入理解,相关的驱动开发和系统调优知识可以在运维/DevOps板块找到更多资料。基本应用流程如下:
- 打开PPS设备:
open("/dev/pps0", O_RDWR);
- 设置捕获参数:
ioctl(fd, PPS_SETPARAMS, ¶ms);
- 获取时间戳:
ioctl(fd, PPS_FETCH, &fdata);
- 校验数据并计算时间偏差。
- 调整系统时间:
adjtimex(&tx);
其中步骤3至5需要在独立的线程中循环执行,以实现持续同步。

PPS同步微调过程日志输出
上图为同步线程的日志输出,各字段含义如下:
- 序列:PPS脉冲的捕获序列号,连续递增表明信号捕获稳定。
- 系统时间:当前的系统时间(秒.纳秒)。
- PPS时刻:PPS脉冲在当前秒内到达的精确纳秒时刻。
- 偏移:系统时间相对于PPS脉冲的偏差(微秒),负值表示系统时间慢于PPS。
- 调整:系统已累计调整的时间量(微秒)。
三、无外部基准源时的RTC增强方案
在缺乏IRIG-B、NTP、GPS等外部基准源的场景下,系统时间完全依赖板载RTC。为了提升此时钟方案的精度与可靠性,可采用外接RX-8025T高精度时钟芯片的方案。
硬件上,通过I2C总线连接RX-8025T至ESM7400,并将RX-8025T产生的中断信号(与秒沿对齐)接入ESM7400的GPIO25引脚。配套驱动可定期将高精度RTC的时间同步到系统时间,默认每10秒同步一次。在晶振误差为20ppm的条件下,能保证系统时间与RTC的偏差小于300微秒。
启用此功能的代码如下:
#define RTC_TIMER_IRQ_CTRL_ON 0x5170
#define RTC_TIMER_IRQ_CTRL_OFF 0x5171
// 打开 RTC 设备
rtc_fd = open("/dev/rtc0", O_RDONLY);
// 使能RTC中断同步功能
ioctl(rtc_fd, RTC_TIMER_IRQ_CTRL_ON, 1);
// ... 程序运行 ...
// 关闭RTC中断同步功能
ioctl(rtc_fd, RTC_TIMER_IRQ_CTRL_OFF, 1);

该增强方案的硬件参考电路如下图所示:

RX-8025T外接电路原理图
本方案所占用主板资源及用途总结如下,合理规划这些GPIO和接口是嵌入式Linux网络/系统开发的基础:
| 主板资源 |
用途说明 |
| GPIO8 |
PPS秒脉冲信号输入 |
| GPIO15 |
IRIG-B时间码信号输入 |
| GPIO25 |
连接RX-8025T中断输出,需外接约10K上拉电阻 |
| GPIO26/27 |
I2C总线,与RX-8025T通信,需外接约4.7K上拉电阻 |
| 串口 |
接收GPS模块数据 |
| 网口 |
与NTP服务器进行网络通信 |