IRIG-B码校时在WEC7主板ESM335x上的实现

 2016-9-12         

  ESM335x是英创公司推出的基于TI AM335x Cortex-A8 CPU的高性能工控主板,板载了丰富的应用通讯接口,如LVDS/TTL标准显示接口,4USB、6串口、双CAN、双网口等。除此之外,ESM335x还引出了一组精简ISA总线,我们基于ESM335x的ISA总线设计了一系列扩展模块,比如8串口扩展模块ETA508、双网口扩展模块ETA728和4路CAN总线扩展模块ETA704,使得ESM335x能够满足更多复杂的工业应用,比如通讯管理机。当然用户也可以利用ESM335x 的ISA总线扩展自己的专有应用模块,以适应特定的现场应用需求。


  在电力、交通、电信等行业,一般要求设备具有高精度的时钟,通常由时钟源提供高精度的时钟信息输出,而设备需要有自动校时和时钟同步的能力,IRIG-B是目前广泛应用的较时方案之一,本文就将介绍ESM335x通过GPS时钟源产生的IRIG-B(DC)码实现时间同步的方法。


  IRIG是美国靶场司令委员会制定的一种时间标准,其中的串行时钟编码共有6种格式,即A、B、D、E、G、H。它们的主要差别是时间码的帧速率不同,广泛应用的IRIG-B即其中的B型编码,B型码的时帧速率为1帧/s,可传递100位信息。图1是IGIG-B码示意图,其时帧周期是1s,每秒100个码元,使用脉宽编码方式,每个码元脉宽10ms,共三种码元,其中高电平5ms和2ms分别表示二进制 “1”,“0”,高电平8ms为位置标识,分别为P0,P1,…P9。连续两个8ms宽度脉冲的第二个8ms脉冲的前沿为秒准点标志,也是一个时间格式的帧参考标志。一个时间格式帧包含了秒,时,分,天数,年份,控制位等丰富的信息。


IRIG-B码.gif

图1:IRIG-B码标准


  上面是对IRIG-B码的简单介绍,在实际使用IRIG-B码时钟源与ESM335x进行时间同步时,用户并不需要关心IRIG-B码的具体含义和实现方法,仅需要将B码脉连接到ESM335x的较时引脚就可以了,ESM335x的驱动程序将完成B码解码、同步等工作。


  ESM335x(EM335x)使用GPIO6作为B码脉冲输入管脚。


  由于GPIO6还复用了PWM功能,所以当使用较时功能时,系统的“PWM1:”则不可用。另外需要特别注意的是:ESM335x(EM335x)所有GIPO的最高输入电压不能超3.3V,否则将损坏主CPU,所以在连接B码信号时应该根据实际情况增加相应的电平转换电路。


  应用程序打开设备"IGB1:"后,对应的驱动程序就会根据注册表的设备,自动进行时间同步,下面是IRIG-B码校时的例子代码:


  #include "stdafx.h"

  #include <winioctl.h>

  #include "bsp_drivers.h"

 

  #define IOCTL_IRIG_B_GET_TIME    

      CTL_CODE(FILE_DEVICE_BUS_EXTENDER, 4055, METHOD_BUFFERED,  FILE_ANY_ACCESS)

  #define IOCTL_IRIG_B_SYNC_NOW 

      CTL_CODE(FILE_DEVICE_BUS_EXTENDER, 4056, METHOD_BUFFERED,FILE_ANY_ACCESS)

 

  int _tmain(int argc, _TCHAR* argv[])

  {

      HANDLE      hIrigb;

      SYSTEMTIME  systime;

      DWORD       dwTimeoues;

 

      // 打开系统较时功能,驱动程序会根据注册表的设置自动较时

      hIrigb = CreateFile(TEXT("IGB1:"),     

          GENERIC_READ|GENERIC_WRITE,        

          FILE_SHARE_READ|FILE_SHARE_WRITE,  

          NULL,                              

          OPEN_EXISTING,                     

          FILE_FLAG_RANDOM_ACCESS,           

          NULL);                             

      if(hIrigb == INVALID_HANDLE_VALUE)

          return -1;

 

      // 立刻进行一次时间同步,超时时间设置为3000ms

      dwTimeoues = 3000;         

      if(DeviceIoControl(hIrigb, 

           IOCTL_IRIG_B_SYNC_NOW,             

          &dwTimeoues,   

          sizeof(DWORD),     

          &systime,           // 如果时间同步成功,返回当时系统时间             

          sizeof(SYSTEMTIME),                

          NULL,NULL))

      {

          RETAILMSG(1, (TEXT("Time: %04d-%02d-%02d.%02d:%02d:%02d\r\n"),

              systime.wYear, systime.wMonth, systime.wDay,

              systime.wHour, systime.wMinute, systime.wSecond));

      }

      else

      {

          RETAILMSG(1, (TEXT("Tiem sync faild!!!\r\n")));

      }

 

      // 查看最近一次同步的时间,如果返回失败表示时间未同步

      if(DeviceIoControl(hIrigb,              

          IOCTL_IRIG_B_GET_TIME,             

          NULL,                              

          0,                                 

          &systime,                          

          sizeof(SYSTEMTIME),                

          NULL, NULL))

      {

          RETAILMSG(1, (TEXT("Sync time: %04d-%02d-%02d.%02d:%02d:%02d\r\n"),

              systime.wYear, systime.wMonth, systime.wDay,

              systime.wHour, systime.wMinute, systime.wSecond));

      }                      

 

      // 关闭较时功能

      CloseHandle(hIrigb);

      return 0;

  }


  用户可以通过修改系统注册表来配置灵活的校时方案,通过注册表的设置,驱动程序可自动实现时间秒同步、分钟同步、小时同步或日同步,对应的注册表项如下:(下面的注册表键值为系统默认值)


  [HKEY_LOCAL_MACHINE\Drivers\BuiltIn\IGB1]

  "Prefix"="IGB"      

  "Dll"="irig_b.dll"     

  "Priority256"=dword:88 

  ; AutoSync =0: 禁止校时功能;  =1: 秒同步; =2: 分同步; = 3: 小时同步; = 4: 日同步

  "AutoSync"=dword:2       ; minute sync

  ; SyncMinute:当AutoSync为小时同步时,在SyncMinute分钟进行同步

  "SyncMinute"=dword:3b    ; 0x3b = 59 -> minute on sync

  ; SyncHour AutoSync为日同步时,在SyncHour小时进行同步

  "SyncHour"=dword:17      ; 0x17= 23 -> hour on sync


  传统的工控板卡在对IRIG-B码处理时,通常需要增加额外的硬件(如单片机,FPGA)对B码进行解码,然后再通过串口、总线或其它形式将数据交给主控板卡处理,增加了系统成本和操作难度,ESM335x可直接对B码进行解码,不需要增加任何硬件就能实现毫秒级精度的时间同步,大大降低了系统复杂程度,节约了成本,提高了系统稳定性。