Skip to main content
richardh
Associate III
May 20, 2020
Question

LWIP SNTP, what does it actually do?

  • May 20, 2020
  • 9 replies
  • 9436 views

I am looking in to implimenting a SNTP client on an embedded board, I am using the STM32CubeIDE so its a checkbox to enable SNTP, but I can find no documentation or examples on what you do from there.

I can see functions to enable/disable SNTP, but not to read anything or write anything....

Does anyone have some pointers about what/how it works? or even an example?

I have hunted the web, lots say how easy it is, just look at RFC4330 (which I have) etc, but I can only presume I am missing something completely.

This topic has been closed for replies.

9 replies

kurta999
Senior
May 22, 2020
Tesla DeLorean
Guru
May 22, 2020

Yes, SNTP is easy, you send an empty packet, and get a time stamped packet back. If latency is low it is great for just setting a 1 Second RTC

Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
richardh
richardhAuthor
Associate III
May 23, 2020

but how do I actually read the time the LWIP returns? I understand I have to set the operating mode and the server IP address then call sntp_init() but how is the time actually returned from LWIP? is it stored in an integer? is it written directly to the RTC? I think thats what I am missing?

Its okay saying its easy, everything is once you know the answer ;)

DMois.1
Associate III
January 14, 2021

There are two changes you need to make in sntp.c:

1) You need to redefine the macro SNTP_SET_SYSTEM_TIME to a function in your code that sets the time, or resets the tick counter. My code maintains its own tick counter, and this function resets it to what comes back from the SNTP request.

2) Your code needs to periodically call sys_check_timeouts(). This is the routine that invokes the SNTP client. My SNTP client runs under FreeRTOS, so I set a timer that invokes this routine every few minutes.

Piranha
Principal III
January 16, 2021

Calling sys_check_timeouts() is necessary only for NO_SYS==1. For RTOS with NO_SYS==0 the timeouts are processed by lwIP code internally.

https://www.nongnu.org/lwip/2_1_x/group__lwip__nosys.html#ga83cffdf69ab60fd0eba9d17d363f9883

DMois.1
Associate III
January 18, 2021

Yeah, confirmed. In my device, I have FreeRTOS running a timer task once a second that increments the seconds, and displays time, and another that updates sys_check_timeouts(). I commented out the latter timer, and SNTP still fires. Thanks.

QRobe.1
Associate II
June 24, 2022

Hello, I was wondering if you have succeeded in implementing a SNTP Client. I am trying to do the same and there is not so much information on internet.

I am using the STM32H745I board and I am able to ping through Ethernet, without OS. From what I have understood so far, I am supposed to redefine a macro called SNTP_SET_SERVER_TIME. Am I supposed to this in the file lwipopts.h or sntp.c ? . Then, the prototype is defined in the main.c for setting the time.

In the main.c, three functions are called :

- sntp_setoperatingmode(SNTP_OPMODE_POLL);

- sntp_setservername(0, "pool.ntp.org");

- sntp_init();

And in the main loop, there are two functions called :

- ethernetif_input(&gnetif);

- sys_check_timeouts();

It seems that the prototype of the function is never called, do you have any ideas or advice to give ?

richardh
richardhAuthor
Associate III
June 24, 2022

never got it working as could never get my head around it, everyone was super helpful but didn't actually explain it well enough to get it doing anything sensible sadly.

QRobe.1
Associate II
June 24, 2022

Okay, thanks for replying ! hope someone else will read this topic again and can give some help. I actually have found two "examples" on chinese forums, if you're interested in them, I will link it to you.

AJohn.14
Visitor II
June 1, 2023

Edited:

Is this still open ?

Please guide me to get more info or a straight forward example.

Thanks in advance.

AJohn.14
Visitor II
June 8, 2023

Hi all,

First of all thanks to all of you and a big one to @Piranha​. I am able to make it work.

But still I have issues.

I am able to get correct MM:SS and Month.

HH and Date I adjusted.

Year not able to fix.

See below,

/**
 * @brief set time from STNP
 */
void ethernet_task_SetTimestamp(uint32_t seconds, uint32_t fractional)
{
	ethernet_task_timestamp 		= seconds;
	ethernet_task_timestampValid 	= 1;
	ethernet_task_timestampOffset 	= HAL_GetTick();
	ethernet_task_timestampms 		= 1000 * (uint64_t)seconds + fractional / 4294967;
	ethernet_task_timestampCount++;
 
	common_TimeDateClass timeDate;
 
	time_t unixTimestamp 	= (time_t)(ethernet_task_timestampms / 1000);
	struct tm* timeinfo 	= gmtime(&unixTimestamp); 	// or localtime(&unixTimestamp) for local time
 
	timeDate.date.year 		= timeinfo->tm_year + 1900; // Years since 1900
	timeDate.date.month 	= static_cast<common_DateMonthEnum>(timeinfo->tm_mon + 1); // Months since January (0-11)
	timeDate.date.date 		= timeinfo->tm_mday + 1; // Day of the month (1-31)
	timeDate.time.hour 		= timeinfo->tm_hour + 1; // Hours since midnight (0-23)
	timeDate.time.minute 	= timeinfo->tm_min; // Minutes after the hour (0-59)
	timeDate.time.second 	= timeinfo->tm_sec; // Seconds after the minute (0-61)
 
	commonAPI_SetTime_SNTP(&timeDate.time);		// RTC write time
	commonAPI_SetDate_SNTP(&timeDate.date);		// RTC write date
 
}

above is my

SNTP_SET_SYSTEM_TIME_NTP()

function. But it has following adjustments.

	timeDate.date.year 		= timeinfo->tm_year + 1900; // Years since 1900
 
	timeDate.date.date 		= timeinfo->tm_mday + 1; // Day of the month (1-31)
	timeDate.time.hour 		= timeinfo->tm_hour + 1; // Hours since midnight (0-23)

As I mentioned already, for 'date' and 'HH' I added addtional value '1' to the orginal value. and for year I am getting '2065' for '2023'.

Kindly advice what am doing wrong.

Thanks in advance.