You are viewing an older revision! See the latest version

Writing a Library

This page discusses the steps in writing and publishing an mbed Library.

What is a Library?

A library is a collection of code, usually focused on enabling a specific component, peripheral or functionality.

You can think of it as a building block for a program; it is not a program in itself. i.e. it doesn't have a main() function, but will be a useful and reusable component in a program.

For example:

How to code a library

A good library has a clear purpose, nice clean interface, and doesn't include the code doing other things - that is what the users program is for. Most libraries actually start as some code that turns out to be useful, is then re-factored in to a useful class of set of functions that can be reused in multiple places in a program, and then finally separated out so any program can include and use it. Lets work through an example to see how this might work...

Step 1 - Refactoring

To start with, here is some code i might have ended up with after some programming:

main.cpp

#include "mbed.h"

DigitalOut pin(LED2);

int main() {
    // do something...

    // flash 5 times
    for(int i=0; i<10; n++) {
        pin = !pin;
        wait(0.2);
    }

    // do something else

    // flash 2 times
    for(int i=0; i<4; n++) {
        pin = !pin;
        wait(0.2);
    }

    // do another thing
}

The program might do what I want, but it is obvious that some of the code is doing very similar things, perhaps as the result of copy-paste to get something working. In this case, it is good practice to re-factor the code so we create a function that can do the flashing for us; define the code in one place, use it in many. So our code might become:

main.cpp

#include "mbed.h"

DigitalOut pin(LED2);

void flash(int n) {
    for(int i=0; i<n*2; n++) {
        pin = !pin;
        wait(0.2);
    }
}

int main() {
    // do something...

    // flash 5 times
    flash(5);

    // do something else

    // flash 2 times
    flash(2);

    // do another thing
}

So we haven't changed the functionality, but the code is now more structured. A quick look at some of the advantages:

  • If my flash logic had a bug, i'd only have to fix it in one place
  • My comments "flash n times" are now pretty redundant! The code speaks for itself

Step 2 - Making it a Class

In the example we're using, although we have factored the flashing logic in to a function, what it is flashing is fixed (a global pin). We might decide that this is so useful, we want to create something that we can use on any output. There are a number of ways we can do this:

  1. Create a class that contains it's own DigitalOut object, so we can create multiple versions on different pins
  2. Make a function that we also pass what pin object to flash
  3. Create a new class inherited from DigitalOut that adds the flash functionality

I'm going to choose 1. (It may actually be the mot appropriate for this example, but is by far the most common)

So we are going to create a class called Flasher, that when created sets up a DigitalOut pin, and provides the method to flash it:

main.cpp

#include "mbed.h"

class Flasher {
public:
    Flasher(PinName pin) : _pin(pin) {  // _pin(pin) means pass the value pin to the DigitalOut/_pin constructor
        _pin = 0;                                        // default the output to 0
    }

    void flash(int n) {
        for(int i=0; i<n*2; n++) {
            _pin = !_pin;
            wait(0.2);
        }
    }

private:
    DigitalOut _pin;
};

Flasher led(LED2);
Flasher out(p6);

int main() {
    led.flash(5);
    led.flash(2);
    out.flash(10);
}

In this code, we can now create a Flasher tied to a particular pin, and tell it to flash. But of course now, we can easily create different flashers on different pins too.

How to publish your library

Information

We will be improving the way libraries are supported in the tools, making it easier to publish and use libraries. This documents the best approach at this time, but keep an eye out for updates that will simplify the process.

The mbed Compiler supports importing and exporting of programs to make it easy to share code. These programs can also be treated as libraries, assuming they have been prepared correctly.

It is effectively a collection of functions and classes, without a "main()" program.

Flasher.h

#ifndef MBED_FLASHER_H
#define MBED_FLASHER_H

#include "mbed.h"

class Flasher {
public:
    Flasher(PinName pin);
    void flash(int n);
  
private:  
    DigitalOut _pin;
};

#endif

Flasher.cpp

#include "Flasher.h"
#include "mbed.h"

Flasher::Flasher(PinName pin) : _pin(pin) {
    _pin = 0;
}

void Flasher::flash(int n) {
    for(int i=0; i<n*2; n++) {
        _pin = !_pin;
        wait(0.2);
    }
}

main.cpp

#include "mbed.h"
#include "Flasher.h"

Flasher led(LED2);

int main() {
    led.flash(5);
}

main.cpp

#include "mbed.h"
#include "Flasher.h"

Flasher led(LED2);
Flasher external_led(p20);

int main() {
    led.flash(5);
    external_led.flash(8);
}

All wikipages