Signal in RT-Thread RTOS – RT-Thread Tutorial Part 8

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.

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.

Signal in RT-Thread RTOS – RT-Thread Tutorial Part 8

Signal

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()

ParametersDescription
signoSignal value (only SIGUSR1 and SIGUSR2 are open to the user, the same applies below)
handlerSet the approach to process signal values
Return——
SIG_ERRWrong signal
The handler value before the signal is installedSuccessful

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()

ParametersDescription
tidThe thread receiving signal
sigSignal value
Return——
RT_EOKSent successfully
-RT_EINVALParameter 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()

ParametersDescription
setSpecify the signal to wait
siPointer pointing to signal information
timeoutWaiting time
Return——
RT_EOKSignal arrives
-RT_ETIMEOUTTimeout
-RT_EINVALParameter 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.

  1. Create the project in the RT-Thread studio.
  2. Open the RT-Thread Settings. Refer to this image.
    • Open RT-Thread Settings
  3. Click the Kernel –> Inter-thread communication –> Enable signals. Refer to this image.
    • Enable Signals

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.

Linux Device Driver TutorialsC Programming Tutorials
FreeRTOS TutorialsNuttX RTOS Tutorials
RTX RTOS TutorialsInterrupts Basics
I2C Protocol – Part 1 (Basics)I2C Protocol – Part 2 (Advanced Topics)
STM32 TutorialsLPC2148 (ARM7) Tutorials
PIC16F877A Tutorials8051 Tutorials
Unit Testing in C TutorialsESP32-IDF Tutorials
Raspberry Pi TutorialsEmbedded Interview Topics
Reset Sequence in ARM Cortex-M4BLE Basics
VIC and NVIC in ARMSPI – Serial Peripheral Interface Protocol
STM32F7 Bootloader TutorialsRaspberry PI Pico Tutorials
STM32F103 Bootloader TutorialsRT-Thread RTOS Tutorials
Zephyr RTOS Tutorials – STM32Zephyr RTOS Tutorials – ESP32
AUTOSAR TutorialsUDS Protocol Tutorials
Product ReviewsSTM32 MikroC Bootloader Tutorial
VHDL Tutorials
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Table of Contents