[嵌入式开发模块]NTP客户端模块(基于wiz/W5500官方io库)

本文介绍了一个基于Wiznet IO库的NTP客户端模块封装,实现了单次请求响应式的UDP协议,适用于各种需要时间同步的嵌入式系统。模块包含NTPClient.h和NTPClient.c文件,提供了NtpClient_RequestTime函数用于发送NTP请求并接收响应。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

最近因项目需要,把之前写好的NTP模块进一步封装了一下,实现了NTP客户端的逻辑。

就很简单的一个模块,稍微改一改就可以改成任何单次request&respond式的基于UDP的协议。算是一个小的示例吧。

里头的MyOS是自己弄的一个小的抽象OS层。就不放源码了,就把里头的MyOSDly改成自己的OS的休眠函数就好。

先复制黏贴好NTP模块的代码:
https://blog.youkuaiyun.com/lin_strong/article/details/90678838

接下来直接上源码:

代码

NTPClient.h

/*
******************************************************************************************
*
*                                   NTP CLIENT MODULE
*
* File : NTPClient.h
* By   : Lin Shijun(http://blog.youkuaiyun.com/lin_strong)
* Date:  2019/09/12
* Version: V1.0
* History: 
* NOTE(s): the module is to provide NTP client function based on wiznet io-library.
*          the current implementation is SNTP.
******************************************************************************************
*/

#ifndef _NTPCLIENT_H
#define _NTPCLIENT_H

/*
*******************************************************************************************
*                                       INCLUDE
*******************************************************************************************
*/

#include "NTP.h"
#include "common.h"

/*
*******************************************************************************************
*                                    CONFIGURE 主配置
*******************************************************************************************
*/

// to enable debug message
//#define NTPC_DEBUG

// set the wait time of a request
#ifndef NTPC_TIMEOUT_TIME_MS
#define NTPC_TIMEOUT_TIME_MS   100
#endif

/*
*******************************************************************************************
*                                    PUBLIC INTERFACES
*******************************************************************************************
*/

// description: launch a ntp request on given socketNum and return the respond if any.
// parameter  : socketNum   the socket number for ntp client
//              buf         the buffer for ntp client
//              serverIp    ip of the ntp server.
//              serverPort  udp port of the ntp server. 0 if default port(i.e. NTP_PORT)
//              ret         to return the result if success
// return     : TRUE        if success
//              FALSE       if fail
// note       : 
BOOL NtpClient_RequestTime(uint8_t socketNum, uint8_t *buf, uint8_t serverIp[4], 
                       uint16_t serverPort, NtpTime *ret);

#endif

NTPClient.c

/*
******************************************************************************************
*
*                                   NTP CLIENT MODULE
*
* File : NTPClient.c
* By   : Lin Shijun(http://blog.youkuaiyun.com/lin_strong)
* Date:  2019/09/12
* Version: beta
* History: 
* NOTE(s): 
******************************************************************************************
*/


/*
*******************************************************************************************
*                                       INCLUDES
*******************************************************************************************
*/

#include "NTPClient.h"
#include "socket.h"
#include "MyOS.h"

#ifndef NTPC_DEBUG
#undef _DEBUG
#endif

#include "DebugMsg.h"
/*
*******************************************************************************************
*                                        CONFIGURATION
*******************************************************************************************
*/

#ifndef NTPC_POLL_INTERVAL_MS
#define NTPC_POLL_INTERVAL_MS  10
#endif
#define NTPC_POLL_CNT ((NTPC_TIMEOUT_TIME_MS) / (NTPC_POLL_INTERVAL_MS))

/*
*******************************************************************************************
*                                 LOCAL FUNCTION DECLARATION
*******************************************************************************************
*/

#define socketNum_valid(socketNum)  ((socketNum) < _WIZCHIP_SOCK_NUM_)

/*
*******************************************************************************************
*                                       DEBUG STRINGS
*******************************************************************************************
*/

static const char *_str_NTPCErrFormat = "NTPC Err: %s.\r\n";

/*
*******************************************************************************************
*                             PUBLIC INTERFACE IMPLEMENTATIONS
*******************************************************************************************
*/

