-
Notifications
You must be signed in to change notification settings - Fork 57
Generic wiselib application
The most flexible way of Wiselib application development is to write a Generic Wiselib Application, which can be useful if algorithms are tested on different hardware/software platforms, or when dealing with heterogeneous networks. The basic idea is that the Wiselib provides an own main()
function that can be used for a starting point of own applications. This main()
function can then be used to create an instance of an own class, which initializes the required Os facets and the used algorithms. Basically, the process consists of three steps: Writing a class that contains algorithms, creating an instance of that class, and executing it in the main()
function. However, there are examples available that can be found in the applications
folder, which is located parallel to wiselib.stable
and wiselib.testing
in the Wiselib SVN.
A generic Wiselib application can be compiled for different platforms (e.g., Shawn or Contiki) - whereby each target needs its own preparation. In the following, the setup for all supported platforms is described:
- iSense: Prepare Generic Wiselib Application
- Shawn: Prepare Generic Wiselib Application
- Contiki: Prepare Generic Wiselib Application
- TinyOs: Prepare Generic Wiselib Application
An overview over all available is given here:
Target | Description |
---|---|
scw_msb |
ScatterWeb2 1.1 firmware on ScatterWeb MSB nodes. |
contiki_msb |
Contiki 2.4 on ScatterWeb MSB nodes. |
contiki_sky |
Contiki 2.4 on Tmote Sky and TelosB nodes. |
contiki_micaz |
Contiki 2.4 on Micaz nodes. |
shawn |
Shawn simulation environment. |
isense |
iSense firmware on iSense nodes. |
isense-pacemate |
iSense firmware on Pacemates. |
tinyos-micaz |
TinyOs 2.1.1 on Micaz nodes. |
tinyos-telosb |
TinyOs 2.1.1 on Micaz nodes. |
tinyos-tossim |
TinyOs 2.1.1 with TOSSIM. |
flash-jtag |
Download hex file via msp430-jtag to node. Tested with ScatterWeb MSB nodes. |
flash-sky |
Download hex file via msp430-bsl-linux to Tmote Sky/TelosB nodes attached on /dev/ttyUSB0 . If at another port, add parameter PORT=... . |
flash-micaz |
Download hex file via uisp to MicaZ nodes attached on /dev/ttyUSB0 . If at another port, add parameter PORT=... . |
flash-tinyos-sky |
Download hex file (TinyOs hex file) via tos-bsl to Tmote Sky/TelosB nodes attached on /dev/ttyUSB0 . If at another port, add parameter PORT=...
|
tinyos-nodeid-micaz |
Change node id in MicaZ TinyOs image - given via TOS_NODE_ID=... . Default is 1. |
tinyos-nodeid-telosb |
Change node id in TelosB/TMote Sky TinyOs image - given via TOS_NODE_ID=... . Default is 1. |
clean |
Delete all object/binary files. |
First of all, an own class must be implemented that provides a method called init()
expecting a parameter of type Os::AppMainParameter&
. Os
can be of type wiselib::OSMODEL
, since OSMODEL
is defined in each makefile in the applications directory. That way, the application adapts automatically to the currently used make target - and it can be compiled for any supported platform just by changing the make target. Currently the following macros are defined:
Platform | Macro |
---|---|
Shawn | SHAWN |
iSense | ISENSE |
ScatterWeb | __SCATTERWEB__ |
Contiki | CONTIKI |
OSA (Os Abstraction Layer) | WISELIB_OSA |
TinyOs | TINYOS |
TinyOs (for TOSSIM) | TINYOS_TOSSIM |
FeuerWare | FEUERWARE |
With the aid of the passed Os::AppMainParameter
, it is possible to get instances of Os facets. This is done by the wiselib::FacetProvider
, which returns an Os facet for the currently used platform. For example, on Contiki it returns a static instance (since there is no dynamic memory allocation available), whereas for Shawn a new instance is created that fits to the currently active processor (in Shawn, the main()
function is called once per processor).
Then, a timer is registered that executes the start()
method of our example after 5000ms (5s). When this method is finally called, it sends a debug message to the radio (broadcast address).
The example looks as follows:
#include "external_interface/external_interface.h"
#include "algorithms/routing/tree/tree_routing.h"
typedef wiselib::OSMODEL Os;
class ExampleApplication
{
public:
void init( Os::AppMainParameter& value )
{
radio_ = &wiselib::FacetProvider<Os, Os::Radio>::get_facet( value );
timer_ = &wiselib::FacetProvider<Os, Os::Timer>::get_facet( value );
debug_ = &wiselib::FacetProvider<Os, Os::Debug>::get_facet( value );
debug_->debug( "Hello World from Example Application!\n" );
radio_->reg_recv_callback<ExampleApplication,
&ExampleApplication::receive_radio_message>( this );
timer_->set_timer<ExampleApplication,
&ExampleApplication::start>( 5000, this, 0 );
}
// --------------------------------------------------------------------
void start( void* )
{
debug_->debug( "broadcast message at %d \n", radio_->id() );
Os::Radio::block_data_t message[] = "hello world!\0";
radio_->send( Os::Radio::BROADCAST_ADDRESS, sizeof(message), message );
// following can be used for periodic messages
// timer_->set_timer<ExampleApplication,
// &ExampleApplication::start>( 5000, this, 0 );
}
// --------------------------------------------------------------------
void receive_radio_message( Os::Radio::node_id_t from, Os::Radio::size_t len, Os::Radio::block_data_t *buf )
{
debug_->debug( "received msg at %u from %u\n", radio_->id(), from );
debug_->debug( " message is %s\n", buf );
}
private:
Os::Radio::self_pointer_t radio_;
Os::Timer::self_pointer_t timer_;
Os::Debug::self_pointer_t debug_;
};
Next, an instance (as a global variable) of type WiselibApplication
must be created, which in turn is a class template expecting the Os and the class of which an instance should be created as template parameters. As with the previously described FacetProvider, it automatically adapts the currently used platform (using Contiki, there is only one static instance available, whereas on Shawn there is one instance per processor). The example is pretty simple, and contains only one line of code:
wiselib::WiselibApplication<Os, ExampleApplication> example_app;
Finally, the main()
function must be implemented, which is called application_main
and expects a type Os::AppMainParameter&
as parameter. The function can contain only one line of code: Calling the init()
method of the WiselibApplication
, which in turn calls the init()
method of the just created class (here: ExampleApplication
):
void application_main( Os::AppMainParameter& value )
{
example_app.init( value );
}