NMEAP TUTORIAL AND REFERENCE


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.

Table Of Contents

  1. Installing the Source Code
  2. Building the Library
  3. Description and Examples
  4. API Documentation
 

1. Installing the source code

Get the source code from NMEAP at sourceforge.net

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
	
 

2. Building the library


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'
 

3. Description and Examples

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:

  1. the application sets up the parser and specifies which sentences are to be parsed and what is to be done with the output data from the parser.
  2. the application reads raw bytes from its IO device and passes the bytes to the parser, either byte by byte or as a buffer/length pair.
  3. nmeap:

Sentence Parsers

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.

Memory Allocation

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.

Threads

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.

IO

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.

Examples

Look at the code for the following example programs to see the usage patterns. The are all located in the 'tst' directory. There are big, obvious comments delineating the steps to setting up and using NMEAP. The IO is simulated in the samples. Follow the comments in the code to see the sequence of operations to setup and run the parser. When you are ready just plug in your own IO.
  1. tst/test1.c Setup for standard GGA and RMC sentences with byte by byte IO (easiest to code up)
  2. tst/test2.c Setup for standard GGA and RMC sentences with block IO (more efficient from a system call standpoint)
  3. tst/test3.c Adding a custom parser
  4. tst/wingps.c A console program that reads a serial port and writes the decoded data to standard out for WIN32 applications
 

API Documentation

The documentation for the actual API is in Doxygen HTML format and is contained in the 'doc' directory of the source distribution. Or, all the external data structures, constants and functions are defined in 'inc/nmeap.h'.

END