«

»

Sep 01

Robotics 101 : Multithreading with ChibiOS (1)

In embedded systems, one og the key features is multithreading : that is to say having multiple threads running. A thread is a processus running on your processor, it has its own memory and stack and can communicate with other threads through shared variables or function calls.
The main interest in having multiple threads running is that each of them handles a separate task, having many threads thus allows you to have multiple tasks running at the same time without having to manually manage how the processor handles it.
For example, you could have a thread receiving commands (a target angle for a servomotor), a thread driving the servomotor and eventually a thread transmitting information (the current angular position of the servomotor). Each one of these threads is very short in code and in complexity, allowing you to divide a complex task in small and easy ones.

In this part of the tutorial we will see how to create a thread and allocate a static stack and static memory to it.

Creating a thread :

For now we are only going to consider threads which are supposed to run forever, we will see in a while how to manage threads with a limited lifetime.

Basic Structure :

__attribute__((noreturn)) msg_t threadName(void *arg){
init_instructions();
/*
...
...
*/
while(1){
main_instructions();
/*
...
...
*/
}
}

Just as in a basic main function, your thread is defined in a function, it has initialization instructions and a main loop.
And it’s that simple to write a thread !
Note that it is a good practice to declare your threads in separated files (remember to add the thread function in your header file), simply add them to the Makefile as we saw in the last tutorial.

Note :
__attribute__((noreturn))
Is a gcc specific prefix, it tells the compiler that the thread won’t return any value (it helps to save stack space and memory)

Simple example :

__attribute__((noreturn)) msg_t blinkLed(void *arg){
palSetPadMode(GPIOD, 15, PAL_MODE_OUTPUT_PUSHPULL); // init
while(1){
// main loop
palSetPad(GPIOD, 15);
chThdSleepMilliseconds(500);
palClearPad(GPIOD, 15);
chThdSleepMilliseconds(500);
}
}

This thread simply flashes the blue LED on the board.

Launching a Thread :

First you must allocate stack space for the thread, to do so use this macro:
static WORKING_AREA(working_area_name, stack_size);
It creates a Working area for your thread, named working_area__name, with stack_size bytes of stack.
Note that this memory is « lost forever », if your thread ends this memory won’t be freed (if you want to know more about the different kinds of thread creation, look on chibiOS’ official How To’s.

Now you can launch the thread using the function chThdCreateStatic

Sample code :

Code explanation :

In order to create a thread we used the chCreatStatic function, it takes five parameters:

  • A pointer to the thread’s working area, simply put there the name you entered in the WORKING_AREA macro
  • The size of the thread’s working area, use the sizeof operator to fill in this field
  • The thread initial priority is a number between and, set it to NORMALPRIO if you have no reason to give it a higher priority (in most cases that’s enough)
  • The thread name, a pointer to the call function (which is the function name)
  • the thread parameters is a pointer to a table containing the parameters of the thread, if there are none : simply fill it with NULL

That’s about it to launch a simple static thread, in the next tutorial we will see how to make your threads communicate with each other.

Felix