Project

General

Profile

Basic application structure

Introduction

This page will present the simplest possible application structure.
Reading this should help you get started writing your first applications.

Throughout this tutorial we will be using the ioNode as our development platform, however most of this applies regardless of the target board, as long as it's an AVR microcontroller.

Setting up for development

If you haven't already done so, please go read the Setup instructions.
This tutorial assumes you are all set up and ready to code, whether in a separate workspace or directly in the SDK.

Defining our application

The first thing to do is to create a directory structure for our project.
We'll call our application 'hello_world', so let's go ahead and create a directory with the same name:

# From the root of our workspace (or the SDK source tree)
mkdir -pv src/hello_world

Then, we need to create a dfe.conf file in our project's directory (src/hello_world/dfe.conf) to hold our application definition.
For now it should be very simple, the example below targets the ioNode (simply adapt mmcu and freq variables if you're using a different platform):

# Firmware Element Configuration - dfe.conf
name: hello_world
type: app
mmcu: atmega1284p
freq: 10000000L

Basic skeleton

Any application built with the Dooba SDK starts with the main function. It is the entry point of our code.

So let's create a simple main.c file containing just this function:

/* Example application - hello_world
 * main.c
 */

// Main Entry Point
void main()
{
    // ToDo: Write some application code here...

    // Ensure we never return from this function
    for(;;);
}

You might notice the infinite for-loop at the end of the main function. Since our main function is the main entry point for our application, returning from it makes no sense. Actually, returning from it will produce unpredictable behavior as the flow of execution might end up anywhere within the program-space of our microcontroller...

For this reason it is important to keep in mind that your main function should never return.

We may now write whatever application code we want within this main function.

The main loop

Most embedded applications feature a similar structure:

  • some kind of initialization function, run once during startup
  • a main loop calling some update function repeatedly until power off

A library is provided as part of the Dooba SDK to simplify this: eloop.
The eloop library actually implements the main function presented in the previous section. It assumes your code provides two functions:

  • void init() - your init function, called once during startup
  • void loop() - your update function, called repeatedly until power off

To use it, simply define eloop as a dependency in your application's dfe.conf file:

# Firmware Element Configuration - dfe.conf
name: hello_world
type: app
mmcu: atmega1284p
freq: 10000000L
deps:
  - eloop

Once this is done, you don't even need to provide a "main" function anymore in your code.
Let's modify our basic skeleton to reflect this:

/* Example application - hello_world
 * main.c
 */

// Initialize
void init()
{
    // ToDo: Write some initialization code here...
}

// Update
void loop()
{
    // ToDo: Write some business logic here...
}

Adding more source files

As explained in building with dbuild, any source file placed in our project's directory will automatically get picked up and built by dbuild.
Therefore adding more files to your project is as simple as that - no need to declare them anywhere.