sonicfirr 发表于 2022-4-8 10:09

【平头哥RVB2601创意应用开发】使用体验06 -- NTP授时

本帖最后由 sonicfirr 于 2022-4-8 10:24 编辑

<p style="text-indent:24.0000pt; text-align:justify"><span style="font-size:12pt"><span style="125%"><span style="font-family:&quot;Times New Roman&quot;"><span style="font-size:12.0000pt"><span style="font-family:宋体"><font face="宋体">本篇记录</font><font face="Times New Roman">RVB2601</font><font face="宋体">使用</font><font face="Times New Roman">NTP</font><font face="宋体">进行网络授时的开发过程,本人历时三次大时间段投入才搞定,也是</font><font face="Times New Roman">SDK</font><font face="宋体">使用以来遇到的最大一坑。</font></span></span></span></span></span></p>

<h2 style="text-align:justify"><span style="font-size:14pt"><span style="125%"><span style="font-family:&quot;Times New Roman&quot;"><span style="font-weight:bold"><b><span style="font-size:14.0000pt"><span style="font-family:宋体"><span style="font-weight:bold"><font face="Times New Roman">1</font><font face="宋体">、</font><font face="Times New Roman">SNTP</font><font face="宋体">行不通</font></span></span></span></b></span></span></span></span></h2>

<p style="text-indent:24.0000pt; text-align:justify"><span style="font-size:12pt"><span style="125%"><span style="font-family:&quot;Times New Roman&quot;"><span style="font-size:12.0000pt"><span style="font-family:宋体"><font face="宋体">阶段一,历时</font><font face="Times New Roman">8</font><font face="宋体">小时(一个下午加晚上),使用</font><font face="Times New Roman">SNTP</font><font face="宋体">组件,各种编译错误,稀里糊涂到直接放弃。最后也是联系平头哥技术支持,了解到</font><font face="Times New Roman">SNTP</font><font face="宋体">没有适配。这段工作已经过了一段时间,当时也没心情做测评记录,大概问题是</font><font face="Times New Roman">SNTP</font><font face="宋体">组件需要</font><font face="Times New Roman">LWIP</font><font face="宋体">包的支持,而</font><font face="Times New Roman">SDK</font><font face="宋体">中包含</font><font face="Times New Roman">SAL</font><font face="宋体">组件已经适配了</font><font face="Times New Roman">LWIP</font><font face="宋体">包,但是功能上,特别是应用层协议适配没有做完整。而单独加载</font><font face="Times New Roman">LWIP</font><font face="宋体">包,又会出现大量重复定义的情况(与</font><font face="Times New Roman">SAL</font><font face="宋体">组件中的冲突),因此除非下力气扩展</font><font face="Times New Roman">SAL</font><font face="宋体">组件,自己添加</font><font face="Times New Roman">SNTP</font><font face="宋体">支持,否则此路行不通了。</font></span></span></span></span></span></p>

<h2 style="text-align:justify"><span style="font-size:14pt"><span style="125%"><span style="font-family:&quot;Times New Roman&quot;"><span style="font-weight:bold"><b><span style="font-size:14.0000pt"><span style="font-family:宋体"><span style="font-weight:bold"><font face="Times New Roman">2</font><font face="宋体">、尝试</font><font face="Times New Roman">NTP</font></span></span></span></b></span></span></span></span></h2>

<p style="text-indent:24.0000pt; text-align:justify"><span style="font-size:12pt"><span style="125%"><span style="font-family:&quot;Times New Roman&quot;"><span style="font-size:12.0000pt"><span style="font-family:宋体"><font face="宋体">阶段二,大概是两天后,活动微信群中已经有很多网友都反馈了</font><font face="Times New Roman">SNTP</font><font face="宋体">的问题,有人提到可以使用</font><font face="Times New Roman">NTP</font><font face="宋体">,但是</font><font face="Times New Roman">NTP</font><font face="宋体">会遇到</font><font face="Times New Roman">SDK</font><font face="宋体">中的</font><font face="Times New Roman">Bug</font><font face="宋体">,就是</font><font face="Times New Roman">drv_wifi_at_w800</font><font face="宋体">组件中的</font><font face="Times New Roman">w800_connect_remote()</font><font face="宋体">函数的</font><font face="Times New Roman">UDP</font><font face="宋体">连接</font><font face="Times New Roman">Bug</font><font face="宋体">(</font><font face="Times New Roman">NTP</font><font face="宋体">使用的</font><font face="Times New Roman">UDP</font><font face="宋体">协议),关键点就是函数实现连接远端</font><font face="Times New Roman">TCP</font><font face="宋体">或</font><font face="Times New Roman">UDP</font><font face="宋体">服务器使用的是同一条语句,也就是相同的</font><font face="Times New Roman">AT</font><font face="宋体">命令,但实际</font><font face="Times New Roman">W800</font><font face="宋体">的</font><font face="Times New Roman">TCP</font><font face="宋体">连接和</font><font face="Times New Roman">UDP</font><font face="宋体">连接,虽然</font><font face="Times New Roman">AT</font><font face="宋体">命令一样,但是默认参数项有差别。</font></span></span></span></span></span></p>

