Writing Your Own UPM Module: Getting Started

Intel-IoT_LogoImage courtesy of Intel iot-devkit GitHub account

UPM (Useful Packages and Modules) is a high-level library that relies on MRAA to talk to hardware peripherals over GPIO, SPI, UART, etc. Both libraries were created by Intel and come packaged with the Galileo and Edison boards. MRAA has support for other single board computers, like the Raspberry Pi and Beaglebone Black, according to the MRAA documentation.

MRAA is the low-level driver that controls the individual bits for the GPIO. UPM is a collection of libraries (modules) that provides the necessary software for various sensors, motor drivers, etc.

Using UPM is a relatively straightforward task. Instantiate an object with the name of the module you want to use, provide the necessary parameters, and call some functions. It is very similar to using libraries in Arduino.

However,  writing a custom module for a piece of hardware in UPM can be quite daunting. In this post, I will cover how to compile UPM from source, create a template for a module (lovingly named “mymodule”), and write a simple example that uses that module.

We write UPM modules in C++ and use SWIG to create interfaces to Python and JavaScript. That means libraries written in UPM can be used by C++, Python, and JavaScript. Java bindings are available, but I won’t cover them.

Note that I perform all of these steps on an Intel Edison. You can cross-compile on a different machine, but I decided that copying files back and forth was more of a pain.

Install and Configure Git

If this is your first time using the Edison, it’s recommended that you configure it:

Follow the prompts. To install git, we need to enable the unofficial Edison packages as per AlexT’s blog. Add the following lines to /etc/opkg/base-feeds.conf:

Save and exit. Run the following commands:

If you’re planning on making a new UPM module and then submitting your code via pull request back to the UPM repository, I recommend forking the original UPM to your GitHub account. You will also need to generate SSH keys for git on your Edison.

Build MRAA

We first need to build MRAA so we have access to the compiled libraries.

Install MRAA and update the pkg-config path:

Build UPM

We then need to build UPM, which links to the MRAA libraries. If you forked UPM, you will want to change intel-iot-devkit to your GitHub account name in the link below.

[Edit 01/20/2016] Now would be a good time to create a new branch for your module:  git checkout -b mymodule

 

Prepare to build:

You can optionally build all of UPM. Note that this takes 2-3 hours, as the Edison is a relatively slow machine. This will build all modules and install them on your Edison:

Initialize Module Source Directory

Create a directory for our module in the source directory:

Create a file named CMakeLists.txt with your favorite editor, and add the following:

[Edit 1/20/2016] Create a file named javaupm_mymodule.i (SWIG interface file for Java), and enter:

Create another file named jsupm_mymodule.i (SWIG interface file for JavaScript), and enter:

Create yet another file named pyupm_mymodule.i (interface file for Python), and enter:

Write the Source Files

We’re going to create a simple C++ class that has one method:  test() , which simply prints a message to the screen when called.

Create a file with the name mymodule.h and enter:

Create another file named mymodule.cxx and enter:

In the end, our module directory should have the following files:

  • mymodule
    • CMakeLists.txt
    • jsupm_mymodule.i
    • mymodule.cxx
    • mymodule.h
    • pyupm_mymodule.i

Build and Install Your Module

We can build and install just mymodule, without needing to reinstall everything in UPM. We do this by invoking  cmake , which sets up all the modules in the build/src directory. From within the build directory, we can call make <MODULE NAME> to build just our module:

[Edit 1/2/16] Note: if you make a change to your source code, especially the interface (e.g. number of arguments in the constructor), you will need to clean the build/src/mymodule directory. From upm/build, run  rm -rf src/mymodule before calling  make mymodule .

Write a C++ Test Program

Now, let’s write a quick C++ program to test our module. Back in our home directory (i.e.  cd ~ ), create a file named my_mod_test.cpp and enter:

Save and exit. Add /usr/local/lib to the linker path, build, and run:

You should get a nice little message (“Hello from my custom module”) appear in the console.

Write a Java Test Program

[Edit 1/20/2016] Added this section on writing a Java test program. Right now, it doesn’t work, and I’m trying to figure out why. For now, just skip this section.

Likely, your Edison didn’t come with JDK, so we can’t write test programs yet. To install the JDK (here to see the latest versions):

Now, we can write a simple Java program to test our module. In the home directory ( cd ~ ), create a file named MyModuleSample.java and enter:

Save and exit. Add /usr/local/lib/pkgconfig to the Java path, build, and run:

Write a JavaScript Test Program

Much like our C++ program, we can also write a simple JavaScript program that uses our new library. In our home directory (i.e.  cd ~ ), create a file named my_mod_test.js and enter:

Add /usr/local/lib/node_modules/ to the Node path and run:

Once again, you should see the same message appear in your console.

Write a Python Test Program

Finally, we can test our module with Python. In our home directory (i.e.  cd ~ ), create a file named my_mod_test.py and enter:

Add /usr/local/lib/python2.7/site-packages/ to the Python path and run:

Our message should appear once more in the console.

Conclusion

If you follow these steps, you will have created a nice template for writing your UPM module. Feel free to use a different name instead of mymodule, say, the name of your hardware component.

If you would like more information on creating your own UPM module, see these documents:

[Edit 2/3/2016] Added make install  to the MRAA build process and corrected the pkg-config path variable export.

7 Responses

  1. hello, W did all steps from this lesson 🙂 On the end when I cmake mymodule I am getting error:
    CMake Error at CMakeLists.txt:5 (upm_module_init):
    Unknown CMake command “upm_module_init”.
    CMake Warning (dev) in CMakeLists.txt:
    No cmake_minimum_required command is present. A line of code such as
    cmake_minimum_required(VERSION 2.8)

Leave a Reply