xuechengan

xuechengan

0个粉丝

10

问答

0

专栏

0

资料

xuechengan  发布于  2016-07-28 10:11:05
采纳率 0%
10个问答
8030

怎么在Hi3516a上实现NTP网络校时呢?

 
需要在Hi3516a上实现NTP网络校时,哪位大神能给个思路啥的不?谢谢了~~~
我来回答
回答21个
时间排序
认可量排序

ngswfx

2个粉丝

55

问答

1

专栏

40

资料

ngswfx 2016-07-28 12:45:41
认可0
本帖最后由 ngswfx 于 2016-7-28 12:52 编辑

如果能广域网,就在板子上写NTP的客户端部分即可。

如果不能广域网,就在局域网里面架设一个NTP服务器,或者让某个arm设备或者PC机提供NTP服务。如果arm端提供校准服务,代码写一个NTP服务端。

网上有实现源码,不难。多调试。

//arm的NTP客户端部分,网上源码很多,修改一下即可。

//////得到UTC时间后,注意和版端时区转换即可。


//参考线程流程,是ntp客户端,代码里面命名initNtpServer错了,改成initNtpCltService就好了,整体流程基本如此,细节不一定对哦::lol
[code]

tm * GetCurTime()
{
        time_t timep;
        time (&timep);
        struct tm *p;
        p=(struct tm *)localtime(&timep);
        p->tm_year+=1900;
        return p;
}
//当前时间显示
void ShowCurTime()
{
        time_t timep;
        time (&timep);
        DebugInfEx(DBG_LEVEL2,"cur time :%s ntp start!\n",asctime(gmtime(&timep)));
}
//获取可用的NTP服务器IP地址
char * GetCanbeUseNtpServerIP()
{
        char *canuseIP=NULL;
        canuseIP=(char *)"200.20.186.76";
        if(IVComInf_IsIPOnLineSpeicalTime("200.20.186.76",false,1500)==5){
                canuseIP=(char *)"200.20.186.76";
        }
        if(canuseIP==NULL){
                if(IVComInf_IsIPOnLineSpeicalTime("pool.ntp.br",false,1500)==5){
                        canuseIP=(char *)"pool.ntp.br";
                }
        }
        if(canuseIP==NULL){
                if(IVComInf_IsIPOnLineSpeicalTime("163.117.202.33",false,1500)==5){
                        canuseIP=(char *)"163.117.202.33";
                }
        }
        if(canuseIP!=NULL){
                DebugInfEx(DBG_LEVEL2,"canUsed NTP Server is %s !\n",canuseIP);
                return canuseIP;
        }else return NULL;
}
//保存时间到硬件
void SetTimeToHW()
{
        /////////其他arm系统/////////////
  //  char strCMD[32];
  //  sprintf(strCMD,"hwclock -w");
   // system(strCMD);
    ////////////HI3520系统///////////////////
        IVHI_SAVE_SystemTimeToRtc();
}
//NTP服务器获取当前精确时间
void *NtpClentThread(void *p)
{
        pthread_detach(pthread_self());
        char *hostname=NULL;
        hostname=GetCanbeUseNtpServerIP();
        int NtpPort                                                =123;                             //NTP is port 123
        int maxlen                                                =1024;                //check our buffers
        int                                                         i;                                          // misc var i
        unsigned char                                         msg[48]={010,0,0,0,0,0,0,0,0};    // the packet we send
        unsigned long                                  buf[maxlen]; // the buffer we get back
        struct protoent                                        *proto;     //
        struct sockaddr_in                                 server_addr;
        int                                                         s=0;  // socket
        long                                                         tmit;   // the time -- This is a time_t sort of
        long                            nLastBackSucTimer=0;//超过1分钟一场,重新建立socket
        long                            nLastRealSucTimer=0;//超过10分钟,尝试找另外的服务器
        long                            nLastGetRtpUTCTimer=1000;//只要成功一次,需要等待1小时
        char *wday[]                                        ={"Sun","Mon","Tue","Wes","Thu","Fri","Sat"};
        //////////////////////////////////////////
        if(hostname!=NULL)
                nLastRealSucTimer=GetTickCount();
        proto=getprotobyname("udp");
        s=socket(PF_INET, SOCK_DGRAM, proto->p_proto);
        int         bFirst=1;
        while(1)
        {
                if(bFirst==1){//首次,尽快执行,获取到准确时间
                        bFirst=0;
                        usleep(1000);
                }else{
                        if(bGetRtpUTCtime>=1)
                                sleep(3600);//一个小时以后再次获取
                        else
                                sleep(10);
                }
                if(bGetRtpUTCtime>=1){
                        if((GetTickCount()-nLastGetRtpUTCTimer)<3600*1000)
                                continue;
                }
                //////////////////////////////
                if(!proto)
                        continue;;
                //超过一分钟,没有收到 信息了,重新建立
                if((GetTickCount()-nLastBackSucTimer)>60000)
                {
                        if(s!=0){
                                close(s);
                                s=0;
                        }
                        nLastBackSucTimer=GetTickCount();
                }
                //超过10分钟
                if((GetTickCount()-nLastRealSucTimer)>600000){
                        hostname=GetCanbeUseNtpServerIP();
                        nLastRealSucTimer=GetTickCount();
                        if(hostname==NULL)
                                continue;
                }
                if(hostname==NULL)
                        continue;
                if(s==0)
                        s=socket(PF_INET, SOCK_DGRAM, proto->p_proto);
                if(s<1){
                        //DebugInfEx(DBG_LEVEL4,"NtpClentThread socket create error !\n");
                        continue;
                }
                memset( &server_addr, 0, sizeof( server_addr ));
                server_addr.sin_family=AF_INET;
                server_addr.sin_addr.s_addr = inet_addr(hostname);
                server_addr.sin_port=htons(NtpPort);
                DebugInfEx(DBG_LEVEL2,"sending data..to:%d %s  \n",server_addr.sin_addr.s_addr,hostname );
                i=sendto(s,msg,sizeof(msg),0,(struct sockaddr *)&server_addr,sizeof(server_addr));
                if(i<1){
                        //DebugInfEx(DBG_LEVEL4,"NtpClentThread socket send error len:%d !\n",i);
                        close(s);
                        s=0;
                        continue;
                }
                //////////////////////////////////
                struct sockaddr saddr;
                socklen_t saddr_l = sizeof (saddr);
                i=recvfrom(s,buf,48,0,&saddr,&saddr_l);
                if(i>0){
                        nLastBackSucTimer=GetTickCount();
                        nLastRealSucTimer=GetTickCount();
                        //////////////////////////////////////////
                        tmit=ntohl((time_t)buf[4]);    //# get transmit time
                        struct timeval tv={0,0};
                        struct timezone tz={0,0};
                        //把这个时间设定到系统里面
                        tmit-= 2208988800U;
                        tzset();
                        gettimeofday(&tv,&tz);//获取当前系统可能的时区
                        DebugInfEx(DBG_LEVEL2,"tmit=%d tz_dsttime:%d tz_minuteswest:%d\n",tmit,tz.tz_dsttime,tz.tz_minuteswest);
                   /////////////////////////////这之前需要强制转换+8个小时的时间 由于ARM可能是精简的,自己没有时区,或者没法设置,但是时间又必须正确
                        ///////////////读取时间计算出当前系统的时区,UTC时间和本地时间如果小时相同,则是0时区,此时,得到的UTC时间+8小时
                        time_t current_timet;
                        time(¤t_timet);//得到当前时间秒数
                        struct tm *pZero;
                        pZero=gmtime(¤t_timet);//得到GMT,即UTC时间
                        time_t local_tm;
                        struct tm *pZone8;
                        pZone8=localtime(&local_tm);//得到本地时间,根据如下打印看出两者相差8小时。
                        int nZone=0;
                        if(pZone8->tm_hour==pZero->tm_hour)
                                nZone=0;
                        /////////////////////////////////////////////////////////////////
                        if(nZone==0)
                                tv.tv_sec = tmit+28800;//3600*8;
                        else
                                tv.tv_sec = tmit;
                        tv.tv_usec = 0;
                   /////////////////////////////
                   settimeofday(&tv,&tz);//并不会改变时区,让时区变成8,底层机制定的.
                   usleep(11*1000);
                   //保存时间到硬件
                        SetTimeToHW();
                        bGetRtpUTCtime++;
                        nLastGetRtpUTCTimer=GetTickCount();
                        tzset();
                        time_t timep;
                        time(&timep);
                        //#compare to system time
                        DebugInfEx(DBG_LEVEL2,"Time: %s",ctime(&timep));
                        struct tm *p;
                        p=localtime(&timep);
                        DebugInfEx(DBG_LEVEL2,"NTP UTC+8:%d%d%d---  %s  %d:%d:%d \n",(1900+p->tm_year),(1+p->tm_mon),p->tm_mday,wday[p->tm_wday],p->tm_hour, p->tm_min, p->tm_sec);
                }else
                        DebugInfEx(DBG_LEVEL2,"NtpClentThread recvfrom  error len:%d!\n",i);
                //每次都重新建立
                if(s!=0){
                        close(s);
                        s=0;
                }
        }
        DebugInfEx(DBG_LEVEL2,"NtpClentThread over\n");
        pthread_exit(NULL);
        return (void *)0;
}
//初始化NTP服务
void                                                        initNtpServer()
{
        ShowCurTime();
        pthread_attr_t attr;
        pthread_attr_init(&attr);
        pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
        pthread_attr_setstacksize(&attr, 1024*1024);
        //开启NTP获取时间线程
        if(!hThreadNtp)
                pthread_create(&hThreadNtp,&attr,NtpClentThread,NULL);
         pthread_attr_destroy(&attr);
}
//释放NTP服务
void                                                        DinitNtpServer()
{
        if(hThreadNtp>0){
                pthread_cancel(hThreadNtp);
                hThreadNtp=0;
        }
}

[/code]

xuechengan

0个粉丝

10

问答

0

专栏

0

资料

xuechengan 2016-07-28 13:36:03
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=35016&ptid=12109]ngswfx 发表于 2016-7-28 12:45[/url]
如果能广域网,就在板子上写NTP的客户端部分即可。

如果不能广域网,就在局域网里面架设一个NTP服务器, ...[/quote]

这代码是你自己写的?我从网上下了Ntpclient源码包,编译出了ntpclient可执行程序,但感觉用不起来

ngswfx

2个粉丝

55

问答

1

专栏

40

资料

ngswfx 2016-07-28 14:24:38
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=35024&ptid=12109]xuechengan 发表于 2016-7-28 13:36[/url]
这代码是你自己写的?我从网上下了Ntpclient源码包,编译出了ntpclient可执行程序,但感觉用不起来[/quote]

对,我试了,可以从广域网得到时间。主要是广域网提供NTP服务器的地址,要弄对就可以了。

///代码支持自动选择,你可以多弄几个,呵呵:lol。

呆呆

0个粉丝

0

问答

0

专栏

0

资料

呆呆 2016-08-01 18:53:26
认可0
学习了,学习了

xuechengan

0个粉丝

10

问答

0

专栏

0

资料

xuechengan 2016-08-02 18:21:07
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=35031&ptid=12109]ngswfx 发表于 2016-7-28 14:24[/url]
对,我试了,可以从广域网得到时间。主要是广域网提供NTP服务器的地址,要弄对就可以了。