<p align="center" style="text-align:center"></p>

<p>&nbsp;<span style="font-size:12pt"><span style="125%"><span style="font-family:&quot;Times New Roman&quot;"><span style="font-size:10.5000pt"><span style="font-family:宋体"><font face="宋体">图</font><font face="Times New Roman">6-1 UDP</font><font face="宋体">连接</font><font face="Times New Roman">Bug</font><font face="宋体">点</font></span></span></span></span></span></p>

<p align="center" style="text-align:center"></p>

<p><font face="宋体" style="font-size: 10.5pt; font-family: 宋体;">图</font><font face="Times New Roman" style="font-size: 10.5pt;">6-2 AT+CIPSTART</font><font face="宋体" style="font-size: 10.5pt; font-family: 宋体;">命令格式要求</font></p>

<p style="text-indent:24.0000pt; text-align:justify"><span style="font-size:12pt"><span style="125%"><span style="font-family:&quot;Times New Roman&quot;"><span style="font-size:12.0000pt"><span style="font-family:宋体"><font face="宋体">针对上述问题,解决方法有两个,一是修改</font>&ldquo;<font face="Times New Roman">atparser_send()</font><font face="宋体">&rdquo;语句,增加</font><font face="Times New Roman">AT</font><font face="宋体">命令的本地端口参数&mdash;&mdash;因为</font><font face="Times New Roman">TCP</font><font face="宋体">也可以传递这个参数,并且改&ldquo;</font><font face="Times New Roman">tcp_client</font><font face="宋体">&rdquo;为&ldquo;</font><font face="Times New Roman">udp_unicast</font><font face="宋体">&rdquo;。二是增加&ldquo;</font><font face="Times New Roman">case NET_TYPE_UDP_UNICAST:</font><font face="宋体">&rdquo;分支的代码,额外提供一个</font><font face="Times New Roman">UDP</font><font face="宋体">连接的函数调用。</font></span></span></span></span></span></p>

<p align="center" style="text-align:center"></p>

<p><span style="font-size:12pt"><span style="125%"><span style="font-family:&quot;Times New Roman&quot;"><span style="font-size:10.5000pt"><span style="font-family:宋体"><font face="宋体">图</font><font face="Times New Roman">6-3 </font><font face="宋体">两种修改方法</font></span></span></span></span></span></p>

<p style="text-indent:24.0000pt; text-align:justify"><span style="font-size:12pt"><span style="125%"><span style="font-family:&quot;Times New Roman&quot;"><span style="font-size:12.0000pt"><span style="font-family:宋体"><font face="宋体">很明显,方法一</font><font face="Times New Roman">TCP</font><font face="宋体">和</font><font face="Times New Roman">UDP</font><font face="宋体">使用同一传递的本地端口参数,这样就限制了板子同时开启</font><font face="Times New Roman">TCP</font><font face="宋体">和</font><font face="Times New Roman">UDP</font><font face="宋体">的能力,所以本人最终采用了方法二,那么索性将</font><font face="Times New Roman">NET_TYPE_TCP_CLIENT</font><font face="宋体">分支也做了修改,只保留</font><font face="Times New Roman">tcp_client</font><font face="宋体">模式的实现。</font></span></span></span></span></span></p>

<p align="center" style="text-align:center"></p>

<p><span style="font-size:12pt"><span style="125%"><span style="font-family:&quot;Times New Roman&quot;"><span style="font-size:10.5000pt"><span style="font-family:宋体"><font face="宋体">图</font><font face="Times New Roman">6-4 </font><font face="宋体">项目最终修改方法</font></span></span></span></span></span></p>

