Search Microcontrollers

Thursday, August 6, 2015

Playing with the TI-RTOS

I always thought that dealing with an RTOS was some kind of nightmare.
Well, looks like I was wrong and yet again we prove that most of our beliefs are generated by ignorance, I happen to have a lot of it! :)

First thing first, what is an RTOS?

Real Time Operating System, that's what the acronym stands for, but to give a better explanation, we can say it is an Operating System that runs on micro-controllers and eventually CPUs.
That's the "OS" part, now for the "RT" one we can say that it is designed to have a minimal overhead and allow, depending on the clock cycle of the used hardware device, a quick reaction to events.

Say you want to control an electric motor and you feed back a number of signals (i.e. actual speed from an hall effect sensor , some user controls etc.), then you want the system to react as "realtime" as possible, you don't want you motor to react 5 minutes later because you are installing some windows updates.

Yup, you should not expect live updates by default in an RTOS :)

When you have many things potentially happening at the same time, then you normally use a loop that scans them (the quick and dirty solution) or better you set up some interrupts and maybe some timer based functions.

If you have an OS, then you can use threads.
An RTOS gives you the ability to schedule threads, neat eh?
However in giving you that functionality it makes sure that this does not generate much overhead and it allows you to define how to prioritize them.

If you played with systems running with multiple interrupts, then you know about nesting interrupts and while in theory this is pretty straight forward, but in an application that should not miss any interrupt and provide a reliable event handling this can be problematic.

You guessed, the RTOS threads make this an easier task.

... but... yeah... when I am dealing with an mcu I might not have much of power to run an OS you may think.
Well, the tiny MSP430G2 runs at 16Mhz, 16 bits, not much, right?
My old 80286 desktop computer was 16 bit , 10MHz and I thought it was running MS-DOS pretty neatly!
So, in reality, it depends on the OS you are using and an RTOS gives you WAY LESS than MS-DOS, and this makes it perfectly usable even on a MSP430 launchpad (don't try to install windows 10 on it, tho)!

TI created its own RTOS (and they called it TI-RTOS) and it is available for different kind of platforms : MSP430, CortexM4 (Stellaris, Tiva), C28x, C6x etc.

If you have any kind of launchpad, chances are you can freely use the TI-RTOS!
In CCS6.1.0, just go to the CCS App Center and download the version that matches your device



As in its best tradition, TI provides amazing training material, including an extremly well done workshop (yup, for free, online) titled "Introduction to the TI RTOS Kernel Workshop".
The instructor Eric Wilbur is absolutely great in those videos.
Lab activities help tremendously in understanding the tasks at hand and in discovering how much you can do with the OS and the related tools.

We said the RTOS has some kind of smart "scheduler" that allows you to run threads, but that's just a small (although important) part of it.
It provides memory management, debug functionality and GUI configuration features.
Also it comes with drivers, provided in a library, these reduce the need to access the system low level, instead they give you APIs you can use to interact with the rich hardware present in the MCUs.

I am currently enjoying the labs of the workshop, I suggest you do the same, but for those who are too lazy for it, I will post here some summary activity, this will be my way of taking minutes about what I do.

Meanwhile, if you think a typical "arduino like" application, it has a skeleton like the following


void init()
{
  // hw initialisation
}

void loop()
{
 while (1)
 {
   dosomeStuff();
   doSomeOtherStuff();
 }
}


a TI RTOS application instead looks like :

void main(void)
{

   hardware_init();// init hardware via Xware
   BIOS_start();
}


There is no more a while(1) loop because the BIOS is handling the task scheduling, you simply ask the bios to start and it will take care of the different threads.
Threads exist in different flavors and they can be assigned different priorities.
The easiest form of a thread is an idle function, which is executed with the lowest priority by the idle thread, basically when the CPU / MCU does not have anything more important to do.

Creating an idle function is fairly easy, say we have a function that toggles the onboard LED (code taken from lab 4 of the before mentioned workshop and slightly modified by myself)

void ledToggle(void)
{
if(GPIOPinRead(GPIO_PORTF_BASE, GPIO_PIN_3))
{
GPIOPinWrite(GPIO_PORTF_BASE,                
                   GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, 0);
}
else
{
GPIOPinWrite(GPIO_PORTF_BASE, 
                   GPIO_PIN_3, GPIO_PIN_3);
}
delay() // create a delay of ~1/2sec
}

then you just need to register the function as an idle, which you can do in the GUI simply like this :

Pretty simple eh?
Now, you may think that the delay function call is blocking, but this "blocking" behavior only affects this specific thread, it does not prevent other threads, with higer priority, to run in parallel.

Now I guess you can see how the whole OS thing starts to make sense and at the same time, it does not necessarily add complexity to your application.

Give it a try, it's fun!


No comments: