~ubuntu-branches/debian/squeeze/ntp/squeeze-201010051545

« back to all changes in this revision

Viewing changes to html/Oncore-SHMEM.htm

  • Committer: Bazaar Package Importer
  • Author(s): Matt Zimmerman
  • Date: 2004-10-11 16:10:27 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20041011161027-icyjbji8ujym633o
Tags: 1:4.2.0a-10ubuntu2
Use ntp.ubuntulinux.org instead of pool.ntp.org

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
<HTML>
2
 
<HEAD>
3
 
    <TITLE> ONCORE - SHMEM </TITLE>
4
 
</HEAD>
5
 
<BODY>
6
 
<H3>
7
 
Motorola ONCORE - The Shared Memory Interface
8
 
</H3>
9
 
<HR>
10
 
 
11
 
<H4>
12
 
Introduction
13
 
</H4>
14
 
 
15
 
<P>
16
 
In NMEA mode, the Oncore GPS receiver provides the user with the same information as
17
 
other GPS receivers.
18
 
In BINARY mode, it can provide a lot of additional information.
19
 
<P>
20
 
In particular, you can ask for satellite positions, satellite health, signal levels,
21
 
the ephemeris and the almanac, and you can set many operational parameters.
22
 
In the case of the VP,
23
 
you can get the pseudorange corrections necessary to act as a DGPS base station, and you can see
24
 
the raw satellite data messages themselves.
25
 
<P>
26
 
When using the Oncore GPS receiver with NTP, this additional information is usually
27
 
not available since the receiver is only talking to the oncore driver in NTPD.
28
 
To make this information available for use in other programs,
29
 
(say graphic displays of satellites positions, plots of SA, etc.), a shared memory interface
30
 
(SHMEM) has been added to the refclock_oncore driver on those operating systems that support
31
 
shared memory.
32
 
<P>
33
 
To make use of this information you will need an Oncore Reference Manual for the
34
 
Oncore GPS receiver that you have.  The Manual for the VP only exists as a paper
35
 
document, the UT manuals are available as a pdf document online.
36
 
<P>
37
 
This interface was written by Poul-Henning Kamp (phk@FreeBSD.org), and modified by
38
 
Reg Clemens (reg@dwf.com).
39
 
The interface is known to work in FreeBSD, Linux, and Solaris.
40
 
<H4>
41
 
Activating the Interface
42
 
</H4>
43
 
Although the Shared Memory Interface will be compiled into the Oncore driver
44
 
on those systems where Shared Memory is supported, to activate this interface you must
45
 
include a <B>STATUS</B> line in the <tt>/etc/ntp.oncore</tt> data file that looks like
46
 
<PRE>
47
 
        STATUS < file_name >
48
 
</PRE>
49
 
Thus a line like
50
 
<PRE>
51
 
        STATUS /var/adm/ntpstats/ONCORE
52
 
</PRE>
53
 
would be acceptable.
54
 
This file name will be used to access the Shared Memory.
55
 
<P>
56
 
In addition, one the two keywords <B>Posn2D</B> and <B>Posn3D</B> can be added to
57
 
see @@Ea records containing the 2D or 3D position of the station (see below).
58
 
Thus to activate the interface, and see 3D positions, something like
59
 
<PRE>
60
 
        STATUS /var/adm/ntpstats/ONCORE
61
 
        Posn3D
62
 
</PRE>
63
 
would be required.
64
 
<H4>
65
 
Storage of Messages in Shared Memory
66
 
</H4>
67
 
With the shared memory interface, the oncore driver (refclock_oncore) allocates space
68
 
for all of the messages that it is configured to receive, and then puts each message
69
 
in the appropriate slot in shared memory as it arrives from the receiver.
70
 
Since there is no easy way for a client program to know when the shared memory has
71
 
been updated,
72
 
a sequence number is associated with each message, and is incremented when a new message
73
 
arrives.
74
 
With the sequence number it is easy to check through the shared memory segment for messages that
75
 
have changed.
76
 
<P>
77
 
The Oncore binary messages are kept in their full length, as described in the Reference
78
 
manual, that is everything from the @@ prefix thru the &lt;checksum&gt;&lt;CR&gt;&lt;LF&gt;.
79
 
<P>
80
 
The data starts at location ONE of SHMEM (NOT location ZERO).
81
 
<P>
82
 
The messages are stacked in a series of variable length structures, that look like
83
 
<PRE>
84
 
        struct message {
85
 
                u_int   length;
86
 
                u_char  sequence;
87
 
                u_char  message[length];
88
 
        }
89
 
</PRE>
90
 
<P>
91
 
if something like that were legal.
92
 
That is, there are two bytes (caution, these may NOT be aligned with word boundaries, so
93
 
the field needs to be treated as a pair of u_char), that contains the length of the next
94
 
message.
95
 
This is followed by a u_char sequence number, that is incremented whenever a new message of
96
 
this type is received.
97
 
This is followed by 'length' characters of the actual message.
98
 
<P>
99
 
The next structure starts immediately following the last char of the previous message (no alignment).
100
 
Thus, each structure starts a distance of 'length+3' from the previous structure.
101
 
<P>
102
 
Following the last structure, is a u_int containing a zero length to indicate the end
103
 
of the data.
104
 
<P>
105
 
The messages are recognized by reading the headers in the data itself, viz @@Ea or whatever.
106
 
<P>
107
 
There are two special cases.
108
 
<P>
109
 
(1) The almanac takes a total of 34 submessages all starting with @@Cb.  <br>
110
 
35 slots are allocated in shared memory.
111
 
Each @@Cb message is initially placed in the first of these locations,
112
 
and then  later it is moved to the appropriate location for that submessage.
113
 
The submessages can be distinguished by the first two characters following the @@Cb header,
114
 
and new data is received only when the almanac changes.
115
 
<P>
116
 
(2) The @@Ea message contains the calculated location of the antenna, and is received
117
 
once per second.
118
 
However, when in timekeeping mode, the receiver is normally put in 0D mode, with the
119
 
position fixed, to get better accuracy.
120
 
In 0D mode no position is calculated.
121
 
<P>
122
 
When the SHMEM option is active,
123
 
and if one of <B>Posn2D</B> or <B>Posn3D</B> is specified,
124
 
one @@Ea record is hijacked each 15s, and the receiver
125
 
is put back in 2D/3D mode so the the current location can be determined (for position determination, or for
126
 
tracking SA).
127
 
The timekeeping code is careful NOT to use the time associated with this (less accurate) 2D/3D tick
128
 
in its timekeeping functions.
129
 
<P>
130
 
Following the initial @@Ea message are 3 additional slots for a total of four.
131
 
As with the almanac, the first gets filled each time a new record becomes available,
132
 
later in the code, the message is distributed to the appropriate slot.
133
 
The additional slots are for messages containing 0D, 2D and 3D positions.
134
 
These messages can be distinguished by different bit patterns in the last data byte of the record.
135
 
<H4>
136
 
Opening the Shared Memory File
137
 
</H4>
138
 
The shared memory segment is accessed through a file name given on a <B>ACCESS</B> card in the
139
 
<tt>/etc/ntp.oncore</tt> input file.
140
 
The following code could be used to open the Shared Memory Segment:
141
 
 
142
 
<PRE>
143
 
        char *Buf, *file;
144
 
        int size, fd;
145
 
        struct stat statbuf;
146
 
 
147
 
        file = "/var/adm/ntpstats/ONCORE";  /* the file name on my ACCESS card */
148
 
        if ((fd=open(file, O_RDONLY)) < 0) {
149
 
                fprintf(stderr, "Cant open %s\n", file);
150
 
                exit(1);
151
 
        }
152
 
 
153
 
        if (stat(file, &statbuf) < 0) {
154
 
                fprintf(stderr, "Cant stat %s\n", file);
155
 
                exit(1);
156
 
        }
157
 
 
158
 
        size = statbuf.st_size;
159
 
        if ((Buf=mmap(0, size, PROT_READ, MAP_SHARED, fd, (off_t) 0)) < 0) {
160
 
                fprintf(stderr, "MMAP failed\n");
161
 
                exit(1);
162
 
        }