<p style="text-indent:24.0000pt; text-align:justify"><span style="font-size:12pt"><span style="125%"><span style="font-family:&quot;Times New Roman&quot;"><span style="font-size:12.0000pt"><span style="font-family:宋体"><font face="宋体">上述方法的确保证</font><font face="Times New Roman">TCP</font><font face="宋体">和</font><font face="Times New Roman">UDP</font><font face="宋体">测试的成功,但是</font><font face="Times New Roman">NTP</font><font face="宋体">依然没有产生效果,于是进一步做代码追踪,最后自己给自己挖了一个坑。因为距离写下此篇也有一段时间了,所以具体过程记不清了,大概是在</font><font face="Times New Roman">w800_devops.c</font><font face="宋体">中看到函数</font><font face="Times New Roman">w800_wifi_module_conn_start()</font><font face="宋体">会调用</font><font face="Times New Roman">w800_connect_remote()</font><font face="宋体">,猜想它就是上一层入口&mdash;&mdash;这一猜想后面通过查看</font><font face="Times New Roman">list</font><font face="宋体">文件&ldquo;项目目录</font><font face="Times New Roman">/Lst/</font><font face="宋体">项目名</font><font face="Times New Roman">.asm</font><font face="宋体">&rdquo;发现是错误的。</font></span></span></span></span></span></p>

<p style="text-indent:24.0000pt; text-align:justify"><span style="font-size:12pt"><span style="125%"><span style="font-family:&quot;Times New Roman&quot;"><span style="font-size:12.0000pt"><span style="font-family:宋体"><font face="宋体">带着这个错误猜想,本人发现函数中会动态生成一个本地端口,但是没有传递给</font><font face="Times New Roman">w800_connect_remote()</font><font face="宋体">,于是就以为</font><font face="Times New Roman">UDP</font><font face="宋体">也要用这里生成的端口,于是做了下述的修改。</font></span></span></span></span></span></p>

<p align="center" style="text-align:center"></p>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p align="center" style="text-align:center"></p>

<p>&nbsp;</p>

<p align="center" style="text-align:center"></p>

<p>&nbsp;</p>

<p align="center" style="text-align:center"></p>

<p><span style="font-size:12pt"><span style="125%"><span style="font-family:&quot;Times New Roman&quot;"><span style="font-size:10.5000pt"><span style="font-family:宋体"><font face="宋体">图</font><font face="Times New Roman">6-5 </font><font face="宋体">并不成功的阶段二过程,事实是猜测有误!</font></span></span></span></span></span></p>

<p style="text-indent:24.0000pt; text-align:justify"><span style="font-size:12pt"><span style="125%"><span style="font-family:&quot;Times New Roman&quot;"><span style="font-size:12.0000pt"><span style="font-family:宋体"><font face="宋体">因为有了阶段一的挫败,阶段二的</font><font face="Times New Roman">UDP</font><font face="宋体">成功和自我猜测带来的谬误,又是历时大半天的研究,结果还是放弃,甚至决定不在项目中使用网络授时了。</font></span></span></span></span></span></p>

<h2 style="text-align:justify"><span style="font-size:14pt"><span style="125%"><span style="font-family:&quot;Times New Roman&quot;"><span style="font-weight:bold"><b><span style="font-size:14.0000pt"><span style="font-family:宋体"><span style="font-weight:bold"><font face="Times New Roman">3</font><font face="宋体">、</font><font face="Times New Roman">NTP</font><font face="宋体">组件的问题</font></span></span></span></b></span></span></span></span></h2>

<p style="text-indent:24.0000pt; text-align:justify"><span style="font-size:12pt"><span style="125%"><span style="font-family:&quot;Times New Roman&quot;"><span style="font-size:12.0000pt"><span style="font-family:宋体"><font face="宋体">前两个阶段的尝试还包括对</font><font face="Times New Roman">NTP</font><font face="宋体">组件版本的实验。</font></span></span></span></span></span></p>

<p align="center" style="text-align:center"></p>

<p>&nbsp;<span style="font-size:12pt"><span style="125%"><span style="font-family:&quot;Times New Roman&quot;"><span style="font-size:10.5000pt"><span style="font-family:宋体"><font face="宋体">图</font><font face="Times New Roman">6-6 </font><font face="宋体">项目测试的</font><font face="Times New Roman">NTP</font><font face="宋体">组件版本</font></span></span></span></span></span></p>

