Hi Richard
There are two main issues here:
- the first are the points that you make
- the second is why the clock runs off by such a lot (perhaps there is a slight error in a frequency configuration which needs to be solved?)
For the moment I will concentrate on your points since there will always be some drift - the periodicity of synchronisation is a variable.
>>Would it be reasonable to define UNDEFINED_SOCKET as -3 and then declare USOCKET TIME_TCP_socket = UNDEFINED_SOCKET;Generally sockets are initialised with -1 to distinguish them from allocated sockets (which are always positive or zero). In the case of the time server demo the socket is uninitialised - however it is initialised immediately and will not fail due to the fact that there has been a socket reserved for it in the socket pool (see TIME_SERVER_SOCKET). It may be cleaner to initialise it as you suggest. I think that your suggestion for its value is OK, although i would possibly shift the others and use -1 as default.
If you are using the socket repeatedly I wouldn't release it. I tried the following change in the seconds event in teh demo code:
if ((ulPresentTime & 0xf) == 0xf) {
fnTCP_Connect(TIME_TCP_socket, (unsigned char *)&ucTimeServers[0], TIME_PORT, 0, 0);
}
This requests the time every 16s (for test purposes).
>>Note that this would rely on whatever released TCP sockets to set TIME_TCP_socket back to UNDEFINED_SOCKET.Correct, but this is Ok since it is application code releasing the socket which also knows that it may want to use it again. As I said, I wouldn't release it because this only has advantages if another use is to be made of the socket and in the case of a regular function it may just as well keep it.
>>I noticed that fnReleaseTCP_Socket() returns either the socket number or a 0 if there is an errorYes I have just seen this. There are a couple of TCP routines which do this so make distinction between an error and an existing socket difficult. I will review and try to add some more meaningful error codes.
Now back to the fact that there is drift.
If you are using the demo code it will be using a timer event to count the seconds:
uTaskerMonoTimer( OWN_TASK, (DELAY_LIMIT)(1*SEC), E_SECOND_TICK );
If there are some functions in taking place which are blocking scheduling long enough to miss a TICK it is possible that missed TICKs will add up.
The other more mundane explanation is simply that the crystal on the board runs a bit slow.
Another possibility is that the TICK is not exact.
2 minutes in 24 hours represents about 0.14%. If the TICK timer set up is out by one it may well result in this. Some processors have periodic interrupt timers which have limited prescaler/dividers (eg teh freescale NE64) where a 34ms TICK can not be set exactly, and the best one can do is get 34.078ms TICK which obviously runs off a bit.
Since you are using the M5223X I would expect a bit better, so I checked with 60MHz PLL clock and 50ms TICK (see M5223X.c for calculations). In fact the perfect PIT divider (using 4k prescaler) is 366.2 (this is obviously rounded down to 366 or 0x16e). This tells me that in 24 hours the system TICK will in fact run fast by about 0.06% or 47seconds (if I am not mistaken).
If you need higher accuracy you could look at using the RTC in the M5223X (see
http://www.utasker.com/forum/index.php?topic=35.0 ). You can configure this to gererate a 1s interrupt which is derived from the crystal directly and so will have the crystal accuracy.
Note too - there is a register called
MCF_CLOCK_RTCDRIt is configured in M5223X.c:
MCF_CLOCK_RTCDR = (OSCCLK-1); // set RTC 1Hz frequency {10}This derives the 1Hz frequency to driver the RTC. It is also possible to adjust this value to math even the inaccuracy of the crystal to tune it to be even more accurate over long periods of time - of course not taking into account aging drifts and temperate dependency (although this could even be considered...).
Thanks for the interesting feedbak - I will make some improvements as mentioned above.
Regards
Mark