Thread
Thread class hierarchy
The Thread class allows defining, creating and controlling parallel tasks.
Note: The function main
is a special thread function that is started at system initialization.
Memory considerations
All the internal thread data structures are part of the C++ class, but by default, the thread stack is allocated on the heap. Memory is allocated at the run time during the call to start
method. If you don't want to use dynamic memory, you can provide your own static memory using the constructor parameters.
The default stack size is 4K. However, the application can override it by using the configuration system and setting the THREAD_STACK_SIZE
option to the required size in mbed_app.json
. For details, please see the configuration documentation.
Note: The main thread stack size is specified as rtos.main-thread-stack-size
in the configuration .json file. That defines the main thread for mbed_rtos_start
in mbed_rtos_rtx.c
.
Thread class reference
Public Types |
Public Member Functions | |
Thread (osPriority priority=osPriorityNormal, uint32_t stack_size=OS_STACK_SIZE, unsigned char *stack_mem=nullptr, const char *name=nullptr) | |
Allocate a new thread without starting execution. More... | |
Thread (uint32_t tz_module, osPriority priority=osPriorityNormal, uint32_t stack_size=OS_STACK_SIZE, unsigned char *stack_mem=nullptr, const char *name=nullptr) | |
Allocate a new thread without starting execution. More... | |
Thread (mbed::Callback< void()> task, osPriority priority=osPriorityNormal, uint32_t stack_size=OS_STACK_SIZE, unsigned char *stack_mem=nullptr) | |
Create a new thread, and start it executing the specified function. More... | |
template<typename T > | |
Thread (T *argument, void(T::*task)(), osPriority priority=osPriorityNormal, uint32_t stack_size=OS_STACK_SIZE, unsigned char *stack_mem=nullptr) | |
Create a new thread, and start it executing the specified function. More... | |
template<typename T > | |
Thread (T *argument, void(*task)(T *), osPriority priority=osPriorityNormal, uint32_t stack_size=OS_STACK_SIZE, unsigned char *stack_mem=nullptr) | |
Create a new thread, and start it executing the specified function. More... | |
Thread (void(*task)(void const *argument), void *argument=nullptr, osPriority priority=osPriorityNormal, uint32_t stack_size=OS_STACK_SIZE, unsigned char *stack_mem=nullptr) | |
Create a new thread, and start it executing the specified function. More... | |
osStatus | start (mbed::Callback< void()> task) |
Starts a thread executing the specified function. More... | |
template<typename T , typename M > | |
osStatus | start (T *obj, M method) |
Starts a thread executing the specified function. More... | |
osStatus | join () |
Wait for thread to terminate. More... | |
osStatus | terminate () |
Terminate execution of a thread and remove it from Active Threads. More... | |
osStatus | set_priority (osPriority priority) |
Set priority of an active thread. More... | |
osPriority | get_priority () const |
Get priority of an active thread. More... | |
uint32_t | flags_set (uint32_t flags) |
Set the specified Thread Flags for the thread. More... | |
int32_t | signal_set (int32_t signals) |
Set the specified Thread Flags for the thread. More... | |
State | get_state () const |
State of this Thread. More... | |
uint32_t | stack_size () const |
Get the total stack memory size for this Thread. More... | |
uint32_t | free_stack () const |
Get the currently unused stack memory for this Thread. More... | |
uint32_t | used_stack () const |
Get the currently used stack memory for this Thread. More... | |
uint32_t | max_stack () const |
Get the maximum stack memory usage to date for this Thread. More... | |
const char * | get_name () const |
Get thread name. More... | |
osThreadId_t | get_id () const |
Get thread id. More... | |
virtual | ~Thread () |
Thread destructor. More... |
Static Public Member Functions | |
static int32_t | signal_clr (int32_t signals) |
Clears the specified Thread Flags of the currently running thread. More... | |
static osEvent | signal_wait (int32_t signals, uint32_t millisec=osWaitForever) |
Wait for one or more Thread Flags to become signaled for the current RUNNING thread. More... | |
static osStatus | wait (uint32_t millisec) |
Wait for a specified time period in milliseconds Being tick-based, the delay will be up to the specified time - eg for a value of 1 the system waits until the next millisecond tick occurs, leading to a delay of 0-1 milliseconds. More... | |
static osStatus | wait_until (uint64_t millisec) |
Wait until a specified time in millisec The specified time is according to Kernel::get_ms_count(). More... | |
static osStatus | yield () |
Pass control to next thread that is in state READY. More... | |
static osThreadId | gettid () |
Get the thread id of the current running thread. More... | |
static void | attach_idle_hook (void(*fptr)(void)) |
Attach a function to be called by the RTOS idle task. More... | |
static void | attach_terminate_hook (void(*fptr)(osThreadId id)) |
Attach a function to be called when a task is killed. More... |
/// Priority values.
typedef enum {
osPriorityNone = 0, ///< No priority (not initialized).
osPriorityIdle = 1, ///< Reserved for Idle thread.
osPriorityLow = 8, ///< Priority: low
osPriorityLow1 = 8+1, ///< Priority: low + 1
osPriorityLow2 = 8+2, ///< Priority: low + 2
osPriorityLow3 = 8+3, ///< Priority: low + 3
osPriorityLow4 = 8+4, ///< Priority: low + 4
osPriorityLow5 = 8+5, ///< Priority: low + 5
osPriorityLow6 = 8+6, ///< Priority: low + 6
osPriorityLow7 = 8+7, ///< Priority: low + 7
osPriorityBelowNormal = 16, ///< Priority: below normal
osPriorityBelowNormal1 = 16+1, ///< Priority: below normal + 1
osPriorityBelowNormal2 = 16+2, ///< Priority: below normal + 2
osPriorityBelowNormal3 = 16+3, ///< Priority: below normal + 3
osPriorityBelowNormal4 = 16+4, ///< Priority: below normal + 4
osPriorityBelowNormal5 = 16+5, ///< Priority: below normal + 5
osPriorityBelowNormal6 = 16+6, ///< Priority: below normal + 6
osPriorityBelowNormal7 = 16+7, ///< Priority: below normal + 7
osPriorityNormal = 24, ///< Priority: normal
osPriorityNormal1 = 24+1, ///< Priority: normal + 1
osPriorityNormal2 = 24+2, ///< Priority: normal + 2
osPriorityNormal3 = 24+3, ///< Priority: normal + 3
osPriorityNormal4 = 24+4, ///< Priority: normal + 4
osPriorityNormal5 = 24+5, ///< Priority: normal + 5
osPriorityNormal6 = 24+6, ///< Priority: normal + 6
osPriorityNormal7 = 24+7, ///< Priority: normal + 7
osPriorityAboveNormal = 32, ///< Priority: above normal
osPriorityAboveNormal1 = 32+1, ///< Priority: above normal + 1
osPriorityAboveNormal2 = 32+2, ///< Priority: above normal + 2
osPriorityAboveNormal3 = 32+3, ///< Priority: above normal + 3
osPriorityAboveNormal4 = 32+4, ///< Priority: above normal + 4
osPriorityAboveNormal5 = 32+5, ///< Priority: above normal + 5
osPriorityAboveNormal6 = 32+6, ///< Priority: above normal + 6
osPriorityAboveNormal7 = 32+7, ///< Priority: above normal + 7
osPriorityHigh = 40, ///< Priority: high
osPriorityHigh1 = 40+1, ///< Priority: high + 1
osPriorityHigh2 = 40+2, ///< Priority: high + 2
osPriorityHigh3 = 40+3, ///< Priority: high + 3
osPriorityHigh4 = 40+4, ///< Priority: high + 4
osPriorityHigh5 = 40+5, ///< Priority: high + 5
osPriorityHigh6 = 40+6, ///< Priority: high + 6
osPriorityHigh7 = 40+7, ///< Priority: high + 7
osPriorityRealtime = 48, ///< Priority: realtime
osPriorityRealtime1 = 48+1, ///< Priority: realtime + 1
osPriorityRealtime2 = 48+2, ///< Priority: realtime + 2
osPriorityRealtime3 = 48+3, ///< Priority: realtime + 3
osPriorityRealtime4 = 48+4, ///< Priority: realtime + 4
osPriorityRealtime5 = 48+5, ///< Priority: realtime + 5
osPriorityRealtime6 = 48+6, ///< Priority: realtime + 6
osPriorityRealtime7 = 48+7, ///< Priority: realtime + 7
osPriorityISR = 56, ///< Reserved for ISR deferred thread.
osPriorityError = -1, ///< System cannot determine priority or illegal priority.
osPriorityReserved = 0x7FFFFFFF ///< Prevents enum down-size compiler optimization.
} osPriority_t;
Thread example
The code below uses two separate threads to blink two LEDs. The first thread is automatically created and executes the main
function; the second thread is created explicitly inside main
.
#include "mbed.h"
DigitalOut led1(LED1);
DigitalOut led2(LED2);
Thread thread;
void led2_thread() {
while (true) {
led2 = !led2;
wait(1);
}
}
int main() {
thread.start(led2_thread);
while (true) {
led1 = !led1;
wait(0.5);
}
}
Thread example with callbacks
The Callback API provides a convenient way to pass arguments to spawned threads.
#include "mbed.h"
Thread thread;
DigitalOut led1(LED1);
volatile bool running = true;
// Blink function toggles the led in a long running loop
void blink(DigitalOut *led) {
while (running) {
*led = !*led;
wait(1);
}
}
// Spawns a thread to run blink for 5 seconds
int main() {
thread.start(callback(blink, &led1));
wait(5);
running = false;
thread.join();
}
Debugging tips
When debugging threads, check the full RTX state (ready, blocked and so on) for a deadlock (two things waiting for each other) or a missed signal leading to an event machine stall. You can confirm a deadlock if you see two threads in the "blocked" state each waiting for a resource that the other is supposed to signal.
To reduce deadlocks, proactively code in a safe way by never claiming a high-level mutex while holding a low-level one.