<p align="center" style="text-align:center"></p>

<p>&nbsp;<span style="font-size: 12pt;"><span style="font-family:&quot;Times New Roman&quot;">&nbsp;</span></span></p>

<p align="center" style="text-align:center"></p>

<p>&nbsp;<span style="font-size:12pt"><span style="125%"><span style="font-family:&quot;Times New Roman&quot;"><span style="font-size:10.5000pt"><span style="font-family:宋体"><font face="宋体">图</font><font face="Times New Roman">6-7 NTP</font><font face="宋体">组件</font><font face="Times New Roman">7.4.5</font><font face="宋体">版本的同步时间函数</font></span></span></span></span></span></p>

<p align="center" style="text-align:center"></p>

<p>&nbsp;<span style="font-size:12pt"><span style="125%"><span style="font-family:&quot;Times New Roman&quot;"><span style="font-size:10.5000pt"><span style="font-family:宋体"><font face="宋体">图</font><font face="Times New Roman">6-8 NTP</font><font face="宋体">组件</font><font face="Times New Roman">7.4.3</font><font face="宋体">版本的同步时间函数</font></span></span></span></span></span></p>

<p style="text-indent:24.0000pt; text-align:justify"><span style="font-size:12pt"><span style="125%"><span style="font-family:&quot;Times New Roman&quot;"><span style="font-size:12.0000pt"><span style="font-family:宋体"><font face="宋体">两种版本的时间同步函数都会报错,其实它们都是又调用了</font><font face="Times New Roman">_ntp_sync_time()</font><font face="宋体">,而这个函数有一系列错误返回判断,随便一个卡住就会不成功。</font></span></span></span></span></span></p>

<p style="text-indent:24.0000pt; text-align:justify"><span style="font-size:12pt"><span style="125%"><span style="font-family:&quot;Times New Roman&quot;"><span style="font-size:12.0000pt"><span style="font-family:宋体"><font face="宋体">后来也是在微信群中看到一个群友</font><font face="Times New Roman">@</font><font face="宋体">杨工,</font><font face="Times New Roman">NTP</font><font face="宋体">测试成功,而且分享的修改截图与本人在阶段二的尝试一致,于是联想到自己的猜测错误,</font><font face="Times New Roman">UDP</font><font face="宋体">本地端口就是要自己定义,那么只可能是</font><font face="Times New Roman">NTP</font><font face="宋体">测试函数中有问题,于是追踪</font><font face="Times New Roman">_ntp_sync_time()</font><font face="宋体">,将其中直接输出时间信息的语句去掉注释,瞬间成功了。</font></span></span></span></span></span></p>

<p align="center" style="text-align:center"></p>

<p><span style="font-size:12pt"><span style="125%"><span style="font-family:&quot;Times New Roman&quot;"><span style="font-size:10.5000pt"><span style="font-family:宋体"><font face="宋体">图</font><font face="Times New Roman">6-9 NTP</font><font face="宋体">同步时间输出</font></span></span></span></span></span></p>

<p align="center" style="text-align:center"></p>

<p>&nbsp;<span style="font-size:12pt"><span style="125%"><span style="font-family:&quot;Times New Roman&quot;"><span style="font-size:10.5000pt"><span style="font-family:宋体"><font face="宋体">图</font><font face="Times New Roman">6-9 NTP</font><font face="宋体">同步时间测试函数的修改</font></span></span></span></span></span></p>

<p style="text-indent:24.0000pt; text-align:justify"><span style="font-size:12pt"><span style="125%"><span style="font-family:&quot;Times New Roman&quot;"><span style="font-size:12.0000pt"><span style="font-family:宋体"><font face="宋体">写下此篇时,本人是利用工作空当完成的,而且在新建工程中逐步复盘前期各种操作并作记录,此时又发现一个</font><font face="Times New Roman">bug</font><font face="宋体">,就是如果注册了接收回调,</font><font face="Times New Roman">ntp</font><font face="宋体">就失败,而去掉回调则成功。应该说,在下对</font><font face="Times New Roman">NTP</font><font face="宋体">或</font><font face="Times New Roman">SNTP</font><font face="宋体">的使用,还是处于不求甚解阶段,只是直接加载封装好的</font><font face="Times New Roman">API</font><font face="宋体">,这个</font><font face="Times New Roman">bug</font><font face="宋体">出现的原因也只能猜想是:&ldquo;</font><font face="Times New Roman">NTP</font><font face="宋体">请求中,本地会与</font><font face="Times New Roman">NTP Server</font><font face="宋体">进行多次交互,而回调函数会影响这多次交互的过程?&rdquo;&mdash;&mdash;其实这个猜想自以为是很不靠谱的!!</font></span></span></span></span></span></p>

