[嵌入式开发模块]NTP客户端模块(基于wiz/W5500官方io库)
文章目录
- 前言
- 代码
- NTPClient.h
- NTPClient.c
- Debug.h
- 使用示例
前言
最近因项目需要,把之前写好的NTP模块进一步封装了一下,实现了NTP客户端的逻辑。
就很简单的一个模块,稍微改一改就可以改成任何单次request&respond式的基于UDP的协议。算是一个小的示例吧。
里头的MyOS是自己弄的一个小的抽象OS层。就不放源码了,就把里头的MyOSDly改成自己的OS的休眠函数就好。
先复制黏贴好NTP模块的代码:
https://blog.csdn.net/lin\_strong/article/details/90678838
接下来直接上源码:
代码
NTPClient.h
/*
******************************************************************************************
*
* NTP CLIENT MODULE
*
* File : NTPClient.h
* By : Lin Shijun(http://blog.csdn.net/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.csdn.net/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");
}
...
}
还没有评论,来说两句吧...