aboutsummaryrefslogtreecommitdiff
path: root/contrib/ntp/html/Oncore-SHMEM.htm
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/ntp/html/Oncore-SHMEM.htm')
-rw-r--r--contrib/ntp/html/Oncore-SHMEM.htm257
1 files changed, 257 insertions, 0 deletions
diff --git a/contrib/ntp/html/Oncore-SHMEM.htm b/contrib/ntp/html/Oncore-SHMEM.htm
new file mode 100644
index 000000000000..3148f6a9a7b9
--- /dev/null
+++ b/contrib/ntp/html/Oncore-SHMEM.htm
@@ -0,0 +1,257 @@
+<HTML>
+<HEAD>
+ <TITLE> ONCORE - SHMEM </TITLE>
+</HEAD>
+<BODY>
+<H3>
+Motorola ONCORE - The Shared Memory Interface
+</H3>
+<HR>
+
+<H4>
+Introduction
+</H4>
+
+<P>
+In NMEA mode, the Oncore GPS receiver provides the user with the same information as
+other GPS receivers.
+In BINARY mode, it can provide a lot of additional information.
+<P>
+In particular, you can ask for satellite positions, satellite health, signal levels,
+the ephemeris and the almanac, and you can set many operational parameters.
+In the case of the VP,
+you can get the pseudorange corrections necessary to act as a DGPS base station, and you can see
+the raw satellite data messages themselves.
+<P>
+When using the Oncore GPS receiver with NTP, this additional information is usually
+not available since the receiver is only talking to the oncore driver in NTPD.
+To make this information available for use in other programs,
+(say graphic displays of satellites positions, plots of SA, etc.), a shared memory interface
+(SHMEM) has been added to the refclock_oncore driver on those operating systems that support
+shared memory.
+<P>
+To make use of this information you will need an Oncore Reference Manual for the
+Oncore GPS receiver that you have. The Manual for the VP only exists as a paper
+document, the UT manuals are available as a pdf document online.
+<P>
+This interface was written by Poul-Henning Kamp (phk@FreeBSD.org), and modified by
+Reg Clemens (reg@dwf.com).
+The interface is known to work in FreeBSD, Linux, and Solaris.
+<H4>
+Activating the Interface
+</H4>
+Although the Shared Memory Interface will be compiled into the Oncore driver
+on those systems where Shared Memory is supported, to activate this interface you must
+include a <B>STATUS</B> line in the <tt>/etc/ntp.oncore</tt> data file that looks like
+<PRE>
+ STATUS < file_name >
+</PRE>
+Thus a line like
+<PRE>
+ STATUS /var/adm/ntpstats/ONCORE
+</PRE>
+would be acceptable.
+This file name will be used to access the Shared Memory.
+<P>
+In addition, one the two keywords <B>Posn2D</B> and <B>Posn3D</B> can be added to
+see @@Ea records containing the 2D or 3D position of the station (see below).
+Thus to activate the interface, and see 3D positions, something like
+<PRE>
+ STATUS /var/adm/ntpstats/ONCORE
+ Posn3D
+</PRE>
+would be required.
+<H4>
+Storage of Messages in Shared Memory
+</H4>
+With the shared memory interface, the oncore driver (refclock_oncore) allocates space
+for all of the messages that it is configured to receive, and then puts each message
+in the appropriate slot in shared memory as it arrives from the receiver.
+Since there is no easy way for a client program to know when the shared memory has
+been updated,
+a sequence number is associated with each message, and is incremented when a new message
+arrives.
+With the sequence number it is easy to check through the shared memory segment for messages that
+have changed.
+<P>
+The Oncore binary messages are kept in their full length, as described in the Reference
+manual, that is everything from the @@ prefix thru the &lt;checksum&gt;&lt;CR&gt;&lt;LF&gt;.
+<P>
+The data starts at location ONE of SHMEM (NOT location ZERO).
+<P>
+The messages are stacked in a series of variable length structures, that look like
+<PRE>
+ struct message {
+ u_int length;
+ u_char sequence;
+ u_char message[length];
+ }
+</PRE>
+<P>
+if something like that were legal.
+That is, there are two bytes (caution, these may NOT be aligned with word boundaries, so
+the field needs to be treated as a pair of u_char), that contains the length of the next
+message.
+This is followed by a u_char sequence number, that is incremented whenever a new message of
+this type is received.
+This is followed by 'length' characters of the actual message.
+<P>
+The next structure starts immediately following the last char of the previous message (no alignment).
+Thus, each structure starts a distance of 'length+3' from the previous structure.
+<P>
+Following the last structure, is a u_int containing a zero length to indicate the end
+of the data.
+<P>
+The messages are recognized by reading the headers in the data itself, viz @@Ea or whatever.
+<P>
+There are two special cases.
+<P>
+(1) The almanac takes a total of 34 submessages all starting with @@Cb. <br>
+35 slots are allocated in shared memory.
+Each @@Cb message is initially placed in the first of these locations,
+and then later it is moved to the appropriate location for that submessage.
+The submessages can be distinguished by the first two characters following the @@Cb header,
+and new data is received only when the almanac changes.
+<P>
+(2) The @@Ea message contains the calculated location of the antenna, and is received
+once per second.
+However, when in timekeeping mode, the receiver is normally put in 0D mode, with the
+position fixed, to get better accuracy.
+In 0D mode no position is calculated.
+<P>
+When the SHMEM option is active,
+and if one of <B>Posn2D</B> or <B>Posn3D</B> is specified,
+one @@Ea record is hijacked each 15s, and the receiver
+is put back in 2D/3D mode so the the current location can be determined (for position determination, or for
+tracking SA).
+The timekeeping code is careful NOT to use the time associated with this (less accurate) 2D/3D tick
+in its timekeeping functions.
+<P>
+Following the initial @@Ea message are 3 additional slots for a total of four.
+As with the almanac, the first gets filled each time a new record becomes available,
+later in the code, the message is distributed to the appropriate slot.
+The additional slots are for messages containing 0D, 2D and 3D positions.
+These messages can be distinguished by different bit patterns in the last data byte of the record.
+<H4>
+Opening the Shared Memory File
+</H4>
+The shared memory segment is accessed through a file name given on a <B>ACCESS</B> card in the
+<tt>/etc/ntp.oncore</tt> input file.
+The following code could be used to open the Shared Memory Segment:
+
+<PRE>
+ char *Buf, *file;
+ int size, fd;
+ struct stat statbuf;
+
+ file = "/var/adm/ntpstats/ONCORE"; /* the file name on my ACCESS card */
+ if ((fd=open(file, O_RDONLY)) < 0) {
+ fprintf(stderr, "Cant open %s\n", file);
+ exit(1);
+ }
+
+ if (stat(file, &statbuf) < 0) {
+ fprintf(stderr, "Cant stat %s\n", file);
+ exit(1);
+ }
+
+ size = statbuf.st_size;
+ if ((Buf=mmap(0, size, PROT_READ, MAP_SHARED, fd, (off_t) 0)) < 0) {
+ fprintf(stderr, "MMAP failed\n");
+ exit(1);
+ }
+</PRE>
+
+<H4>
+Accessing the data
+</H4>
+The following code shows how to get to the individual records.
+
+<PRE>
+ void oncore_msg_Ea(), oncore_msg_As(), oncore_msg_Bb();
+
+ struct Msg {
+ char c[5];
+ unsigned int seq;
+ void (*go_to)(uchar *);
+ };
+
+ struct Msg Hdr[] = { {"@@Bb", 0, &oncore_msg_Bb},
+ {"@@Ea", 0, &oncore_msg_Ea},
+ {"@@As", 0, &oncore_msg_As}};
+
+ void
+ read_data()
+ {
+ int i, j, k, n, iseq, jseq;
+ uchar *cp, *cp1;
+
+
+ for(cp=Buf+1; (n = 256*(*cp) + *(cp+1)) != 0; cp+=(n+3)) {
+ for (k=0; k < sizeof(Hdr)/sizeof(Hdr[0]); k++) {
+ if (!strncmp(cp+3, Hdr[k].c, 4)) { /* am I interested? */
+ iseq = *(cp+2);
+ jseq = Hdr[k].seq;
+ Hdr[k].seq = iseq;
+ if (iseq > jseq) { /* has it changed? */
+ /* verify checksum */
+ j = 0;
+ cp1 = cp+3; /* points to start of oncore response */
+ for (i=2; i < n-3; i++)
+ j ^= cp1[i];
+ if (j == cp1[n-3]) { /* good checksum */
+ Hdr[k].go_to(cp1);
+ } else {
+ fprintf(stderr, "Bad Checksum for %s\n", Hdr[k].c);
+ break;
+ }
+ }
+ }
+ }
+ if (!strncmp(cp+3, "@@Ea", 4))
+ cp += 3*(n+3);
+ if (!strncmp(cp+3, "@@Cb", 4))
+ cp += 34*(n+3);
+ }
+ }
+
+ oncore_msg_Bb(uchar *buf)
+ {
+ /* process Bb messages */
+ }
+
+ oncore_msg_Ea(uchar *buf)
+ {
+ /* process Ea messages */
+ }
+
+ oncore_msg_As(uchar *buf)
+ {
+ /* process As messages */
+ }
+</PRE>
+
+The structure Hdr contains the Identifying string for each of the messages that
+we want to examine, and the name of a program to call when a new message of that
+type is arrives.
+The loop can be run every few seconds to check for new data.
+<H4>
+Examples
+</H4>
+There are two complete examples available.
+The first plots satellite positions and the station position as affected by SA, and
+keeps track of the mean station position, so you can run it for periods of days
+to get a better station position.
+The second shows the effective horizon by watching satellite tracks.
+The examples will be found in the GNU-zipped tar file
+<A HREF=ftp://ftp.udel.edu/pub/ntp/software/OncorePlot.tar.gz>
+ftp://ftp.udel.edu/pub/ntp/software/OncorePlot.tar.gz</A>.
+<P>
+Try the new interface, enjoy.
+<HR>
+<ADDRESS>
+Reg.Clemens (reg@dwf.com),
+Poul-Henning Kamp (phk@FreeBSD.org)
+<ADDRESS>
+</BODY>
+</HTML>