<p align="center" style="text-align:center"></p>

<p>&nbsp;<span style="font-size:12pt"><span style="125%"><span style="font-family:&quot;Times New Roman&quot;"><span style="font-size:10.5000pt"><span style="font-family:宋体"><font face="宋体">图</font><font face="Times New Roman">6-10 NTP</font><font face="宋体">的新</font><font face="Times New Roman">bug</font><font face="宋体">发现,与输入回调注册有冲突</font></span></span></span></span></span></p>

<p style="text-indent:24.0000pt; text-align:justify"><span style="font-size:12pt"><span style="125%"><span style="font-family:&quot;Times New Roman&quot;"><span style="font-size:12.0000pt"><span style="font-family:宋体"><font face="宋体">随着代码编写,更有意思的地方出现了。之前虽然发现是</font><font face="Times New Roman">_ntp_sync_time()</font><font face="宋体">中有</font><font face="Times New Roman">bug</font><font face="宋体">,但是还不确定是哪里,</font><font face="Times New Roman">NTP</font><font face="宋体">可以输出信息,但是最后还是输出一句&ldquo;</font><font face="Times New Roman">NTP sync error</font><font face="宋体">&rdquo;蛮膈应人的。于是本人尝试逐句添加</font><font face="Times New Roman">printf</font><font face="宋体">输出,判断出错位置,没想到的是这回居然返回了&ldquo;</font><font face="Times New Roman">NTP sync success</font><font face="宋体">&rdquo;了。</font></span></span></span></span></span></p>

<p align="center" style="text-align:center"></p>

<p>&nbsp;</p>

<p align="center" style="text-align:center"></p>

<p>&nbsp;</p>

<p align="center" style="text-align:center"></p>

<p><span style="font-size:12pt"><span style="125%"><span style="font-family:&quot;Times New Roman&quot;"><span style="font-size:10.5000pt"><span style="font-family:宋体"><font face="宋体">图</font><font face="Times New Roman">6-11 NTP</font><font face="宋体">同步时间莫名成功</font></span></span></span></span></span></p>

<p><span style="font-size:14pt"><span style="125%"><span style="font-family:&quot;Times New Roman&quot;"><span style="font-weight:bold"><b><span style="font-size:14.0000pt"><span style="font-family:宋体"><span style="font-weight:bold"><font face="Times New Roman">4</font><font face="宋体">、</font><font face="Times New Roman">NTP</font><font face="宋体">现阶段测试代码</font></span></span></span></b></span></span></span></span></p>

<p style="text-indent:24.0000pt; text-align:justify"><span style="font-size:12pt"><span style="125%"><span style="font-family:&quot;Times New Roman&quot;"><span style="font-size:12.0000pt"><span style="font-family:宋体"><font face="Times New Roman">NTP</font><font face="宋体">组件最后选用</font><font face="Times New Roman">v7.4.3</font><font face="宋体">与</font><font face="Times New Roman">Demo</font><font face="宋体">的版本一致了,</font><font face="Times New Roman">ntp.c</font><font face="宋体">中修改</font><font face="Times New Roman">_ntp_sync_time()</font><font face="宋体">函数。</font></span></span></span></span></span></p>

