MansOS tutorial

From DiLab
Revision as of 12:30, 14 October 2011 by Atis (talk | contribs)
Jump to: navigation, search

Getting MansOS

See MansOS installation guide. For the purposes of this tutorial, you will need:

  • MansOS sources. The recommended way is to checking them out from SVN by using command "svn co http://mansos.net/svn/mansos/ mansos"
  • Development tools, such as msp430-gcc compiler
  • Common UNIX command line tools, such as make
  • A working Python installation
  • At least one mote (Tmote Sky, Arduino, Epic mote, SADmote etc.) on which to run the application
    • If you don't have any motes, you can just run MansOS using its built-in simulation platform "pc"

Building and running your first application

Change location in MansOS root directory to mansos/apps/demo/Blink.

Now compile the application and program it in the device.

For users of Tmote Sky:

make telosb upload

For users of Arduino:

make atmega upload

For users of SADmote:

make telosb upload-msp430

For testing the application on simulator:

make pc run

The first argument to "make" is the platform for which to build. The second argument is "upload" command, which means "take the compiled application and program it on a mote".

See MansOS platforms documentation for more detailed description different hardware platforms.

See MansOS building documentation for more detailed description of make targets.

After programming is complete, the mote should now periodically (one change per second) turn one of its LEDs on and off.

The upload command by default tries to upload the application to serial port /dev/ttyUSB0. If your mote is attached to another port, change BSLPORT environmental variable to specify the correct port. For example:

$ export BSLPORT=/dev/ttyUSB1
$ make telosb upload
...
./../../../mos/make/scripts/tos-bsl --telosb -c "/dev/ttyUSB1" -r -e -I -p ./build/telosb/image.ihex

To see to which port the mote is attached you can use motelist utility:

$ motelist
Reference  Device           Description
---------- ---------------- ---------------------------------------------
M4AOQGBQ   /dev/ttyUSB0     Moteiv tmote sky

Debugging an application

Printf-style debugging is the most commonly used form of debugging for sensor motes.

MansOS provides several macros for this:

  • PRINTF(format, arguments): analogue of printf() function;
  • PRINT(string): just print the string passed as argument; when compared to PRINTF(), this version has the benefit of smaller executable size;
  • PRINTLN(string): print the string passed as argument with newline character appended.

By default, output from these macros is sent to serial port.

To see one of these macros in action, change directory to mansos/apps/demo/CounterToSerial, compile and upload the application.

Listening to serial port

To observe the output a program capable to listening the serial port is required. If you don't know what to use, try:

  • On Linux or MAC: minicom
  • On Windows: putty

Use 38400 as baudrate setting, 8 bits, 1 stopbit, parity none, flow control turned off. Here is a complete minicom configuration file for reference:

pu port             /dev/ttyUSB0
pu baudrate         38400
pu bits             8
pu parity           N
pu stopbits         1
pu rtscts           No 

Configure minicom/putty so that it listens to the serial port a mote is attached (/dev/ttyUSB0 for minicom by default). Compile and upload the CounterToSerial application, and launch minicom:

$ minicom
Welcome to minicom 2.4

OPTIONS: I18n 
Compiled on Jan 25 2010, 06:49:09.
Port /dev/ttyUSB0

Press CTRL-A Z for help on special keys                    
                                                           
counter = 1                                                
counter = 2                                                
counter = 3
counter = 4
...

Alternatives to serial port output

Alternatively, the printed characters can be sent on air by using radio transceiver. To enable this option, add this line:

CONST_DPRINT_TO_RADIO=1

to application's configuration file. In this case, no output to serial port will be produced. You will need another mote which listens to radio and forwards all messages received to its serial port, i.e. acts as a proxy.

Alternatively, the printed characters can be sent to LCD terminal, if pone is attached to the mote.

Analysis of a MansOS application

Let's analyze the CounterToSerial application. There are three files in directory mansos/apps/demo/CounterToSerial:

  • main.c - C source file, contains application-specific code
  • Makefile - this file is used by GNU make to build the application for different architectures and upload it to different motes
  • config - application-specific configuration file. This file is used to specify:
    1. Which MansOS components to include and which to exclude when building the application,
    2. Compile time constants (a constant defined in this file using "CONST_xxx=y" syntax is visible by C preprocessos as xxx=y)
    3. Other things, like the MCU model, upload baudrate, CPU frequency (CPU_MHZ variable) etc. This file is eventually processed by GNU make - this means that all variables and syntax supported in Makefile is also supported in this file.


File main.c (comments removed):

1: #include "stdmansos.h"
2: 
3: void appMain(void)
4: {
5:     uint8_t counter = 1;
6:     while(1)
7:     {
8:         PRINTF("counter = %u\n", counter++);
9:         toggleRedLed();
10:        mdelay(1000);
11:    }
12: }

Line #1: Include all standard MansOS headers.

Line #3: Define appMain() function. This function must be present in every MansOS application, in the same way every C program usually requires main() function. (An exception of this rule regarding MansOS: when USE_KERNELMAIN option is set to n, the usual C rule requiring main() is in power.)

Line #5: Declare a local 8-bit variable called "counter" and initialize it to 1.

Line #6 - #11: The main loop of the program.

Line #8: Print the value of the counter.

