Support for multi-threading. More...

Detailed Description


As RIOT is using a fixed priority scheduling algorithm, threads are scheduled based on their priority. The priority is fixed for every thread and specified during the thread's creation by the priority parameter.

The lower the priority value, the higher the priority of the thread, with 0 being the highest possible priority.

The lowest possible priority is THREAD_PRIORITY_IDLE - 1.

Assigning the same priority to two or more threads is usually not a good idea. A thread in RIOT may run until it yields (thread_yield) or another thread with higher priority is runnable (STATUS_ON_RUNQUEUE) again. Multiple threads with the same priority will therefore be scheduled cooperatively: when one of them is running, all others with the same priority depend on it to yield (or be interrupted by a thread with higher priority). This may make it difficult to determine when which of them gets scheduled and how much CPU time they will get. In most applications, the number of threads in application is significantly smaller than the number of available priorities, so assigning distinct priorities per thread should not be a problem. Only assign the same priority to multiple threads if you know what you are doing!

Thread Behavior

In addition to the priority, flags can be used when creating a thread to alter the thread's behavior after creation. The following flags are available:

Flags Description
THREAD_CREATE_SLEEPING the thread will sleep until woken up manually
THREAD_CREATE_WOUT_YIELD the thread might not run immediately after creation
THREAD_CREATE_STACKTEST measures the stack's memory usage

Thread creation

Creating a new thread is internally done in two steps:

  1. the new thread's stack is initialized depending on the platform
  2. the new thread is added to the scheduler and the scheduler is run (if not indicated otherwise)
Creating threads from within an ISR is currently supported, however it is considered to be a bad programming practice and we strongly discourage you from doing so.


char rcv_thread_stack[THREAD_STACKSIZE_MAIN];
void *rcv_thread(void *arg)
msg_t m;
while (1) {
printf("Got msg from %" PRIkernel_pid "\n", m.sender_pid);
return NULL;
int main(void)
thread_create(rcv_thread_stack, sizeof(rcv_thread_stack),
rcv_thread, NULL, "rcv_thread");

Reading from the top down, you can see that first, stack memory for our thread rcv_thread is preallocated, followed by an implementation of the thread's function. Communication between threads is done using Messaging / IPC. In this case, rcv_thread will print the process id of each thread that sent a message to rcv_thread.

After it has been properly defined, rcv_thread is created with a call to thread_create() in main(). It is assigned a priority of THREAD_PRIORITY_MAIN - 1, i.e. a slightly higher priority than the main thread. Since neither the THREAD_CREATE_SLEEPING nor the THREAD_CREATE_WOUT_YIELD flag is set, rcv_thread will be executed immediately.

If the messages to the thread are sent using msg_try_send() or from an ISR, activate your thread's message queue by calling msg_init_queue() to prevent messages from being dropped when they can't be handled right away. The same applies if you'd like msg_send() to your thread to be non-blocking. For more details, see the Messaging documentation.


file  thread.h
 Threading API.
file  thread_flags.h
 Thread flags.

List of thread states

#define STATUS_NOT_FOUND   (-1)
 Describes an illegal thread status.

Blocked states

#define STATUS_STOPPED   0
 has terminated
 waiting for a locked mutex
 waiting for a message
 waiting for message to be delivered
 waiting for a message response
 waiting for any flag from flag_mask
 waiting for all flags in flag_mask
 waiting for get/put on mbox

Queued states

 to check if on run queue: st >= STATUS_ON_RUNQUEUE
#define STATUS_RUNNING   9
 currently running
#define STATUS_PENDING   10
 waiting to be scheduled to run