<pre>
<code>static int _ntp_sync_time(char *server)
{
    char               buf;
    size_t             nbytes;
    int                sockfd, maxfd1;
    struct sockaddr_in servaddr = {0,};
    fd_set             readfds;
    struct timeval   timeout, recvtv, tv, rcvtimeout = {3, 0};
    double             offset;

    servaddr.sin_family = AF_INET;
    servaddr.sin_port   = htons(NTP_PORT);

    if (server == NULL) {
      //1.cn.pool.ntp.org is more reliable
      servaddr.sin_addr.s_addr = inet_host("ntp1.aliyun.com");
      LOGD(TAG, "ntp1.aliyun.com");
    } else {
      servaddr.sin_addr.s_addr = inet_host(server);
      LOGD(TAG, "%s", server);
    }
        printf("---------------------&gt;check server done! _ntp_sync_time()\n");

    if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) &lt; 0) {
      //LOGE(TAG, "socket error");
      return -1;
    }

    setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &amp;rcvtimeout, sizeof(struct timeval));

    if (connect(sockfd, (struct sockaddr *)&amp;servaddr, sizeof(struct sockaddr)) != 0) {
      //LOGE(TAG, "connect error");
      close(sockfd);
      return -errno;
    }
        printf("---------------------&gt;connect server done! _ntp_sync_time()\n");

    nbytes = BUFSIZE;

    if (get_ntp_packet(buf, &amp;nbytes) != 0) {
      //LOGE(TAG, "construct ntp request errorr");
      close(sockfd);
      return -1;
    }

    send(sockfd, buf, nbytes, 0);
        printf("---------------------&gt;send request pack done! _ntp_sync_time()\n");

    FD_ZERO(&amp;readfds);
    FD_SET(sockfd, &amp;readfds);
    maxfd1 = sockfd + 1;

    timeout.tv_sec= TIMEOUT;
    timeout.tv_usec = 0;

    if (select(maxfd1, &amp;readfds, NULL, NULL, &amp;timeout) &gt; 0) {
      if (FD_ISSET(sockfd, &amp;readfds)) {
            if ((nbytes = recv(sockfd, buf, BUFSIZE, 0)) &lt; 0) {
                //LOGE(TAG, "recv error");
                close(sockfd);
                return -1;
            }

            //printf("nbytes = %d\n", nbytes);
            print_ntp((struct ntphdr *) buf);
            gettimeofday(&amp;recvtv, NULL);
            offset = get_offset((struct ntphdr *)buf, &amp;recvtv);

            gettimeofday(&amp;tv, NULL);
            //TODO: ctime has some problem
#if 0
            LOGD(TAG, "system time:\t%s", ctime((time_t *) &amp;tv.tv_sec));
#else
            //char *tbuf = NULL;
            //char tbuf;
            //strftime(tbuf, sizeof(tbuf), "%Y-%m-%d %T", localtime(&amp;tv.tv_sec));
            //memset(&amp;tv, 0, sizeof(tv));
            //tbuf = ctime((time_t *)&amp;tv.tv_sec);
            //LOGD(TAG, "system time1:%s", tbuf);
#endif
#if 1

            tv.tv_sec += (int)offset;
            tv.tv_usec += offset - (int)offset;

            if (settimeofday(&amp;tv, NULL) != 0) {
                //LOGE(TAG, "set time");
                close(sockfd);
                return -1;
            }
                        printf("---------------------&gt;settimeofday done! _ntp_sync_time()\n");

            //TODO: ctime has some problem
            //LOGD(TAG, "ntp time:\t%s", ctime((time_t *) &amp;tv.tv_sec));
#endif
      }
    } else {
      close(sockfd);
                printf("---------------------&gt;select body error! _ntp_sync_time()\n");
      return -1;
    }

    close(sockfd);
        printf("---------------------&gt;whole done! _ntp_sync_time()\n");
    return 0;
}</code></pre>

<p style="text-indent:24.0000pt; text-align:justify"><span style="font-size:12pt"><span style="125%"><span style="font-family:&quot;Times New Roman&quot;"><span style="font-size:12.0000pt"><span style="font-family:宋体"><font face="Times New Roman">w800_api.c</font><font face="宋体">中修改</font><font face="Times New Roman">w800_connect_remote()</font><font face="宋体">函数,增加</font><font face="Times New Roman">UDP</font><font face="宋体">分支。其中端口号是自己随意定义的,本人觉得还是单独定义端口号比较方便。</font></span></span></span></span></span></p>

