Skip to content
Dimitrios Amaxilatis edited this page Jul 16, 2013 · 3 revisions

Programing Hints

Writing an Application

...

Writing an Algorithm

First Steps

When writing an algorithm, on crucial factor is the use of the implementations of the External Interface, the Os Facets. First of all, an algorithm should accept each Os Facet that is needed as a template parameter, e.g.

template<typename OsModel_P,
       typename Radio_P = typename OsModel_P::Radio,
       typename Timer_P = typename OsModel_P::Timer,
       ...>
class MyAlgorithm
{
public:
   typedef OsModel_P OsModel;
   typedef Timer_P Timer;
   typedef Radio_P Radio;

   typedef typename Radio::block_data_t block_data_t;

   void enable_algorithm();

The very first template parameter should be the OsModel, as done in any other template within the Wiselib. Following parameters such as Radio or Timer can also use default values offered by the Os, as shown in the above example.

Each template parameter must be provided as a public typedef, whereby the names are written in CamelCase letters. The parameters should also become the suffix _P, so that each type definition can provide the original name.

When not implementing a function inside the template class definition, the complete template signature must be copied:

template<typename OsModel_P, typename Radio_P, typename Timer_P, ...>
void
MyAlgorithm<OsModel_P, Radio_P, Timer_P>::
enable_algorithm()
{
   ...
}

Using the Radio Facet

When using the radio interface, one can take a look into the radio concept <http://www.ibr.cs.tu-bs.de/users/tbaum/wiselib/doxygen/testing/html/group__radio__concept.html>_ to have an overview over all type definitions and methods. E.g., when one wants to enable the Radio, one must just call

radio_->enable_radio();
[...]
Radio::self_pointer_t radio_;

Thereby Radio is the passed template parameter described in ''First Steps'', and self_pointer_t is a pointer type defined in the Radio. This can be an ordinary pointer, or on some systems a reference to a static object, which can save memory on such systems. However, the user does not need to care about the concrete implementation - the radio_ member can be used as an ordinary pointer on all supported systems!

Sending of a message requires a destination and a message to be sent (could also be empty). So, if a message should be sent to the node id destination, and the message is a class that provides at least the method buffer_size(), it would look like this

radio_->send( destination, message.buffer_size(), (Radio::block_data_t*)&message );

The Radio also provides a broadcast address, where a message is transmitted to all nodes in communication range. It is Radio::BROADCAST_ADDRESS.

Next, one can register itself as a receiver of messages. The only requirement is that the function signature (return value and types of parameters) must fit to the specification in the radio concept. For example, if there is a method

void my_receive( Radio::node_id_t from, Radio::size_t len, Radio::block_data_t *data )

implemented in the algorithm, one can register it at the radio as follows.

typedef MyAlgorithm<OsModel, Timer, Radio, ...> self_type;
[...]
radio_->template reg_recv_callback<self_type, &self_type::my_receive>( this );

Using the Timer Facet

Using the Timer Facet works similar to the registration of message reception callbacks in the Radio Facet. As described in the timer concept <http://www.ibr.cs.tu-bs.de/users/tbaum/wiselib/doxygen/testing/html/group__timer__concept.html>_, it only provides one method set_timer. For example, if we have a method void my_timer_elapsed( void *data ) that we want to be called in 5 seconds by passing the buffer my_buf, we can register it at the Timer by calling

timer_->template set_timer<self_type, &self_type::my_timer_elapsed>( 5000, this, my_buf );
[...]
Timer::self_pointer_t timer_;
Clone this wiki locally