///代码支持 ...[/quote]

我编译了一个ntpdate客户端,然后自己建立了一个ntp服务器,把编译好的ntpdate放到开发板上运行更新时间时少了8小时,我直到是因为UTC时区和上海时区的原因,我应该怎么修改呢,想请教你一下。

ngswfx

2个粉丝

55

问答

1

专栏

40

资料

ngswfx 2016-08-02 20:24:20
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=35312&ptid=12109]xuechengan 发表于 2016-8-2 18:21[/url]
我编译了一个ntpdate客户端,然后自己建立了一个ntp服务器,把编译好的ntpdate放到开发板上运行更新时间 ...[/quote]

方法一:arm上面把时区需要的东西都配置上,通过linux有关时区函数实现,获取时区。
方法二:直接加时间8小时,8×3600

///////代码里面都有。只不过不一定能用起来。

kg123456

0个粉丝

14

问答

0

专栏

3

资料

kg123456 2016-08-02 23:40:57
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=35312&ptid=12109]xuechengan 发表于 2016-8-2 18:21[/url]
我编译了一个ntpdate客户端,然后自己建立了一个ntp服务器,把编译好的ntpdate放到开发板上运行更新时间 ...[/quote]

你设置中国时区使用亚洲/上海(+8)

将PC Linux下的/usr/share/zoneinfo/Asia/Shanghai   复制到板子/etc/下  改名为localtime

cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime



xuechengan

0个粉丝

10

问答

0

专栏

0

资料

xuechengan 2016-08-03 09:13:18
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=35333&ptid=12109]kg123456 发表于 2016-8-2 23:40[/url]
你设置中国时区使用亚洲/上海(+8)

将PC Linux下的/usr/share/zoneinfo/Asia/Shanghai   复制到板子/ ...[/quote]

Shanghai是一个链接文件,并且一个在开发板,一个在虚拟机,cp没用吧

kg123456

0个粉丝

14

问答

0

专栏

3

资料

kg123456 2016-08-03 15:09:38
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=35340&ptid=12109]xuechengan 发表于 2016-8-3 09:13[/url]
Shanghai是一个链接文件,并且一个在开发板,一个在虚拟机,cp没用吧[/quote]

虚拟机挂载到板子上就可以用cp直接复制过去了   我省略了挂载目录而已

kg123456

0个粉丝

14

问答

0

专栏

3

资料

kg123456 2016-08-03 15:16:52
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=35340&ptid=12109]xuechengan 发表于 2016-8-3 09:13[/url]
Shanghai是一个链接文件,并且一个在开发板,一个在虚拟机,cp没用吧[/quote]

补充下我设置网络时间的步骤

1. 添加网关         # route add default gw 192.168.3.1
2. 运行                 # ntpdate 0.pool.ntp.org  

xuechengan

0个粉丝

10

问答

0

专栏

0

资料

xuechengan 2016-08-03 18:39:26
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=35383&ptid=12109]kg123456 发表于 2016-8-3 15:16[/url]
补充下我设置网络时间的步骤

1. 添加网关         # route add default gw 192.168.3.1
[/quote]

您好,我按照您的方法在开发板上挂载虚拟机下面的文件系统,出现下面的问题:
如果挂载我制作的文件系统,在 /usr/share目录下面就没有东西了,所以想复制/usr/share/zoneinfo/Asia/Shanghai 时也就找不到文件了;

如果挂载虚拟机的根文件系统,权限都不允许;

ngswfx

2个粉丝

55

问答

1

专栏

40

资料

ngswfx 2016-08-03 19:35:02
认可0
本帖最后由 ngswfx 于 2016-8-3 19:38 编辑

[quote][url=forum.php?mod=redirect&goto=findpost&pid=35407&ptid=12109]xuechengan 发表于 2016-8-3 18:39[/url]
您好,我按照您的方法在开发板上挂载虚拟机下面的文件系统,出现下面的问题:
如果挂载我制作的文件系统 ...[/quote]

PC机上的文件,和开发板,这个时区文件通用,从PC机上找一个,弄到开发板上去。

xuechengan

0个粉丝

10

问答

0

专栏

0

资料

xuechengan 2016-08-03 20:13:56
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=35409&ptid=12109]ngswfx 发表于 2016-8-3 19:35[/url]
PC机上的文件,和开发板,这个时区文件通用,从PC机上找一个,弄到开发板上去。[/quote]

我把 localtime 放到开发板上自己挂载的文件系统去了,可是获取时间,还是相差八小时啊,感觉 localtime 没用起来啊!只是拷贝了,放进去而已

ngswfx

2个粉丝

55

问答

1

专栏

40

资料

ngswfx 2016-08-04 01:36:44
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=35411&ptid=12109]xuechengan 发表于 2016-8-3 20:13[/url]
我把 localtime 放到开发板上自己挂载的文件系统去了,可是获取时间,还是相差八小时啊,感觉 localtime  ...[/quote]

