摘要:以工业控制领域中的SNTP时间同步协议为基础,对其工作过程及原理进行深入剖析,着重探讨了如何在Windows CE环境下实现时间同步,并给出相应的实现方案。最后给出了Windows CE环境下的SNTP协议栈运行结果。
关键词:SNTP;时间同步;Windows CE
中图分类号:TP273文献标识码:A文章编号:1009-3044(2008)11-20228-04
1 引言
控制网络的“实时性”已成为目前工控领域的重中之重,通信系统必须保证传输实时性的确定性、精确性和稳定性。也就是说工业现场设备向网络上发送数据都必须遵循严格的时序,这就要求具有在所有通信设备之间实现精确时间同步的能力。简单网络时钟同步协议(SNTP)是目前在工控领域中广泛使用的、对终端及工作站进行时间同步控制的协议,它是一个简化了的NTP服务器和NTP客户端的协议,不需要实现NTP协议的所有功能,因此极大地简化了控制过程中复杂的时间控制,节约了运行空间和成本。在现场设备上运行SNTP协议栈是为了使在控制网络内的其它设备的系统时钟与标准的时钟源保持同步,其同步精度一般可达到1-50ms。本文在深入分析SNTP协议的工作原理的基础上,着重探讨了如何在WinCE环境下实现时间同步的方案,实现了各个设备终端与标准的时钟源保持同步。最后给出了WinCE环境下的SNTP协议栈的运行结果。
2 SNTP协议的工作原理
为实现现场设备间的时间同步,每个设备自上电初始化起便周期性地向系统时间服务器发出时间同步的请求,通过时间服务器的响应来保持设备的本地时间和系统时间的一致。
(1)现场设备A(客户端)发送一个SNTP包给现场设备B(服务器端),该包带有它离开现场设备A的时间戳,该时间戳为T1。
(2)当此SNTP包到达现场设备B时,现场设备B加上自己的时间戳,该时间戳为T2。
(3)当此SNTP包离开现场设备B时,现场设备B再次加上自己的时间戳,该时间戳为T3。
(4)当现场设备A接收到该响应包时,加上一个新的时间戳,该时间戳为T4。
整个同步过程如图1所示。
因为SNTP协议简化了NTP协议的复杂的时间控制,所以整个同步过程实际上只需两步:一个SNTP包从一个现场设备发送到另一个现场设备,然后又回到原来那个现场设备,只不过SNTP包在发送和接收时都要加上当前时间戳。所以共有四个时间戳,如表1所示。
至此,作为客户端的现场设备A已拥有足够的信息来计算两个重要的参数:一是SNTP数据包在服务器端和客户端之间往返的时间延迟RoundTripDelay,二是现场设备A和现场设备B的时钟差即偏离时间Offset。由此现场设备A能够设定自己的时钟与现场设备B同步。可以根据如下公式算出现场设备A与现场设备B之间的时间差。
RoundTripDelay =(T4-T1)-(T3-T2)
=(DestinationTimestamp - OriginateTimestamp)
-(TransmitTimestamp- ReceiveTimestamp)
Offset = T2-T1- RoundTripDelay/2
= T2-T1-((T4–T1)-(T3-T2))/2
=((T2-T1)+(T3-T4))/2
=((ReceiveTimestamp - OriginateTimestamp)
+(TransmitTimestamp - DestinationTimestamp))/2
用偏离时间Offset与现场设备A进行时间补偿,就可以精确地对现场设备A进行时间校正。在这个过程中,假设传输介质是对称均匀的。
3 SNTP协议在Windows CE环境下的实现
3.1 SNTP时间报文格式的定义
在服务器端与客户端程序中都涉及到SNTP时间报文发送和接收,SNTP时间报文的格式由SntpPacket结构来表示,其具体定义如下:
struct SntpPacket
{
BYTE m_LiVnMode;
BYTE m_Stratum;
char m_Poll;
char m_Precision;
long m_RootDelay;
long m_RootDispersion;
char m_ReferenceID[4];
CSntpTimePacket m_ReferenceTimestamp;
CSntpTimePacket m_OriginateTimestamp;
CSntpTimePacket m_ReceiveTimestamp;
CSntpTimePacket m_TransmitTimestamp;
};
3.2 CSntpTime类的定义
因为GMT和UTC两种时间格式不一致以及对时间偏差进行计算,需要在CSntpTime类中定义SNTP时间报文的转换函数以及对时间运算的运算符重载函数等。它的定义描述如下:
class CSntpTime
{
public:
CSntpTime();
CSntpTime(const CSntpTime& time);
CSntpTime(CSntpTimePacket& packet);
CSntpTime(const SYSTEMTIME& st);
CSntpTime& operator=(const CSntpTime& time);
double operator-(const CSntpTime& time)const;
CSntpTime operator+(const double& timespan)const;
operator SYSTEMTIME()const;
operator CSntpTimePacket()const;
operator unsigned_int64()const { return m_Time; };
DWORD Seconds()const;
DWORD Fraction()const;
static CSntpTime GetCurrentTime();
static DWORD MsToSntpFraction(WORD wMilliSeconds);
static WORD SntpFractionToMs(DWORD dwFraction);
static double SntpFractionToSecond(DWORD dwFraction);
protected:
static long GetJulianDay(WORD Year, WORD Month, WORD Day);
static void GetGregorianDate(long JD, WORD& Year, WORD& Month, WORD& Day);
static DWORD m_MsToNTP[1000];
unsigned_int64 m_Time;
};
3.3 服务器端的报文收发模块的流程
服务器端的报文发送模块如图2所示,设备上电并调用InitServer()函数初始化本地的一些属性值,然后从标准时间源获取时间并赋值给服务器的本地时间。然后监听控制网络上的报文,如有报文来的话,首先调用接收函数MonitorRecv (),此函数调用UdpRecv()进行接收、并通过同步信息标志是否为1来判断是否是包含有同步时间信息的同步报文。如果不是,则丢弃重新监听;如果是,则将收到的报文时的时间记下来作为T2,然后从报文中解析出的时间戳T1,再将T1、T2封装成新的报文进行发送,发送时记录一个发送时间T3,调用函数MonitorSend(),此函数调用了UdpSend()函数发送至客户端。通过这个模块流程,就可以把报文到达以及两次发送时间记录下来。
3.4 客户端的报文收发模块的流程
同样,在客户端设备上电并调用InitClient()函数初始化本地的一些属性值,其报文模块调用函数ClientSntpSocket类里的成员函数SockInit()来完成了建立套接口、初始化IP等工作。客户端的报文收发过程则和服务器端的过程相反。首先是对设备的状态进行判断,如果发送状态,则开始一个主动的发送时间报文的过程,即调用GetCurrentTime()函数,记录下当前的时间戳并封装好再加上一些认证信息再发送;如果是已经发出了报文,则客户端设备应处于接收状态,准备接收同步报文。整个流程如图3所示。
另外,在CSntpClient类中存在一个GetServerTime()函数,客户端可以通过这个函数从时间服务器获取response报文中的四个时间戳,从而计算出与服务器系统时间的偏差并修正本地时间。
3.5 时间同步模块在Windows CE环境下的实现
首先创建定制的操作系统镜像文件(Image),在Windows CE开发工作区启动Platform Builder应用程序,应用平台向导创建并配置基本平台。其中目标设备的BSP选择为EMULATOR-X86。然后编译操作系统镜像文件,在平台配置列表中选择ClockSyn-EMULATOR:X86 Win32 Debug;在编译选项中选中Enable Full Kernel Mode复选框,设置新的环境变量IMGRAM64,进行编译。接下来与仿真器建立连接并下载操作系统镜像文件,在配置远程连接的过程中,Services for active named connection下的Download框中选择Emulator,Kernel Transport框中选择Emulator,进行配置连接并下载。当操作系统成功启动后,Windows CE操作系统界面就会出现ClockSyn-Emulator for Windows CE窗口中。
接着断开PB与目标设备的连接,在Platform菜单中选择Configure SDK选项,应用Export SDK Wizard工具完成平台SDK的生成与导出。本工程SDK的导出如图4所示。
SDK导出后就开始为仿真器添加并编译应用程序,在PB集成开发环境中的Target菜单中选择Disconnect以断开连接,关闭仿真器窗口。在eMbedded Visual C++中添加时间同步客户端和服务器端程序并编译。
在定制的操作系统镜像仿真器中运行应用程序,在Windows CE窗口中选择Run Programs,运行已编译成功的EPA时间同步客户端和服务器端程序。在任务栏中选择ClockSyn-Emulator for Windows CE来查看运行中的时间同步应用程序,如图5所示。
4结束语
本文详述了控制网络中的SNTP时间同步协议的工作原理,在此基础上讨论了基于SNTP的时间同步机制在Windows CE环境下的实现方法。通过对终端的时间同步控制,有效地解决了工控领域中现场设备的同步问题,具有一定的现实意义。
参考文献:
[1] 简单网络时间协议(SNTP)[S].(RFC1769 ——Simple Network Time Protocol).
[2] 过晓冰,伍卫国.Windows CE及其开发工具[J].计算机工程,2000,(9).
[3] 陈向群,王雷,马洪兵,等.Windows CE.NET系统分析及实验教程[M].机械工业出版社,2003.
[4] Douglas Boling.Microsoft Windows CE程序设计[M].北京大学出版社,1999.
[5] 谢聪敏.基于Windows CE.NET的嵌入式控制系统[J].国内外机电一体化技术,2003,(6).
注:本文中所涉及到的图表、注解、公式等内容请以PDF格式阅读原文