在HPM6700/6400系列微控制器上,提供了2个以太网控制器。都可以支持IEEE1588-2002和IEEE1588-2008标准。方便用户实现基于网络的精确时间同步。
本文提供了与HPM6700/6400系列微控制器基于网络的IEE1588的功能示例和使用指南。
IEEE1588简介
IEEE1588的全称是网络测量和控制系统的精密时钟同步协议标准(PTP – Precision Time Protocol)。目前为2个版本,分别为IEEE1588(v1)和IEEE1588(v2)。IEEE1588的目的是为了对全网设备时钟同步,这对于网络设备在控制和采集同步尤为重要。本节简单介绍IEEE1588的基础知识,详细的协议描述,请参考相关网站。
1588的同步原理
1588的原理是通过网络中的主设备对从设备发送特殊的报文并以此和从设备进行交互得出时间的偏离以进一步将设备时钟同步。如下图所示:
主端口在t1时刻发送同步报文,并在接下来的报文中发送t1点的时间,从端口在t2时间点收到同步报文并在t3时刻发送响应给主端口,主端口在收到从端口的响应后再将t4时刻发送给从端口。
在这个过程中,得到网络延迟和时钟偏差。
Toffset = ((t2 - t1) + (t4 – t3)) / 2
Tdelay = ((t4 - t1) - (t3 – t2)) / 2
在整个网络拓扑中,所有的节点定期的进行时钟同步,最终达到纳秒(IEEE1588-2008)或者微秒级(IEEE1588-2002)的精度。
HPM67/64系列1588功能介绍
IEEE1588本身是基于以太网提出的,因此其详细使用以及寄存器描述请参见HPM6700/6400用户手册的第60章。
使用1588功能,首先要为该功能赋予时钟源。因为HPM6700/6400有2个以太网控制器,ENET0, ENET1。因此,控制器为1588设立了2个时钟源,分别为:
CLOCK_TOP_PTP0;
CLOCK_TOP_PTP1。
HPM6700/6400微控制器上,CLOCK_TOP_PTP0/1分别作为ENET0/1的1588时间戳计数器的运行时钟,其默认频率选择是使用PLL1CLK1输出, PLL1CLK1的默认输出为400MHz,默认时钟分频系数为4,因此CLOCK_TOP_PTP0/1的默认频率为100MHz。用户可以根据自己的需要设置成不同的频率作为输入。
clock_set_source_divider(clock_ptp0, clk_src_pll1_clk1, 4);
clock_set_source_divider(clock_ptp1, clk_src_pll1_clk1, 4);
用户需要设置以下几个寄存器来实现相应的1588功能
TS_CTRL 时间戳控制寄存器
SUB_SEC_INCR 次-秒增量寄存器
SYST_SEC 系统时间 – 秒寄存器
SYST_NSEC 系统时间 – 纳秒寄存器
SYST_SEC_UPD 系统时间 – 秒更新寄存器
SYST_NSEC_UPD 系统时间 – 纳秒更新寄存器
TS_ADDEND 时间戳加法寄存器
当确定好输入频率后,用户需要在SUB_SEC_INCR中填写增量值。它的填写主要依靠2个因素,一个是TS_CTRL中的第9位TSCTRLSSR,另一个因素是前面提到的输入频率。
TSCTRLSSR是计数方式的选择,当其置1时,SYS_NSEC纳秒寄存器到0x3B9AC9FF时翻转;当其置0时,SYS_NSEC纳秒寄存器到0x7FFFFFFF时翻转。SYS_NSEC每翻转一次代表时间上的1秒钟。因此,当TSCTRLSSR置1时,SYS_NSEC中的1代表1ns;当TSCTRLSSR置0时,SYS_NSEC中的1代表0.465ns。SUB_SEC_INCR.SSINC中的数代表着输入频率所对应的时间,它会根据SYS_NSEC中1个计数所代表的时间进行相应的折算。
例如,当输入频率为100MHz时,一个clock是10ns,当TSCTRLSSR置1时,则SUB_SEC_INCR.SSINC设为10(10/1);当TSCTRLSSR置0时,则SUB_SEC_INCR.SSINC设为21(10/0.465)。
建议用户将TSCTRLSSR置1,这样理解和计算都更方便。
SYST_SEC和SYST_NSEC为MAC维护的时间戳。SYST_SEC为秒级时间戳,SYST_NSEC为纳秒级时间戳。其中SYS_NSEC会根据TSCTRLSSR的设置在不同的数据下翻转。当TSCTRLSSR置1时,它将会在0x3B9AC9FF时翻转,当TSCTRLSSR置0时,它将会在0x7FFFFFFF时翻转。
SYST_SEC_UPD和SYST_NSEC_UPD为更新时间戳的寄存器,如果需要减少纳秒时间,需要将SYST_NSEC_UPD中的最高位置1,如果需要增加纳秒时间则需要将SYST_NSEC_UPD中的最高位置0。
假设时钟同步算法发现时钟偏慢,希望将累加的步长调整为10.1 ns,这时,可以保持SUB_SEC_INCR.SSINC为10,设置ADDEND = 0xFFFFFFFF * (0.1) = 0x19999999。此时,可以视为累加的等效步长为10.1 ns。
假设时钟同步算法发现时钟偏快,希望将累加的步长调整为9.9 ns,这时,需要设置SUB_SEC_INCR.SSINC为 9,设置ADDEND = 0xFFFFFFFF * (0.9) = 0xE6666666。此时,可以视为累加的等效步长为9.9 ns。
注意,以上所有的寄存器的写入都是需要通过设置TS_CTRL中相应的状态位为1,等待此位为0时,认为设置成功。
在先楫提供的SDK中,可以直接调用
../../hpm_sdk/drivers/src/hpm_enet_drv.c进行设置
void enet_init_ptp(ENET_Type *ptr, enet_ptp_config_t *config)
void enet_set_ptp_timestamp(ENET_Type *ptr, enet_ptp_time_t *timestamp)
1588例程分析
在先楫发布的SDK中,可以找到1588的实现例程v1(即IEEE1588-2002)
..\..\hpm_sdk\samples\lwip\lwip_ptp\v1
其中包括master和slave, 分别对应主端口和从端口。在不改动任何设置的情况下,用户需要2块进行测试,一块作为主端口,另一块作为从端口。为了测试IEEE1588的时钟同步性能,我们采用了2块HPM6750EVK,分别烧写master和slave的程序。
需要注意一下2块板子的ip地址应该是不同的。默认的例程使用的是板子上的RMII PHY,用户可以根据自身的需求更换成RGMII PHY进行测试。
1. 代码分析
初始化系统,首先初始化IO,以太网芯片以及设置1588的时钟。
board_init();
board_init_enet_ptp_clock(ENET);
board_init_enet_pins(ENET);
enet_init(ENET);
在初始化以太网芯片成功后,初始化lwip,设置网络参数,ptp时钟
enet_ptp_init();
lwip_init();
netif_config();
user_notification(&gnetif);
ptpd_Init();
接受网络时钟同步数据包,并以此进行时钟校正。如此往复。
while (1) {
ethernetif_input(&gnetif);
ptpd_periodic_handle(localtime);
}
2. 测试方法
因为1588的时钟精确同步功能需要在网络中实现,因此先楫用了2块HPM6750EVK通过对接的方式测试。在分别烧入了master和slave的程序后,通过网线直接连接板子上的RJ45(J10)端口。如图所示:
系统上电后,在从端口的串口中显示
(D 1651074120.060559130) state PTP_SLAVE
(D 1651074121.919880830) addForeign: new record (0,1) 1 1 98:2c:bc:b1:9f:18
(D 1651074121.923243890) event MASTER_CLOCK_CHANGED
(D 1651074121.925549510) state PTP_UNCALIBRATED
(D 1651074121.927681110) toState: Q = 0, R = 5
(D 1651074123.919898550) updateOffset
(D 1651074123.921597570) updateClock seconds
(D 1651074134.003162180) setTime: resetting system clock to 1651074134s 3162050ns
(D 1651074134.006781080) initClock
(D 1651074134.008349500) one-way delay: 0s 0ns
(D 1651074134.011270660) offset from master: -10s -79562820ns
(D 1651074134.014279260) observed drift: 0
(D 1651074135.999474620) updateOffset
(D 1651074136.001174640) one-way delay: 0s 0ns
(D 1651074136.004096190) offset from master: 0s 10170ns
(D 1651074136.007017370) observed drift: 169
(D 1651074137.999480800) updateOffset
(D 1651074138.001180620) one-way delay: 0s 0ns
(D 1651074138.004101330) offset from master: 0s 14370ns
(D 1651074138.007022680) observed drift: 408
3. 测试结果
通过对结果的比对,我们将时间戳的偏移值进行比较,得到下图:
从图中可以看到,在同步之初,时间的偏差较大,但经过最初的快速调整后,时钟精确在±10us之内。这对于IEEE1588-2002来说,已经是非常好的效果。
总结
本文介绍了HPM6700/6400系列微控制器的以太网1588功能的使用和示例的演示。在IEEE1588-2002下,100MHz的网络测试中得到了很好的效果。对于1588-2008版本的测试,会在后续的文档中推出。