You are viewing an older revision! See the latest version

Documenting a Library

Table of Contents

  1. Extra Features

Once you have written a library, you probably should write some documentation.

There are two kinds of documentation on mbed.org:

1. General information which answers questions like:

  • How do I get started using this library?
  • How do I wire up the part this library is written for? Where can I buy the part?
  • Which version of the library should I use?

To answer these questions and provide a 'home' for the project, the general advice is to create an appropriately named Cookbook page and provide links to the actual program/library page from within that page.

2. API documentation.

The mbed website can automatically generate API documentation for published libraries if you mark them up using Javadoc/Doxygen notation. This is a great way to document APIs of your libraries to allow other users to quickly pick up and using them.

This is intended as a way of documenting the programming interface specifically - this will answer questions such as:

  • What functions/classes are available?
  • What are the arguments?
  • What should I expect the function to return?

We use Doxygen as the engine and the Javadoc style /** and @param markup. So, for example:

/** A brief description of the function foo
 * 
 * More details about the function goes here
 * and here
 *
 * @param x a variable used by foo
 * @returns something magical done with x   
 */
int foo(int x) {...}

Doxygen supports lots of variants of the documentation markup styles, but it is better if everyone sticks to the above style to make it simple and consistent. You should markup both the class, and the methods within it you want to display to the user. Here is a real example of some marked up code to give you an example:

Import library

00001 /* mbed R/C Servo Library
00002  * Copyright (c) 2007-2010 sford, cstyles
00003  *
00004  * Permission is hereby granted, free of charge, to any person obtaining a copy
00005  * of this software and associated documentation files (the "Software"), to deal
00006  * in the Software without restriction, including without limitation the rights
00007  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00008  * copies of the Software, and to permit persons to whom the Software is
00009  * furnished to do so, subject to the following conditions:
00010  *
00011  * The above copyright notice and this permission notice shall be included in
00012  * all copies or substantial portions of the Software.
00013  *
00014  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00015  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00016  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00017  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00018  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00019  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00020  * THE SOFTWARE.
00021  */
00022   
00023 #ifndef MBED_SERVO_H
00024 #define MBED_SERVO_H
00025 
00026 #include "mbed.h"
00027 
00028 /** Servo control class, based on a PwmOut
00029  *
00030  * Example:
00031  * @code
00032  * // Continuously sweep the servo through it's full range
00033  * #include "mbed.h"
00034  * #include "Servo.h"
00035  * 
00036  * Servo myservo(p21);
00037  * 
00038  * int main() {
00039  *     while(1) {
00040  *         for(int i=0; i<100; i++) {
00041  *             myservo = i/100.0;
00042  *             wait(0.01);
00043  *         }
00044  *         for(int i=100; i>0; i--) {
00045  *             myservo = i/100.0;
00046  *             wait(0.01);
00047  *         }
00048  *     }
00049  * }
00050  * @endcode
00051  */
00052 class Servo {
00053 
00054 public:
00055     /** Create a servo object connected to the specified PwmOut pin
00056      *
00057      * @param pin PwmOut pin to connect to 
00058      */
00059     Servo(PinName pin);
00060     
00061     /** Set the servo position, normalised to it's full range
00062      *
00063      * @param percent A normalised number 0.0-1.0 to represent the full range.
00064      */
00065     void write(float percent);
00066     
00067     /**  Read the servo motors current position
00068      *
00069      * @param returns A normalised number 0.0-1.0  representing the full range.
00070      */
00071     float read();
00072     
00073     /** Set the servo position
00074      *
00075      * @param degrees Servo position in degrees
00076      */
00077     void position(float degrees);
00078     
00079     /**  Allows calibration of the range and angles for a particular servo
00080      *
00081      * @param range Pulsewidth range from center (1.5ms) to maximum/minimum position in seconds
00082      * @param degrees Angle from centre to maximum/minimum position in degrees
00083      */
00084     void calibrate(float range = 0.0005, float degrees = 45.0); 
00085         
00086     /**  Shorthand for the write and read functions */
00087     Servo& operator= (float percent);
00088     Servo& operator= (Servo& rhs);
00089     operator float();
00090 
00091 protected:
00092     PwmOut _pwm;
00093     float _range;
00094     float _degrees;
00095     float _p;
00096 };
00097 
00098 #endif

and the resulting documentation summary:

Import library

Public Member Functions

Servo (PinName pin)
Create a servo object connected to the specified PwmOut pin.
void write (float percent)
Set the servo position, normalised to it's full range.
float read ()
Read the servo motors current position.
void position (float degrees)
Set the servo position.
void calibrate (float range=0.0005, float degrees=45.0)
Allows calibration of the range and angles for a particular servo.
Servo & operator= (float percent)
Shorthand for the write and read functions.

You can explore the whole library here:

Import libraryServo

A class to control a model R/C servo, using a PwmOut

Troubleshooting

If you've marked up your code with doxygen comments but documentation doesn't appear to be generated, check:

  • For classes, make sure you document the class itself as well as the methods
  • For global functions, variables, enums, typedefs, and defines, you need to include an @file <filename> attribute in the doxygen comments at the top of the file

Extra Features

Not only do you get the API documentation, but you can insert code and API documentation in to your wiki pages, as I did here. These were done using the library macro and the urls of the things I wanted to pull in:

<<library http://mbed.org/users/simon/libraries/Servo/le3jpb/docs/Servo_8h_source.html>>
<<library http://mbed.org/users/simon/libraries/Servo/le3jpb/docs/classServo.html>>
<<library http://mbed.org/users/simon/libraries/Servo/le3jpb/>>

Note that this is great for API documentation. It is not really a good idea to markup your normal code implementation comments, and these sorts of things should just say as normal comments so they don't appear in the API documentation. Other documentation such as how you made it, how to use it in detail are best kept for example programs and the cookbook wiki.

For more details about doxygen itself, you can take a look at the website:


All wikipages