服务器时区多少?也需要注意。

kg123456

0个粉丝

14

问答

0

专栏

3

资料

kg123456 2016-08-04 09:15:28
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=35411&ptid=12109]xuechengan 发表于 2016-8-3 20:13[/url]
我把 localtime 放到开发板上自己挂载的文件系统去了,可是获取时间,还是相差八小时啊,感觉 localtime  ...[/quote]

我的意思是  将上海那个时区文件   复制到开发板/etc下  改名为localtime   

kg123456

0个粉丝

14

问答

0

专栏

3

资料

kg123456 2016-08-04 09:17:30
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=35411&ptid=12109]xuechengan 发表于 2016-8-3 20:13[/url]
我把 localtime 放到开发板上自己挂载的文件系统去了,可是获取时间,还是相差八小时啊,感觉 localtime  ...[/quote]

这个路径是PC端的/usr/share/zoneinfo/Asia/Shanghai      复制到开发板的/etc目录下

xuechengan

0个粉丝

10

问答

0

专栏

0

资料

xuechengan 2016-08-04 09:49:48
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=35435&ptid=12109]kg123456 发表于 2016-8-4 09:17[/url]
这个路径是PC端的/usr/share/zoneinfo/Asia/Shanghai      复制到开发板的/etc目录下[/quote]

嗯嗯,昨天拷的目的地是挂载的文件系统,所以有问题,现在解决了,谢谢您的回答

xuechengan

0个粉丝

10

问答

0

专栏

0

资料

xuechengan 2016-08-04 09:51:32
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=35420&ptid=12109]ngswfx 发表于 2016-8-4 01:36[/url]
服务器时区多少?也需要注意。[/quote]

嗯嗯,昨天是拷错地方了,现在同步了,谢谢帮忙解答啊

xuechengan

0个粉丝

10

问答

0

专栏

0

资料

xuechengan 2016-08-09 10:25:49
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=35435&ptid=12109]kg123456 发表于 2016-8-4 09:17[/url]
这个路径是PC端的/usr/share/zoneinfo/Asia/Shanghai      复制到开发板的/etc目录下[/quote]

你好,又遇到一个问题想请教你一下,我现在ntp校时是可以了,但前提是要求ntp服务器(也就是linux虚拟机)是连网的,如果ntp服务器不联网,只是PC机和开发板互连就不能实现网络校时,所以ntp服务器是必须要连网的吗?

kg123456

0个粉丝

14

问答

0

专栏

3

资料

kg123456 2016-08-09 11:35:52
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=35753&ptid=12109]xuechengan 发表于 2016-8-9 10:25[/url]
你好,又遇到一个问题想请教你一下,我现在ntp校时是可以了,但前提是要求ntp服务器(也就是linux虚拟机 ...[/quote]

你开发板不能ping外网?板子有空间的话  你把文件放到板上  在板上运行  
我当时是直接在虚拟机上的  没注意这个问题
加载中···
或将文件直接拖到这里
悬赏:
E币
网盘
* 网盘链接:
* 提取码:
悬赏:
E币

Markdown 语法

  • 加粗**内容**
  • 斜体*内容*
  • 删除线~~内容~~
  • 引用> 引用内容
  • 代码`代码`
  • 代码块```编程语言↵代码```
  • 链接[链接标题](url)
  • 无序列表- 内容
  • 有序列表1. 内容
  • 缩进内容
  • 图片![alt](url)
+ 添加网盘链接/附件

Markdown 语法

  • 加粗**内容**
  • 斜体*内容*
  • 删除线~~内容~~
  • 引用> 引用内容
  • 代码`代码`
  • 代码块```编程语言↵代码```
  • 链接[链接标题](url)
  • 无序列表- 内容
  • 有序列表1. 内容
  • 缩进内容
  • 图片![alt](url)
举报反馈

举报类型

  • 内容涉黄/赌/毒
  • 内容侵权/抄袭
  • 政治相关
  • 涉嫌广告
  • 侮辱谩骂
  • 其他

详细说明

易百纳技术社区