> Baloo uses the build and configuration systems of Contiki-NG. Some familiarity with the Contiki concepts is useful for understanding how to use (and develop with) Baloo. We refer un-experience readers to [the Contiki-NG documentation](https://github.com/contiki-ng/contiki-ng/wiki). ## Objective Get familiar with the program flow of a Baloo application. The `baloo-minimal` application is taken as an example. ## Overview The middleware component of Baloo (referred to as `gmw` - or _Glossy MiddleWare_ - in the code) is implemented as a Contiki protothread (called `gmw_thread`). As described [previously](Baloo-overview), Baloo divides the implementation of the NET layer protocol into two parts. 1. The `gmw_thread` protothread is a generic software component, which is __not meant to be modified by the user__. It is implemented in the `os/net/mac/gmw/gmw.c` file. 2. The user-defined component, typically implemented in the example folder (e.g., `example/baloo-minimal/baloo-minimal.c`). The major part of the program flow of a Baloo application is driven by the middleware, which starts and stops the execution of the communication privitives and it executes the callback functions that implement the NET layer logic. This page is meant to give an _overview of the program flow_. More details related to the control packet, callbacks, processes, etc., are provided in dedicated pages. ## Initialization After the standard booting procedure from the Contiki OS, a Baloo program starts with its main application process. Below is the application process of the `baloo-minimal` example (see `example/baloo-minimal/baloo-minimal.c`). ```c /*---------------------------------------------------------------------------*/ PROCESS(app_process, "Application Task"); AUTOSTART_PROCESSES(&app_process); /*---------------------------------------------------------------------------*/ PROCESS_THREAD(app_process, ev, data) { PROCESS_BEGIN(); /* initialization of the GMW structures */ gmw_init(&host_impl, &src_impl, &control); /* application specific initialization */ /* start the GMW thread */ gmw_start(NULL, &app_process, &host_impl, &src_impl); /* main loop of this application task */ while(1) { /* the app task should not do anything until it is explicitly granted * permission by receiving a poll event by the GMW task */ PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_POLL); DEBUG_PRINT_INFO("dummy application task"); /* poll the debug-print task to print out all queued debug messages */ debug_print_poll(); } PROCESS_END(); } /*---------------------------------------------------------------------------*/ ``` The `gmw_init()` function initializes the program on the user-side. Most importantly, it loads user-defined parameters in the host node's control structure (to prepare for sending the first control packet). The `gmw_start()` function initializes the middleware-side. It performs some checks for valid parameter settings, then schedules the first execution of the `gmw_thread`. The `gmw_start()` function takes as parameters the address of two processes (`pre_gmw_proc` and `post_gmw_proc`) that will be polled by the middleware respectively before and after a communication round. Typically, the application process (`app_process`) is passed as `post_gmw_proc` (like in the `baloo-minimal.c` example above). The last two arguments of the `gmw_start()` are pointers to the callback functions that the middleware should execute for the host node and for regular nodes, respectively. Once `gmw_start()` has returned, the application process enters its main loop, where is yield until polled. The rest of the `baloo-minimal.c` file only contains the callback functions implementing the logic of the protocol. ## Flexible execution Unless instructed otherwise, the middleware always reuses the last provided control information. Naturally, Baloo allows its user to flexibly update the control information (and thus, the execution of the communication rounds) at any time. In the `baloo-minimal` example, such updates are performed in the `app_control_update()` function (see below). In `baloo-minimal`, `app_control_update()` is executed during the `host_on_round_finished()` callback, but it could be placed anywhere. However, it is **important to always notify the middleware** that the control information has been updated by executing the `gmw_set_new_control()` function. ```c /*---------------------------------------------------------------------------*/ static void app_control_update(gmw_control_t* control) { /* update the absolute time */ control->schedule.time += control->schedule.period; /* print debug output */ DEBUG_PRINT_INFO("time: %lu, period: %u", control->schedule.time, control->schedule.period); } /*---------------------------------------------------------------------------*/ ``` ## Program flow We describe below the program flow of the `baloo-minimal` example, which is a typical Baloo application. - The OS runs its initialization procedure. - The application process `app_process` is executed by the OS. - `app_process` initializes the user-side data structures of Baloo (control and callbacks), then call `gmw_start()`. - `gmw_start()` initializes the middleware protothread `gmw_thread`, schedules its first execution, and returns. - `app_process` enters its main loop and yields. - The middleware timer fires and triggers the first execution of the protothread, i.e., the first communication round. - The host and regular nodes are initilized in the _Running_ and _Bootsrapping_ state, respectively. - The middleware enters its main loop: - If a `pre_gmw_proc` has been defined, it is polled before the round starts. The protothread yields for some time to leave the process some time to execute. - The host checks for updated control information, then prepares and sends the control packet. - Regular nodes try to receive a control packet. When the reception times out, the middleware excutes the on_bootstrap_timeout() callback. A node transitions to the _Running_ state once it has received a valid control packet. - For each data slot, the middleware: - executes the `on_slot_pre()` callback function, - waits until the start of the slot, - executes the desired communication primitive, - executes the `on_slot_post()` callback function - After all data slots, the `on_round_finished()` callback is executed. - The middleware schedules its next execution to be on time for the next round, polls the `post_gmw_proc`, and yields. --- Next > [Baloo - Control Packet](Baloo-control-packet)