copyright (c) 2005 David M. Howard This work is licensed under the Creative Commons Attribution License. To view a copy of this license, visit http://creativecommons.org/licenses/by/2.0/ or send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305,USA You are free: * to copy, distribute, display, and perform the work * to make derivative works * to make commercial use of the work Under the following conditions: Attribution. You must give the original author credit. * For any reuse or distribution, you must make clear to others the license terms of this work. * Any of these conditions can be waived if you get permission from the author.
Linux: expand the tarball to a directory of your choice. >tar --gzip -xf [tarball name] >cd [nmeap...] Windows: use Winzip to unzip the zipfile to a directory of your choice
Linux: >cd [working directory] >make This builds a static library named libnmeap.a in the 'lib' directory. there is no option for a dynamic library. This thing is so small that it isn't worth the trouble. It also builds the test/examples programs in 'tst'. Windows: >cd [working directory] >nmake -f win32.mak Again, this builds a static library names libnmeap.lib in the 'lib' direcotry, plus the test programs in 'tst'
The NMEA-0183 standard specifies how the output is formatted for GPS data output, usually on a serial port. The data consists of 'sentences' delimited by CR/LF end of line markers. A lot has been written about the format, so this document won't cover the specifics. A good place to start is the NMEA FAQ maintained by Peter Bennett.
NMEAP is an extensible C language parser library that takes NMEA sentences as input and spits out the decoded data as output. You link NMEAP in to your application, set it up, initialize it and feed it bytes. It signals you when it has found a complete valid sentence and provides the parsed out data to you. Parsing NMEA-0183 is pretty easy but it has a few tricky bits. The value of NMEAP is not that it is rocket science to write an NMEA parser, but that it provides a relatively efficient implementation that works, along with an extension framework to add more sentence parsers without hacking the base source code.
An NMEA 'sentence' has the following format:
$name,data1,data2,...,dataN*XX[CR/LF] OR $name,data1,data2,...,dataN[CR/LF] where header := a 5 digit sentence identifier. all ASCII upper case. e.g. GPGGA data1..dataN := some number of data elements, all ASCII numbers or letters, in all kinds of weird formats. fields can be empty, in which case 2 commas will be side by side. normally data fields are identified by their position in the sentence. *XX := a '*' plus two ASCII hex digits of checksum. this field is optional. [CR/LF] := end of line is terminated by a carriage return/linefeed pair. example from the NMEA FAQ: $GPGGA,123519,4807.038,N,01131.324,E,1,08,0.9,545.4,M,46.9,M,,*42
The NMEAP parser works as follows:
Most of the work in NMEAP is done by the sentence parsers. Each type of NMEA sentence string has an associated parser. NMEAP provides standard ones, and the user can add more in a systematic way. The sentence parser is responsible for knowing the token position of the data elements and whatever format they are in. There are functions in nmeap to decode standard data element formats. If something is nonstandard, the sentence parser decodes it. Each sentence parser has a 'struct' type associated with it that the decoded data gets poked into an instance of that data structure, which is provided by the client application when nmeap is set up.
All memory allocation is done by the application. Several data items are required. The application can declare them statically or use malloc or whatever. NMEAP doesn't do any memory allocation on its own. This is an important requirement for portability and especially in embedded systems where memory allocation needs to be tightly defined and controlled.
NMEAP as implemented is not meant to be called from multiple threads. It expects to execute within the context of a single thread. The sentence callouts execute in the context of the thread of the nmeap client thread. Given how nmeap works, it doesn't really make sense to make nmeap thread-safe because the usage pattern is intrinsically single thread. If one wanted to, one could add some mutex locking within the nmeap function calls to make it thread safe. In a multithreaded environment, a more likely approach to thread-safety is to put synchronization in the client side of the application, within the sentence parser callouts or inline handling of sentence data.
NMEAP is IO agnostic. That is a pompous way of saying that NMEAP doesn't do the IO, the client application does it. There are way too many IO schemes to handle to keep it portable, especially in the embedded world. That said, the example programs contain a Linux and a Win32 specific program that includes serial IO for those two platforms.
END