Arduino · 26 June 2012 35

leOS, a simple OS for Arduino

Go to leOS2

Today I’ll show you leOS (little embedded Operating System), a system that can manage the background execution of little routines with customizable interval launch times using a scheduler that can start them indipendently by the main loop of the user’s program. leOS can start new tasks, pause and resume them and delete them too. All is done using a scheduler that can start tasks without the partecipation of the user so that the tasks will appear trasparent at the main loop.

To be honest, it should more correct to say that leOS is actually something that is halfway a simple prototype of a real-time operating system (RTOS) and a scheduler. In fact it doesnt have the methods to give a task a tick of time to run itself and a preemptive sistem to stop them, freeze their state and resume them in a later moment; but it’s something that is more complex and efficient of several other schedulers that just use millis() to schedule when launch a task because i.e. leOS isn’t affected by the use of delay() in the main loop. leOS uses timer 2 to manage the tasks so the user looses the PWM functionalities over pins 3 & 11. leOS can run simple tasks that don’t require excessive CPU time but it can be useful in all of those situations where the user wants to let a task run itself out of the main loop. To test leOS just download the attached package and decompress it. After that move the resulting folde /leOS inside your /libraries’ folder. Usually this folder is in /home/user/sketchbook/libraries on a Linux box and into /Documents/Arduino/libraries on a Windows system. To use leOS just include its library at the beginning of your sketch and then create a new istance of the class:

#include "leOS.h"
leOS myOS;

Now you have to call the begin() method from the setup() routine, to initialize the timer used by leOS. Then you can add your tasks using the method addTask():

void setup() {
  myOS.begin();
  myOS.addTask(myFunction, interval[, status]);
  ....
}

With myFunction you pass the method the function you want to be scheduled, with interval you specify how many milliseconds have to pass between a call and the following (the maximun allowed value is 3,600,000 ms, 1 hr., but you can modify this number by editing the file leOS.cpp). yourFunction must be a routine that is inside your sketch. status is the status of the task and it can be: PAUSED, for a task that doesn’t have to start immediately; SCHEDULED (default option), for a normal task that has to start after its scheduling; ONETIME, for a task that has to run only once (read below).

To test the attached test connect 3 LEDs (with their resistors) to Arduino pins 7, 8, and 9 and then upload the sketch. You will see the 3 LEDs flashing with 3 differents times: the middle LED is driven by the code into the main loop() while the other two are managed by 2 tasks. Every 10 seconds you will see that a LED cease to flash and that after 10 seconds more it will start flashing again, to demonstrate the use of pause and restart methods. These are the other 3 methods leOS has:

myOS.removeTask(myFunction)
myOS.pauseTask(myFunction);
myOS.restartTask(myFunction);

It is easy to understand what those methods do, but I’ll give you a little explanation: removeTask can be used to permanently remove a task from the scheduler; pauseTask pauses a task while restartTask resume it. Don’t worry, there’s a sketch in the attached package that shows the use of these methodes.

An interesting feature are the one-time tasks, introduced since version 0.0.7. A one-time task is a task that has to run only once. After its execution, leOS will remove it from the scheduler. To set a task as a one-time task simpy add the keyword ONETIME after the interval in the addTask method:

myOS.addTask(myFunction, interval, ONETIME);

A new method to check the current status of a task has been introduced with version 1.0.0:

myOS.getTaskStatus(nomeFunzione);

It returns the status of the task using the values PAUSED, SCHEDULED, or ONETIME.

In case the user is pausing, resuming or removing a task, he has been asked to check if the status of the circuit or the code managed by the task paused, resumed or removed is coherent and compatible with the new condition: i.e., if a task was driving a transistor that was driving a circuit, the user has to foresee if the last state of the transistor will represent a critical situation for the circuit itself. But this is logic, don’t you?

Version updates & more info in the docs included in the package.

Enjoy with leOS!


leOS2

One of the most frequent appointment that I’ve found reading the messages of the users that tried leOS is about the incompatibility between the scheduler and other libraries that use timer 2: this is due to the fact that a timer can only be used by one application.

So I’ve read about the architecture of the microcontrollers I usually use and I’ve realized to use the WatchDog Timer, WDT. This circuit is usually used to reset the microcontroller if the user doesn’t reset its counter before this one has expired. This is good in critical applications where the sketch must never freeze, both for logical errors or for infinite loops caused by external factors (i.e. datas that should arrive through an ethernet or serial connection). The WatchDog is particular because it uses the internal 128 kHz oscillator as clock source, so it can operate asynchronously respect to the system clock; additionally, it can not only reset the microcontroller but it can also raise an interrupt. We can use the latter and intercept the corresponding ISR putting in it the leOS’s scheduler: in this manner the scheduler won’t use any timer of the MCU. This is leOS2.

To use leOS2 you just have to copy it into the folder /libraries that is included in your sketchs’ folder, and then add your sketch the inclusion of the library and the creation of a new instance of leOS2:

#include "leOS2.h"
leOS2 myOS;

You are now ready to use leOS2 like its predecessor. Only 2 methods are changed, let’s see them in detail. Due to the fact that leOS2 is based on WDT and that this only has a fixed clock and a few prescalers, there are some limitations on the suitable intervals for a task: the minimum available interval is 16 ms, and the intervals must also be multiplies of this value. So, 16 ms represents a “tick” and the intervals must be passed to addTask() & modifyTask() in ticks and not in milliseconds as in leOS. So, addTask(function, 100) will not add a task scheduled to be run every 100 ms but every 100 ticks, or 1,600 ms. To help converting from milliseconds to ticks (if you don’t want to add a simple bit shift, i.e.: interval>>4) I’vew added a new function called convertMs() that accepts a time in milliseconds and returns the corresponding number of ticks. Here are some examples:

myOS.addTask(function1, 10); //add a task to be run every 160 ms(16 ms*10)
myOS.addTask(function2, myOS.convertMs(160)); //same above, but with the conversion
myOS.modifyTask(function1, myOS.convertMs(300)); //re-set function1 to 300 ms

The other methods are unchanged.

Due to the fact that leOS2 uses the WatchDog, the user can not use the Avr library wdt.h to reset the microcontroller. For this reason I’ve added a new method reset() to reset the MCU immediately:

myOS.reset(); //reset the microcontroller

leOS2 supports almost every microcontroller that is supported by the Arduino IDE, by the original core or by a third party one (i.e. the Tiny core for the Atmel Attiny microcontrollers). The only common chip that is incompatible with leOS2 is the Atmega8/A because Atmel didn’t provide it of a WDT capable to raise interrupts. In this case you have to use the first version of leOS.

leOS2 – IMPORTANT FOR ARDUINO MEGA/MEGA2560 USERS
the original bootloader flashed into the Arduino MEGA and MEGA2560 boards doesn’t deactivate the watchdog at the microcontroller’s startup so the chip will freeze itself in a neverending loop caused by eternal resets. To solve this problem, users that want to use leOS2 have to change the bootloader with one that it isn’t affected by this issue. The bootloader can be downloaded by this page.

leOS
leOS
leOS_1.2.1.zip
Version: 1.2.1
2.1 MiB
5914 Downloads
Details...
leOS2
leOS2
leOS2_2.3.1.zip
Version: 2.3.1
1.9 MiB
6512 Downloads
Details...