163
 
</PRE>
164
 
 
165
 
<H4>
166
 
Accessing the data
167
 
</H4>
168
 
The following code shows how to get to the individual records.
169
 
 
170
 
<PRE>
171
 
        void    oncore_msg_Ea(), oncore_msg_As(), oncore_msg_Bb();
172
 
 
173
 
        struct Msg {
174
 
            char         c[5];
175
 
            unsigned int seq;
176
 
            void         (*go_to)(uchar *);
177
 
        };
178
 
 
179
 
        struct Msg Hdr[] = { {"@@Bb", 0, &oncore_msg_Bb},
180
 
                             {"@@Ea", 0, &oncore_msg_Ea},
181
 
                             {"@@As", 0, &oncore_msg_As}};
182
 
 
183
 
        void
184
 
        read_data()
185
 
        {
186
 
            int     i, j, k, n, iseq, jseq;
187
 
            uchar   *cp, *cp1;
188
 
 
189
 
 
190
 
            for(cp=Buf+1; (n = 256*(*cp) + *(cp+1)) != 0;  cp+=(n+3)) {
191
 
                for (k=0; k < sizeof(Hdr)/sizeof(Hdr[0]);  k++) {
192
 
                    if (!strncmp(cp+3, Hdr[k].c, 4)) {      /* am I interested? */
193
 
                        iseq = *(cp+2);
194
 
                        jseq = Hdr[k].seq;
195
 
                        Hdr[k].seq = iseq;
196
 
                        if (iseq > jseq) {              /* has it changed? */
197
 
                            /* verify checksum */
198
 
                            j = 0;
199
 
                            cp1 = cp+3;             /* points to start of oncore response */
200
 
                            for (i=2; i < n-3; i++)
201
 
                                j ^= cp1[i];
202
 
                            if (j == cp1[n-3]) {    /* good checksum */
203
 
                                    Hdr[k].go_to(cp1);
204
 
                            } else {
205
 
                                fprintf(stderr, "Bad Checksum for %s\n", Hdr[k].c);
206
 
                                break;
207
 
                            }
208
 
                        }
209
 
                    }
210
 
                }
211
 
                if (!strncmp(cp+3, "@@Ea", 4))
212
 
                    cp += 3*(n+3);
213
 
                if (!strncmp(cp+3, "@@Cb", 4))
214
 
                    cp += 34*(n+3);
215
 
            }
216
 
        }
217
 
 
218
 
        oncore_msg_Bb(uchar *buf)
219
 
        {
220
 
                /* process Bb messages */
221
 
        }
222
 
 
223
 
        oncore_msg_Ea(uchar *buf)
224
 
        {
225
 
                /* process Ea messages */
226
 
        }
227
 
 
228
 
        oncore_msg_As(uchar *buf)
229
 
        {
230
 
                /* process As messages */
231
 
        }
232
 
</PRE>
233
 
 
234
 
The structure Hdr contains the Identifying string for each of the messages that
235
 
we want to examine, and the name of a program to call when a new message of that
236
 
type is arrives.
237
 
The loop can be run every few seconds to check for new data.
238
 
<H4>
239
 
Examples
240
 
</H4>
241
 
There are two complete examples available.
242
 
The first plots satellite positions and the station position as affected by SA, and
243
 
keeps track of the mean station position, so you can run it for periods of days
244
 
to get a better station position.
245
 
The second shows the effective horizon by watching satellite tracks.
246
 
The examples will be found in the GNU-zipped tar file
247
 
<A HREF=ftp://ftp.udel.edu/pub/ntp/software/OncorePlot.tar.gz>
248
 
ftp://ftp.udel.edu/pub/ntp/software/OncorePlot.tar.gz</A>.
249
 
<P>
250
 
Try the new interface, enjoy.
251
 
<HR>
252
 
<ADDRESS>
253
 
Reg.Clemens (reg@dwf.com),
254
 
Poul-Henning Kamp (phk@FreeBSD.org)
255
 
<ADDRESS>
256
 
</BODY>
257
 
</HTML>