changeset 748:d21da3c91474

First import of the Simple Network Time Protocol client.
author asl
date Tue, 25 Feb 2003 14:42:21 +0000
parents 95c190a63a7e
children 800af3130c76
files packages/net/sntp/current/ChangeLog packages/net/sntp/current/cdl/sntp.cdl packages/net/sntp/current/doc/sntp.sgml packages/net/sntp/current/include/sntp.h packages/net/sntp/current/src/sntp.c packages/net/sntp/current/tests/sntp1.c
diffstat 6 files changed, 633 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
new file mode 100644
--- /dev/null
+++ b/packages/net/sntp/current/ChangeLog
@@ -0,0 +1,42 @@
+2003-02-16  Andrew Lunn  <andrew.lunn@ascom.ch>
+
+	* src/sntp.c: First import of SNTP client code.
+	* include/sntp.c: Ditto
+	* test/sntp1.c: Ditto
+	* cdl/sntp.cdl: Ditto
+	* doc/sntp.sgml: Ditto
+
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2003 Andrew Lunn
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
new file mode 100644
--- /dev/null
+++ b/packages/net/sntp/current/cdl/sntp.cdl
@@ -0,0 +1,103 @@
+# ====================================================================
+#
+#      sntp.cdl
+#
+#      Simple Network Time Protocol
+#
+# ====================================================================
+######ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 2003 Andrew Lunn
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+## WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License along
+## with eCos; if not, write to the Free Software Foundation, Inc.,
+## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+##
+## As a special exception, if other files instantiate templates or use macros
+## or inline functions from this file, or you compile this file and link it
+## with other works to produce a work based on this file, this file does not
+## by itself cause the resulting work to be covered by the GNU General Public
+## License. However the source code for this file must still be made available
+## in accordance with section (3) of the GNU General Public License.
+##
+## This exception does not invalidate any other reasons why a work based on
+## this file might be covered by the GNU General Public License.
+##
+## Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+## at http://sources.redhat.com/ecos/ecos-license/
+## -------------------------------------------
+######ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s):      Andrew Lunn
+# Contributors:
+# Date:           2003-02-11
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_NET_SNTP {
+    display       "Simple Network Time Protocol Client (SNTP)"
+    description   "
+                  This package provides an SNTP client which will recieve
+		  SNTP broadcasts and set the system clock to the correct
+		  time."
+    doc           ref/net-sntp.html
+    include_dir   cyg/sntp
+
+    requires      CYGPKG_NET
+    requires      CYGPKG_ISO_TIME
+
+    compile       sntp.c
+    
+    cdl_component CYGPKG_NET_SNTP_OPTIONS {
+        display "SNTP support build options"
+        flavor  none
+        no_define
+
+        cdl_option CYGPKG_NET_SNTP_CFLAGS_ADD {
+            display "Additional compiler flags"
+            flavor  data
+            no_define
+            default_value { "-D_KERNEL -D__ECOS" }
+            description   "
+                This option modifies the set of compiler flags for
+                building the SNTP package.
+                These flags are used in addition
+                to the set of global flags."
+        }
+
+        cdl_option CYGPKG_NET_SNTP_CFLAGS_REMOVE {
+            display "Suppressed compiler flags"
+            flavor  data
+            no_define
+            default_value { "" }
+            description   "
+                This option modifies the set of compiler flags for
+                building the SNTP package. These flags are removed from
+                the set of global flags if present."
+        }
+    }
+
+    cdl_option CYGPKG_NET_SNTP_TESTS {
+        display "sntp tests"
+        flavor  data
+        no_define
+        calculated { "tests/sntp1.c" }
+    }
+}
+
+# ====================================================================
+# EOF sntp.cdl
new file mode 100644
--- /dev/null
+++ b/packages/net/sntp/current/doc/sntp.sgml
@@ -0,0 +1,100 @@
+<PART ID="net-sntp">
+<TITLE>Simple Network Time Protocol Client</TITLE>
+<PARTINTRO>
+<PARA>
+The SNTP package provides implementation of a client for RFC 2030, the
+Simple Network Time Protocol (SNTP). The client listens for broadcasts
+from an NTP server and uses the information received to set the system
+clock.
+</PARA>
+</PARTINTRO>
+<CHAPTER id="sntp-the">
+<TITLE>The SNTP Client</TITLE>
+<SECT1 id="sntp-starting">
+<TITLE>Starting the SNTP client</TITLE>
+<para>
+The sntp client is implemented as a thread which listens for NTP
+broadcasts. This thread is not automatically start by the
+system. Instead it must be started by the user application. The header
+file <filename>cyg/sntp/sntp.h</filename> declares the function to be
+called.  The thread is then started by calling the function:
+</para>
+<programlisting>
+void cyg_sntp_start(void);
+</programlisting>
+<para>
+
+Once started, the thread will run forever.
+</sect1>
+
+<sect1 id="net-sntp-operation">
+<title>What it does</title>
+<para>
+The SNTP client listens for NTP broadcasts from any NTP servers. Such
+broadcasts contain a timestamp indicating the current time. The packet
+also contains information about where the server is in the hierarchy
+of time servers. A server at the root of the time server tree normally
+has an atomic clock. Such a server is said to be at stratum 0. A time
+server which is synchronised to a stratum 0 server is said to be at
+stratum 1 etc. The client will accept any NTP broadcast packets from
+servers using version 3 or 4 of the protocol. When receiving packets
+from multiple servers, it will use the packets from the server with
+the lowest stratum. However, if there are no packets from this server
+for 10 minute and another server is broadcasting, the client will
+change server.
+</para>
+<para>
+The system clock in eCos is accurate to 1 second. The SNTP client will
+change the system clock when the time difference with the received
+timestamp is greater than 2 seconds. The change is made as a step. 
+</para>
+</sect1>
+
+<sect1 id="net-sntp-warning">
+<title>Warning: timestamp wrap around</title>
+<para>
+The timestamp in the NTP packet is a 32bit integer which represents
+the number of seconds after 00:00 01/01/1900. This 32bit number will
+wrap around at 06:28:16 Feb 7 2036. At this point in time, the eCos
+time will jump back to around 00:00:00 Jan 1 1900 when the next
+broadcast is received. 
+</para>
+<para>
+YOU HAVE BEEN WARNED!
+</para>
+</SECT1>
+<sect1 id="net-sntp-testing">
+<title>The SNTP test program</title>
+<para>
+The SNTP package contains a simple test program. Testing an SNTP
+client is not easy, so the test program should be considered as more a
+proof of concept. It shows that a broadcast packet has been received,
+at is accurate to within a few days. 
+</para>
+<para>
+The test program starts the network interfaces using the standard
+call. It then starts the SNTP thread. A loop is then entered printing
+the current system time every second for two minutes. When the client
+receives a broadcast the time will jump from 1970 to hopefully the
+present day. Once the two minutes have expired, two simple tests are
+made. If the time is still less than 5 minutes since 00:00:00
+01/01/1970 the test fails. This indicates no broadcast messages have
+been received. Check that the server is actually broadcasting, using
+the correct port (123), and at a sufficiently frequent rate that the
+target has a chance to receive a message within the 2 minute
+interval. If all this is correct, assume the target is broken. 
+</para>
+<para>
+The second test is that the current system time is compared with the
+build time as reported by the CPP macro __DATE__. If the build date is
+in the future relative to the system time, the test fails. If the
+build date is more than 10 days in the past relative to the system
+time the test also fails. If such failures are seen, use walk-clock
+time to verify the time printed during the test. If this seems correct
+check the build date for the test. This is printed at startup. If all
+else fails check that the computer used to build the test has the
+correct time. 
+</para>
+</SECT1>
+</CHAPTER>
+</PART>
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/packages/net/sntp/current/include/sntp.h
@@ -0,0 +1,56 @@
+#ifndef CYGONCE_SNTP_SNTP_H
+#define CYGONCE_SNTP_SNTP_H
+//=============================================================================
+//
+//      sntp.h
+//
+//      SNTP - Simple Network Time Protocol
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2003 Andrew Lunn
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):   andrew.lunn
+// Contributors:
+// Date:        2003-02-11
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+/* Call this function to start the SNTP Client */
+void cyg_sntp_start(void);
+
+#endif
new file mode 100644
--- /dev/null
+++ b/packages/net/sntp/current/src/sntp.c
@@ -0,0 +1,197 @@
+//=============================================================================
+//
+//      sntp.c
+//
+//      Simple Network Time Protocol
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2003 Andrew Lunn
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):   andrew.lunn
+// Contributors:
+// Date:        2003-02-12
+// Description: Provides a Simple Network Time Protocol Client
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <network.h>
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/sntp/sntp.h>
+#include <time.h>
+
+#define VERSION_MASK   0x38000000
+#define VERSION_SHIFT  27
+#define MODE_MASK      0x07000000
+#define MODE_SHIFT     24
+#define STRATUM_MASK   0x00ff0000
+#define STRATUM_SHIFT  16
+
+#define MODE_BROADCAST 5
+
+struct sntp_srv_s {
+  struct sockaddr_in addr;
+  int stratum;
+  int version;
+  cyg_uint32 timestamp;
+};
+
+#define SECONDSPERMINUTE (cyg_uint32)60
+#define SECONDSPERHOUR   (cyg_uint32)(SECONDSPERMINUTE * 60)
+#define SECONDSPERDAY    (cyg_uint32)(SECONDSPERHOUR * 24)
+#define SECONDSPERYEAR   (cyg_uint32)(SECONDSPERDAY * 365)
+
+/* Convert a SNTP timestamp to a time_t. timestamps are seconds from
+   1/1/1900. time_t is 1/1/1970.  That equates to 70 years, or which
+   17 were leap years.*/
+static time_t timestamp2time(cyg_uint32 timestamp) {
+  
+  return timestamp - 
+    (SECONDSPERYEAR *  (cyg_uint32)(70)) -
+    (SECONDSPERDAY * (cyg_uint32)(17));
+}
+
+/* Is the new server better than the current one? If its the same as
+   the current, its always better. If the stratum is lower its better.
+   If we have not heard from the old server for more than 10 minutes,
+   the new server is better. */
+
+static int is_better(struct sntp_srv_s *newer, struct sntp_srv_s *old) {
+   
+  time_t last_time, diff;
+  
+  if (newer->addr.sin_addr.s_addr == old->addr.sin_addr.s_addr) return 1;
+  if (newer->stratum < old->stratum) return 1;
+
+  if (old->timestamp != 0xffffffff) {
+    last_time = timestamp2time(old->timestamp);
+  
+    diff = time(NULL) - last_time;
+    if (diff > 600) return 1;
+    
+    return 0;
+  }
+  return 1;
+}
+
+static void sntp_fn(cyg_addrword_t data) {
+  int fd;
+  int ret;
+  struct sockaddr_in local;
+  struct servent *serv;
+  cyg_uint32 buf[12];
+  struct sntp_srv_s new_srv;
+  struct sntp_srv_s best_srv;
+  int mode;
+  int len;
+  time_t new_time, current_time, diff;
+
+  memset(&best_srv,0xff,sizeof(best_srv));
+
+  fd = socket(AF_INET,SOCK_DGRAM,0);
+  CYG_ASSERT(-1 != fd,"Failed to open socket");
+
+  serv = getservbyname("ntp","udp");
+  CYG_ASSERT(serv,"getservbyname(sntp,udp)");
+
+  memset(&local,0,sizeof(local));
+  local.sin_family = AF_INET;
+  local.sin_port = serv->s_port;
+  local.sin_addr.s_addr = INADDR_ANY;
+  
+  ret=bind(fd,(struct sockaddr *)&local,sizeof(local));
+  CYG_ASSERT(0 == ret, "Bind failed");
+
+  while (1) {
+    len = sizeof(new_srv.addr);
+    ret=recvfrom(fd,buf,sizeof(buf),0,(struct sockaddr *)&new_srv.addr,&len);
+    CYG_ASSERT(0 < ret,"recvfrom");
+
+    /* We expect at least enough bytes to fill the buffer. There could
+       be more if there is a digest, but we ignore that. */
+    if (ret < sizeof(buf))
+      continue;
+    
+    new_srv.version = (htonl(buf[0]) & VERSION_MASK) >> VERSION_SHIFT;
+    new_srv.stratum = (htonl(buf[0]) & STRATUM_MASK) >> STRATUM_SHIFT;
+    new_srv.timestamp = htonl(buf[10]);
+    mode = (htonl(buf[0]) & MODE_MASK) >> MODE_SHIFT;
+    
+    /* Only support protocol versions 3 or 4 */
+    if (new_srv.version < 3 || new_srv.version > 4) 
+      continue;
+    
+    /* Only process broadcast packet */
+    if (mode != MODE_BROADCAST) 
+      continue;
+    
+    /* Is the packet from a better server than our current one */
+    if (is_better(&new_srv,&best_srv)) {
+      best_srv = new_srv;
+
+      /* Work out the difference between server and our time */
+      new_time = timestamp2time(best_srv.timestamp);
+      current_time = time(NULL);
+      diff = current_time - new_time;
+      
+      if (diff < 0) 
+	diff = -diff;
+      
+      if (diff > 2) 
+	cyg_libc_time_settime(new_time);
+    }
+  }
+}
+
+/* Start the SNTP server */
+void cyg_sntp_start(void) {
+  
+  static char sntp_stack[CYGNUM_HAL_STACK_SIZE_TYPICAL];
+  static cyg_thread sntp_thread_data;
+  static cyg_handle_t sntp_handle;
+
+  cyg_thread_create(CYGPKG_NET_THREAD_PRIORITY+1, 
+		    sntp_fn,               // entry
+		    0,                     // entry parameter
+		    "sntp",                // Name
+		    &sntp_stack,           // stack
+		    sizeof(sntp_stack),    // stack size
+		    &sntp_handle,          // Handle
+		    &sntp_thread_data);    // Thread data structure
+
+  cyg_thread_resume(sntp_handle);
+}
new file mode 100644
--- /dev/null
+++ b/packages/net/sntp/current/tests/sntp1.c
@@ -0,0 +1,135 @@
+//=================================================================
+//
+//        sntp1.c
+//
+//        Simple Network Time Protocol test 1
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2003 Andrew Lunn
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):     Andrew Lunn
+// Contributors:  
+// Date:          2003-02-11
+// Description:   Tests the sntp client
+//####DESCRIPTIONEND####
+
+#include <network.h>
+#include <cyg/infra/testcase.h>
+#include <time.h>
+#include <cyg/sntp/sntp.h>
+#include <stdio.h>
+
+#define SECONDSPERMINUTE (cyg_uint32)60
+#define SECONDSPERHOUR   (cyg_uint32)(SECONDSPERMINUTE * 60)
+#define SECONDSPERDAY    (cyg_uint32)(SECONDSPERHOUR * 24)
+#define SECONDSPERYEAR   (cyg_uint32)(SECONDSPERDAY * 365)
+
+void
+net_test(cyg_addrword_t param)
+{
+  int seconds;
+  time_t now, build_time;
+  struct tm tm={ 0,0,0,0,0,0,0,0,0 };
+  int i;
+  char month[4];
+  char months[12][4] = { "Jan", "Feb", "Mar", 
+			 "Apr", "May", "Jun", 
+			 "Jul", "Aug", "Sep",
+			 "Oct", "Nov", "Dec" };
+  
+  CYG_TEST_INIT();
+
+  CYG_TEST_INFO("sntp1 test build " __DATE__);
+
+  init_all_network_interfaces();
+
+  cyg_sntp_start();
+
+  for (seconds = 120; seconds > 0; seconds--) {
+    now = time(NULL);
+    CYG_TEST_INFO(ctime(&now));
+    cyg_thread_delay(100);
+  }
+  
+  now = time(NULL);
+
+  if ( now < (5 * 60)) {
+    CYG_TEST_FAIL_FINISH("Nothing recieved from the SNTP server");
+  } else {
+    
+    i=sscanf(__DATE__, "%s %d %d",month,&tm.tm_mday,&tm.tm_year);
+    CYG_ASSERT(3==i,"sscanf did not return enough results");
+    for (i=0; i < 12; i++) {
+      if (!strcmp(month,months[i])) 
+	break;
+    }
+    tm.tm_mon = i;
+    tm.tm_mday++;
+
+    build_time = mktime(&tm);
+    CYG_ASSERT(-1 != build_time,"mktime returned -1");
+
+    if (build_time > time(NULL)) {
+      CYG_TEST_FAIL_FINISH("Build time is ahead of SNTP time");
+    } else {
+      if ((build_time + 60 * 60 * 24 * 10) > time(NULL)) {
+	CYG_TEST_FAIL_FINISH("Build time is more than 10 days old");
+      }
+    }
+  }
+  CYG_TEST_FINISH("sntp1 test is complete");
+}
+
+#define STACK_SIZE (CYGNUM_HAL_STACK_SIZE_TYPICAL*2)
+static char thread_stack[STACK_SIZE];
+static cyg_thread thread_data;
+static cyg_handle_t thread_handle;
+
+void
+cyg_user_start(void)
+{
+    // Create a main thread, so we can run the scheduler and have time 'pass'
+    cyg_thread_create(10,                  // Priority - just a number
+                      net_test,            // entry
+                      0,                   // entry parameter
+                      "Network test",      // Name
+                      thread_stack,        // Stack
+                      STACK_SIZE,          // Size
+                      &thread_handle,      // Handle
+                      &thread_data         // Thread data structure
+            );
+    cyg_thread_resume(thread_handle);      // Start it
+}