This article is a continuation of the Series on RT-Thread STM32 Tutorials and carries the discussion on RT-Thread RTOS and implementation with STM32. The aim of this series is to provide easy and practical examples that anyone can understand. In our last post, we have seen Message Queue in the RT-Thread RTOS. In this post, we will see the Signal in RT-Thread RTOS.
You can see the video explanation of Getting started with the RT-Thread RTOS.
Prerequisites
This is the continuation of the below tutorials. If you don’t read it, please read that also before this.
- RT-Thread RTOS Introduction
- Getting started with RT-Thread RTOS – Part 1
- Thread management of RT-Thread RTOS – Part 2
- Timer management of RT-Thread RTOS – Part 3
- Semaphore in RT-Thread RTOS – Part 4
- Mutex and Event in RT-Thread RTOS – Part 5
- Mailbox in RT-Thread RTOS – Part 6
- Message Queue in RT-Thread RTOS – Part 7
Tools and Components Required
- STM32F411 Dev Board (You can use any STM32F4 controller)
- RT-Thread Studio
Inter-thread Communication in RT-Thread RTOS
If we are working in a multithreaded environment, we need to send data from one thread to another thread. There are many ways to do that. Normally we use global variables or some memory segment for that purpose. Sometimes it is hard to use global data. Because it is difficult to keep track of the messages. To make our lives easier, RTOSs are will support a few inter-thread communication methods. RT-Thread RTOS supports the below inter-thread communication methods.
- Mailbox
- Message Queue
- Signals
Signal in RT-Thread RTOS – RT-Thread Tutorial Part 8
Signal
A signal is a software interrupt that is generated when an event has occurred. Essentially, signals notify threads of events that occurred during the execution of other threads or ISRs. When it comes to its principle, a thread receiving a signal is similar to the processor receiving an interrupt request.
The signal is also like Counting semaphores and events. But here signals will have a separate handler to process that. Signals are used for asynchronous communication in RT-Thread. It is like signals in the Linux system.
No operation is needed for a thread to wait for the signal’s arrival. In fact, the thread does not know when the signal will arrive.
Management of Signals
In RT-Thread RTOS, the signal supports the below operations.
Install signal
When the thread wants to process or receive the signal, then that thread has to install the signal using the below function interface.
rt_sighandler_t rt_signal_install(int signo, rt_sighandler_t[] handler);
This function will map the signal value and the action of the thread when that signal value is received.
Input parameters and return values for rt_signal_install()
Parameters | Description |
---|---|
signo | Signal value (only SIGUSR1 and SIGUSR2 are open to the user, the same applies below) |
handler | Set the approach to process signal values |
Return | —— |
SIG_ERR | Wrong signal |
The handler value before the signal is installed | Successful |
Block Signal
If the thread doesn’t want to process the signal, then that thread can use the below function to block the signal.
void rt_signal_mask(int signo);
Unblock Signal
If the thread wants to unblock the blocked signal, then it can use the below function to do that.
void rt_signal_unmask(int signo);
Send Signal
One thread or ISR can send the signal to another thread using the below function.
int rt_thread_kill(rt_thread_t tid, int sig);
Input parameters and return values for rt_thread_kill()
Parameters | Description |
---|---|
tid | The thread receiving signal |
sig | Signal value |
Return | —— |
RT_EOK | Sent successfully |
-RT_EINVAL | Parameter error |
Wait for Signal
Wait for the arrival of the set signal. If this signal did not arrive, suspend the thread until the signal arrives or wait until time exceeds the specified timeout. If the signal arrived, the pointer pointing to the signal body is stored in si, as follows is the function to wait for the signal.
int rt_signal_wait(const rt_sigset_t *set, rt_siginfo_t[] *si, rt_int32_t timeout);
Input parameters and return values for rt_signal_wait()
Parameters | Description |
---|---|
set | Specify the signal to wait |
si | Pointer pointing to signal information |
timeout | Waiting time |
Return | —— |
RT_EOK | Signal arrives |
-RT_ETIMEOUT | Timeout |
-RT_EINVAL | Parameter error |
Enable Signal in RT-Thread RTOS
By default, the signals won’t be enabled. So, we need to enable them in the RT-Thread RTOS before using the signals. Please follow the below steps.
- Create the project in the RT-Thread studio.
- Open the RT-Thread Settings. Refer to this image.
- Click the Kernel –> Inter-thread communication –> Enable signals. Refer to this image.
That’s it. We can start coding.
Signal in RT-Thread Example
In this example, I have created two threads. Thread 2, installs the SIGUSR1
and SIGUSR2
signals. And thread 1 increments the count. When the count value is odd, it will send the SIGUSR1
signal. When the count value is even, it will send the SIGUSR2
signal.
Source code
You can get this entire project’s source code from GitHub.
#include <rtthread.h> #define DBG_TAG "main" #define DBG_LVL DBG_LOG #include <rtdbg.h> #include <drv_common.h> #include <rtdevice.h> static rt_thread_t threadId1 = RT_NULL; static rt_thread_t threadId2 = RT_NULL; /* Signal process function for thread 2 signal handler */ void thread2_signal_handler1(int sig) { rt_kprintf("Thread 2 Handler 1: Received signal %d\n", sig); } /* Signal process function for thread 2 signal handler */ void thread2_signal_handler2(int sig) { rt_kprintf("Thread 2 Handler 2: Received signal %d\n", sig); } /* Thread 1 */ static void thread1_function(void *parameter) { uint32_t count = 0; while (1) { count++; LOG_D("Thread 1: count = %d\n", count); if( count & 0x01 ) { /* Send signal SIGUSR1 to thread 2 */ rt_thread_kill(threadId2, SIGUSR1); } else { /* Send signal SIGUSR2 to thread 2 */ rt_thread_kill(threadId2, SIGUSR2); } rt_thread_mdelay(1000); } } /* Thread 2 */ static void thread2_function(void *parameter) { /* Install signal */ rt_signal_install(SIGUSR1, thread2_signal_handler1); rt_signal_install(SIGUSR2, thread2_signal_handler2); /* Unblock the signal */ rt_signal_unmask(SIGUSR1); rt_signal_unmask(SIGUSR2); while (1) { /* Do nothing or something */ } } int main(void) { /* Create thread 1 */ threadId1 = rt_thread_create("thread1_fn", //Name thread1_function, //Function address RT_NULL, //Thread function parameter 1024, //Stack Size 1, //Thread priority 2000); //Time slice in ticks /* Create thread 2 */ threadId2 = rt_thread_create("thread2_fn", //Name thread2_function, //Function address RT_NULL, //Thread function parameter 1024, //Stack Size 1, //Thread priority 2000); //Time slice in ticks /* Start both threads */ rt_thread_startup(threadId1); rt_thread_startup(threadId2); while(1); return RT_EOK; }
Output
\ | / - RT - Thread Operating System / | \ 4.1.1 build Mar 8 2023 20:05:40 2006 - 2022 Copyright by RT-Thread team ←[0m[D/main] Thread 1: count = 1 ←[0m Thread 2 Handler 1: Received signal 30 ←[0m[D/main] Thread 1: count = 2 ←[0m Thread 2 Handler 2: Received signal 31 ←[0m[D/main] Thread 1: count = 3 ←[0m Thread 2 Handler 1: Received signal 30 ←[0m[D/main] Thread 1: count = 4 ←[0m Thread 2 Handler 2: Received signal 31 ←[0m[D/main] Thread 1: count = 5 ←[0m Thread 2 Handler 1: Received signal 30 ←[0m[D/main] Thread 1: count = 6 ←[0m Thread 2 Handler 2: Received signal 31
In our next tutorial, we will see the demo application which uses a few peripherals in RT-Thread RTOS.
You can also read the below tutorials.

Embedded Software | Firmware | Linux Devic Deriver | RTOS
Hi, I’m SLR. I am a tech blogger and an Embedded Engineer. I am always eager to learn and explore tech-related concepts. And also, I wanted to share my knowledge with everyone in a more straightforward way with easy practical examples. I strongly believe that learning by doing is more powerful than just learning by reading. I love to do experiments. If you want to help or support me on my journey, consider sharing my articles, or Buy me a Coffee! Thank you for reading my blog! Happy learning!