Close

SNTP and its integration

A project log for NTP Clock Based on STM32H735 Discovery Kit

This is an SNTP clock based on the STM32H735 Discovery Kit.

dmoisandmoisan 04/04/2021 at 00:230 Comments

Now we come to SNTP:  Simple Network Time Protocol is a well-known TCP application that retrieves a timestamp from an NTP server.  It is the simpler cousin to NTPd, the distributed time server application that runs everywhere on the Internet.  (I run an NTP server for my home network on a Beaglebone, with my own custom cape, with GPS, an RTC and an OLED display.)

LwIP comes with its own SNTP client, which is included in the  ST Microelectronics library.  As far as I can tell, it's unchanged from the official code on LwIP's Git page.

How does it work with our code?

First, let's go back to main.c, where the SNTP client is set up.

  /* Initialize the LwIP stack */
  Netif_Config();


  //
  // Look up server address
  //
  dns_init();
  ip_addr_t defaultdns;

  IP4_ADDR(&defaultdns,8,8,8,8); // Google DNS

  dns_setserver(0,&defaultdns);

//SNTPDNSResult = dns_gethostbyname(sntp_server_name,&sntp_server_address, NULL, NULL);
//  const TickType_t xDelay = 20000 / portTICK_PERIOD_MS; // 20 second delay
//  vTaskDelay(xDelay);

  IP4_ADDR(&sntp_server_address,108,61,73,244);
  sntp_setoperatingmode(SNTP_OPMODE_POLL);
  sntp_setserver(0,&sntp_server_address);
  sntp_init();

 DNS has to be enabled in opts.h.  I ran into trouble getting SNTP to enable DNS lookups, so this DNS code ultimately didn't work.  I hard-coded a public SNTP server, 0.us.pool.ntp.org, with one of its IP addresses, 108.61.73.244.  (The pool.ntp.org servers use round-robin DNS, so that 0.us.pool.ntp.org will present several other IP's besides 108.61.73.244.)

Moving on, we set the operating mode to SNTP_OPMODE_POLL, set the client to use the IP address we just defined as a server.  Then sntp_init kicks it off.  But, we need to change the code in sntp.c itself to include a callback to our code that SNTP can refer to when it retrieves a timestamp.  This is where I had a bad time.

In LwIP, and as in every library, one needs to tweak parameters, and enable or disable features as needed for their project.  In C, we use the preprocessor #define directive:

# main.h
#define TURNONFEATURE     1
#define MYFUNCTIONCALLBACK  MyCallback(int functionthings);
...
...
In main.c:
#ifdef TURNONFEATURE
...some enabling code...
#endif
...
...
MYFUNCTIONCALLBACK

At least, this was the mental model I had in my head.  I put my defines in sntpopts.h, and declared sntpopts.h in every place I could find where my code would work with SNTP.

Didn't work.  I searched online, and there were just a few people using the code.  One person said the code was not well documented.  It's the story of our lives, at least as I can see as a IT professional. 

I did something ugly, and altered my copy of sntp.c directly.  It felt wrong.  It felt like writing in a library book.

//
// External function prototypes
//

extern void SNTPSetTicks(uint64_t sec);
extern void SNTPGetTicks(uint64_t sec, int us);

...
...


//  SNTP_SET_SYSTEM_TIME_NTP(sec, frac); // line 332 in sntp.c, original
  SNTPSetTicks((u32_t)sec); //line 332 in sntp.c, my change
 

Around line 332, is our callback function, SNTPSetTicks.  (SNTPGetTicks is defined, but not used.  It's there to allow SNTP to compute a roundtrip time to the server.  For my application, I didn't need this extra complexity.)

The actual callback is a very short function in ntpdisplaytasks.c:

extern void SNTPSetTicks(uint64_t sec, uint64_t us) {
    // This is a callback function that is defined by a macro in sntp_opts.h
    // Update the SecondsCounter

    SecondsCounter = sec;
    }

All this function does is step our seconds counter with the seconds count in the timestamp.  We don't use the microseconds (us) variable.  We don't discipline our clock timer because this is just a display clock and I don't know how to do this like ntpd does.   My Twatch clock worked the same way.

That's it for the network part of my clock.  My next few entries will go into the display on the clock, and the LCD functions available on the STM32H735 Discovery Kit. Til next time.

Discussions