<pre>
<code>int32_t udp_local_port = 1338;
int w800_connect_remote(int id, net_conn_e type, char *srvname, uint16_t port)
{
    int ret = -1;
    int ret_id;

    if (g_net_status &lt; NET_STATUS_GOTIP) {
      LOGE(TAG, "net status error\n");
      return -1;
    }

    aos_mutex_lock(&amp;g_cmd_mutex, AOS_WAIT_FOREVER);

    atparser_clr_buf(g_atparser_uservice_t);

    switch (type) {
      case NET_TYPE_TCP_SERVER:
            /* TCP Server can NOT ignore lport */
            break;

      case NET_TYPE_UDP_UNICAST:
                        printf("UDP_UNICAST mode\n");
                        ret = atparser_send(g_atparser_uservice_t, "AT+CIPSTART=%d,%s,%s,%d,%d", id, "udp_unicast", srvname, port, udp_local_port);
                        break;
                       
      case NET_TYPE_TCP_CLIENT:
                        printf("TCP_CLIENT mode\n");
            ret = atparser_send(g_atparser_uservice_t, "AT+CIPSTART=%d,%s,%s,%d", id, "tcp_client", srvname, port);
            break;

      default:
            LOGE(TAG, "type=%d err!", type);
            return -1;

    }

    if (ret == 0) {
      ret = -1;

      if ((atparser_recv(g_atparser_uservice_t, "OK\n") == 0) \
            &amp;&amp; (atparser_recv(g_atparser_uservice_t, "+EVENT=CONNECT,%d\n", &amp;ret_id) == 0)) {
            if (ret_id == id) {
                ret = 0;
            }
      }
    }

    atparser_cmd_exit(g_atparser_uservice_t);

    aos_mutex_unlock(&amp;g_cmd_mutex);

    return ret;
}</code></pre>

<p>&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<span style="font-size:12pt"><span style="125%"><span style="font-family:&quot;Times New Roman&quot;"><span style="font-size:12.0000pt"><span style="font-family:宋体"><font face="宋体">基于</font><font face="Times New Roman">Hello World Demo</font><font face="宋体">扩展,</font><font face="Times New Roman">init.c</font><font face="宋体">中添加一个</font><font face="Times New Roman">ntp</font><font face="宋体">函数,这样在</font><font face="Times New Roman">ntp</font><font face="宋体">同步后再进行传输层</font><font face="Times New Roman">input</font><font face="宋体">回调函数的注册。其中</font><font face="Times New Roman">Delay()</font><font face="宋体">函数是</font><font face="Times New Roman">Demo OLED</font><font face="宋体">驱动中定义,查询</font><font face="Times New Roman">SysTick</font><font face="宋体">的逻辑,没有用</font><font face="Times New Roman">aos_sleep()</font><font face="宋体">,是怕任务跑飞。另外,这里的延时也是为了和前面的网络初始化间隔开来,不加也可以。然后,就是网络事件回调中,在获得</font><font face="Times New Roman">IP</font><font face="宋体">即连接</font><font face="Times New Roman">AP</font><font face="宋体">后进行</font><font face="Times New Roman">ntp</font><font face="宋体">测试。目前,写到这里时还没有研究添加时区矫正和</font><font face="Times New Roman">RTC</font><font face="宋体">,后续可以在启动时做一次时间同步就好。</font></span></span></span></span></span></p>

<pre>
<code>//ntp test func
void aita_ntptest(void) {
        Delay(1000); //delay 1s then use ntp
        ntp_sync_time("ntp1.aliyun.com");
       
        //register input event callback for w800 module
        w800_packet_input_cb_register(&amp;aita_w800in_cb);
}

//network event callback function
static void network_event(uint32_t event_id, const void *param, void *context) {
    switch(event_id) {
                case EVENT_NETMGR_GOT_IP: {
                        LOGD(TAG, "EVENT_NETMGR_GOT_IP\n");
                        printf("start polling_timer. periodic: %d min\n", period);
                        aita_StartTimer;
                        aita_ntptest();
                        break;
                }
                case EVENT_NETMGR_NET_DISCON: {
                        LOGD(TAG, "EVENT_NETMGR_NET_DISCON\n");
                        printf("ready to restart wifi connection...\n");
                        aita_InitNetwork();
//                        netmgr_reset(app_netmgr_hdl, 30);
                        break;
                }       
        }
}</code></pre>

<p>&nbsp;</p>

<p>&nbsp;</p>

Jacktang 发表于 2022-4-9 17:07

<p>基于Hello World Demo扩展,init.c中添加一个ntp函数,这样在ntp同步后再进行传输层input回调函数的注册有收获,,,</p>

<p>这个必须收藏,楼主的NTP授时测试,花费了很大精力经验满满</p>

sonicfirr 发表于 2022-4-9 20:42

Jacktang 发表于 2022-4-9 17:07
基于Hello World Demo扩展,init.c中添加一个ntp函数,这样在ntp同步后再进行传输层input回调函数的注册有 ...

<p>谢谢,赞赏</p>

<p>&nbsp;</p>
页: [1]
查看完整版本: 【平头哥RVB2601创意应用开发】使用体验06 -- NTP授时