Line #9: Change status of the red LED. If it was turned off, it will be turned on, and vice versa.

Line #10: Delay for one second or 1000 milliseconds. If energy efficiency is required, msleep() should be used instead.


Makefile:

...
# Sources are all project source files, excluding MansOS files
SOURCES = main.c

# Module is the name of the main module built by this makefile
APPMOD = CounterToSerial
...
ifndef MOSROOT
  MOSROOT = $(PROJDIR)/../../..
endif
...

You should pay attention only to this fragment of the Makefile.

SOURCES is a variable which tells the names of all application-specific source files. For most applications, only one is sufficient.

APPMOD is the name of the application. The name is of no great significance; a generic name like "App" could be used as well.

MOSROOT must contain the path to MansOS root, either relative or absolute. It is an important variable! If MOSROOT is not specified correctly, the application is not going to compile.


config

For CounterToSerial application, the configuration file is empty.

For majority of non-trivial applications, the configuration file needs to be tuned, either by enabling some MansOS options disabled by default, or by disabling option enabled by default - either because your hardware platform does not have these options of for optimization purposes.

For example, humidity sensor support is disabled by default. If the application includes C code that reads the humidity sensor, configuration file must have the line:

USE_HUMIDITY=y

See MansOS configuration options for list of all supported configuration options.

MansOS shell

MansOS comes with a PC command line tool that can be used to control and reprogram the motes in the network, either via serial port or wirelessly.

The shell tool is located under mansos/pc/shell.

The shell features these commands:

ls                              -- list all motes
led (red|green|blue) [on|off]   -- control LEDs
sense                           -- read sensor values
get <OID>                       -- get a specific OID value from all motes
set <OID> <type> <value>        -- set a specific OID to <value>
select [<address>]              -- select a specific mote (no args for broadcast)
load [<file>]                   -- load an ihex file (no args for clear existing)
program [<address>]             -- upload code (from ihex file) on a specific mote
reboot                          -- reboot mote
quit                            -- exit program
help                            -- show this help

To use the shell, support on mote side is required as well. In particular, USE_SMP must be enabled in configuration file. If run-time reprogramming is going to be used, then USE_REPROGRAMMING should be enabled as well.

MansOS contains a few demo examples that can be used in conjunction with the shell. They are located under mansos/apps/tests/SmpTest. Compile and upload them as any other applications; then launch the shell tool on your PC and try it out for yourself.

MansOS features

MansOS has support for:

  • LEDs
    • On Tmote Sky: red, green, and blue
    • On SADmote: just red
    • On Arduino: just yellow
  • Bidirectional serial port communication
    • Sending data to serial port
    • Reading input from serial port
  • Radio communication
    • Packet sending
    • Packet receiving
    • Measuring the strength of received radio signal in different channels (in this way, a primitive spectrum analyzer can be built!)
    • Optionally: TinyOS frame format support
    • Optionally: rudimentary 802.15.4 MAC frame format support
  • Networking stack
    • Sending data to a specific mote in the network
    • Sending data to all motes in the network
    • Sending data reliably
    • Collecting data from the whole network
    • Synchronizing time in the whole network
  • Management
    • Controlling a specific mote by using an application running on computer
    • Controlling whole network of motes at once
    • Reading the address, serial number, sensor data etc.
    • Rebooting the mote, turning LEDs on and off etc.
    • Reprogramming the mote
  • Parallel execution
    • Preemptive multitasking
    • Optionally, cooperative multitasking (similar to Contiki protothreads)
  • Storing data on flash or SD card:
    • Optionally, using a file system
  • Reading sensors
    • Light
    • Temperature
    • Humidity
    • Accelerometer and gyroscope
    • Data from a GPS device (NMEA stream)
    • Other sensors using analogue interface. Just specify the correct ADC channel you want to read and voila!
    • Other sensors using digital I2C interface (you will need to write your own driver for this; however, it may be not as hard as it sounds)
  • Output to LCD display
  • Low power modes
    • msleep() and usleep() functions will automatically put the sensor device in low power mdoe

FAQ

Q. How different features of MansOS can be turned on and off?

A. To turn on an option, use configuration files. Note that most of commonly used options are already turned on by default (such as LEDs, printing to serial port, radio, ADC etc.).

Turning off an option is not normally required. MansOS build system can automatically detect that an option is not used, and prune from the final executable all code that is related to this option. In some cases when this "smart linking" does not give the expected results, or when a more advanced control over some options is required - disable the option in the configuration file.

Q. Can MansOS be used just as a library?

A. Some people worry that using whole operating system as opposed to writing their own program from scratch is going to be suboptimal.

However, with MansOS the user is not required to enable advanced operating system services like parallel execution, scheduler, dynamic memory management or any other.

First, the user can disable all advanced algorithms and features by using the configuration file.

Second, if even that is not enough, MansOS can be used just as a library or even just as a development environment that provides various tools for compiling and uploading applications.

In fact, a "MansOS application" is not required to have any system code at all. The user can specify USE_KERNELMAIN=n in application configuration file and write his own main() function, without relying on any system services. If you are going to try this, you may wish to look in mansos/mos/kernel/kernelmain.c to see how system initialization is done in the default case to get some idea what you might need.