BOOL NtpClient_RequestTime(uint8_t socketNum, uint8_t *buf, uint8_t serverIp[4], 
                          uint16_t serverPort, NtpTime *ret){
  int32_t len;
  uint8_t dip[4];
  uint16_t dport;
  BOOL rst = FALSE;
  int remainPollCnt = NTPC_POLL_CNT;
  if(serverIp == NULL || ret == NULL || buf == NULL || !socketNum_valid(socketNum)){
    _dbg_printf1(_str_NTPCErrFormat, "bad param");
    return FALSE;
  }
  serverPort = (serverPort != 0)? serverPort: NTP_PORT;
  if(getSn_SR(socketNum) != SOCK_UDP)
    if(socketNum != socket(socketNum, Sn_MR_UDP, 0, 0x00)){
      _dbg_printf1(_str_NTPCErrFormat, "Open socket");
      goto bail;
    };
  len = (int32_t)NtpMsg_initRequest(buf, NULL);
  len = sendto(socketNum, buf, (uint16_t)len, serverIp, serverPort);
  if(len < 0){
    _dbg_printf1(_str_NTPCErrFormat, "sendto");
    goto bail;
  }
  _dbg_printf0("NTPC :waiting for respond\r\n");
  do{
    MyOS_DlyHMSM(0,0,0,NTPC_POLL_INTERVAL_MS);
    if(getSn_RX_RSR(socketNum) > 0){
      len = recvfrom(socketNum, buf, sizeof(NTPMSG), dip, &dport);
      // intentionly only check server ip. considering the situation that respond with another port;
      if((*(uint32_t *)dip == *(uint32_t *)serverIp) && len == sizeof(NTPMSG)){
         NtpMsg_resolveCurTimeSNTP(buf, ret);
         _dbg_printf2("NTPC : get ntptime %lu_%lu.\r\n", (unsigned long)ret->sec, (unsigned long)ret->frac);
         rst = TRUE;
         goto bail;
      }
    }
    if(getSn_SR(socketNum) != SOCK_UDP){
      _dbg_printf1(_str_NTPCErrFormat, "socket mode");
      goto bail;
    }
  }while(--remainPollCnt >= 0);
  _dbg_printf1(_str_NTPCErrFormat, "timeout");
bail:
  close(socketNum);
  return rst;
}

Debug.h

顺带附上我现在用的打印调试用的小模块。因为我用的编译器不支持可变参的宏,所以写成了按参数个数不同名字的写法。

#ifndef _DEBUG_MSG_H
#define _DEBUG_MSG_H
#include <stdio.h>
#ifdef _DEBUG
  #define _dbg_printf0(format)                   ((void)printf(format))
  #define _dbg_printf1(format,p1)                ((void)printf(format,p1))
  #define _dbg_printf2(format,p1,p2)             ((void)printf(format,p1,p2))
  #define _dbg_printf3(format,p1,p2,p3)          ((void)printf(format,p1,p2,p3))
  #define _dbg_printf4(format,p1,p2,p3,p4)       ((void)printf(format,p1,p2,p3,p4))
  #define _dbg_printf5(format,p1,p2,p3,p4,p5)    ((void)printf(format,p1,p2,p3,p4,p5))
  #define _dbg_printf6(format,p1,p2,p3,p4,p5,p6) ((void)printf(format,p1,p2,p3,p4,p5,p6))
  #define _dbg_printf7(format,p1,p2,p3,p4,p5,p6,p7) \
                ((void)printf(format,p1,p2,p3,p4,p5,p6,p7))
  #define _dbg_printf8(format,p1,p2,p3,p4,p5,p6,p7,p8) \
                ((void)printf(format,p1,p2,p3,p4,p5,p6,p7,p8))
  #define _dbg_printf9(format,p1,p2,p3,p4,p5,p6,p7,p8,p9) \
                ((void)printf(format,p1,p2,p3,p4,p5,p6,p7,p8,p9))
#else
  #define _dbg_printf0(format)
  #define _dbg_printf1(format,p1)
  #define _dbg_printf2(format,p1,p2)
  #define _dbg_printf3(format,p1,p2,p3)
  #define _dbg_printf4(format,p1,p2,p3,p4)
  #define _dbg_printf5(format,p1,p2,p3,p4,p5)
  #define _dbg_printf6(format,p1,p2,p3,p4,p5,p6)
  #define _dbg_printf7(format,p1,p2,p3,p4,p5,p6,p7)
  #define _dbg_printf8(format,p1,p2,p3,p4,p5,p6,p7,p8)
  #define _dbg_printf9(format,p1,p2,p3,p4,p5,p6,p7,p8,p9)
#endif

#endif

使用示例

如下就可以从202.112.31.197处的NTP服务器处要到当前时间:

static uint8_t ntpBuf[sizeof(NTPMSG)];
static uint8_t ntpServerIP[] = {202,112,31,197};
void NtpTask(void *p_arg){
  NtpTime time;
  Datetime dt;
  // 已省去不重要的代码
  ...
  printf("launch ntp request\r\n");
  if(NtpClient_RequestTime(NTP_SOCKET, ntpBuf, ntpServerIP, NTP_PORT,&time) == TRUE){
    NtpTime_toDatetime(time.sec, &dt);
    printf("%4u-%2u-%2u %2u:%2u:%2u\r\n",dt.yy,dt.mo,dt.dd,dt.hh,dt.mm,dt.ss);
  }else{
    printf("request time fail\r\n");
  }
  ...
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值