Why Not Use Global Variables for Inter-task Communication in RTOS?

Follow+Star Public Account Number, don’t miss wonderful content

Why Not Use Global Variables for Inter-task Communication in RTOS?

Author | strongerHuang

WeChat Public Account | strongerHuang

Students who have a deep understanding of RTOS principles or have read RTOS source code should know: RTOS implements inter-task communication usually by a series of pointers.
The “effective data” of inter-task communication is actually implemented by pointers pointing to a “variable” or “array”.
1.Semaphore

The essence of a semaphore is to pass an “event”. For example: Task A completes sending data and notifies Task B through the semaphore.

OSSemPost(EventSem_SendOK);

We mainly want to convey the event of “data sent successfully”, further analysis shows that it is actually a “flag” or “variable”.

2.Queue

The principle of queues is somewhat similar to that of semaphores, but here it is a “variable”. For example: after receiving a complete frame of data through the serial port, it is sent to Task B through the queue.

OSQPost(UARTRcvQueue, RcvBuf);

Compared to semaphores, queues can transmit a larger amount of data, and the effective data transmitted by queues is generally an array.

There are also mailboxes, which are similar to queues and can be understood as “two-dimensional arrays”.

Writing to this point, you will find that whether it is semaphores or queues, the underlying essence is also to pass “variables” and “arrays”.

So the question arises: Why not use global variables for inter-task communication in RTOS?

This question is quite common, and I have also seen discussions about it in my technical exchange group, so I will simply share my views.

What are the issues with global variables?

The reason why RTOS does not use global variables for inter-task communication is that there are many drawbacks to using global variables.
1. Preemption Issues
If two or more tasks need to “use” the same global variable without adding any “mutual exclusion” measures, there will inevitably be preemption issues.
2. Code Specification Issues
If there are only a few global variables in the entire project, it’s not a problem, but if there are dozens or even hundreds of global variables, do you think such code will be easy to maintain later?
After multiple iterations, the code will only become increasingly difficult to understand and read.
3. Coupling Issues
Global variables can lead to unreasonable layering and contradict modular programming; your global variables have no ownership, neither belonging to Task A nor Module A, which may ultimately lead to “being at the mercy of others” and result in “failure”.
4. Security Issues
There is a saying that global variables are the “culprit” of projects; when projects grow larger, even a small modification may cause a major bug.
Why Not Use Global Variables for Inter-task Communication in RTOS?
Global variables have many other drawbacks, which I won’t describe one by one here. In short, be cautious with global variables.
Of course, the above-mentioned issues (drawbacks) are based on the existence of multiple variables in the project; if the project only has 1 or 2 global variables, this is not within the scope of this discussion.

Principle of Semaphore and Queue Communication

Most RTOS semaphores and queues use pointers, structures, arrays, etc., combined with the system to “encapsulate” them, making inter-task communication more effective and secure, while also adhering to the principle of “high cohesion and low coupling”.
For example, the semaphore post in ucos:
INT8U  OSSemPost (OS_EVENT *pevent){#if OS_CRITICAL_METHOD == 3u                          /* Allocate storage for CPU status register      */    OS_CPU_SR  cpu_sr = 0u;#endif
#if OS_ARG_CHK_EN > 0u    if (pevent == (OS_EVENT *)0) {                    /* Validate 'pevent'                             */        return (OS_ERR_PEVENT_NULL);    }#endif    if (pevent->OSEventType != OS_EVENT_TYPE_SEM) {   /* Validate event block type                     */        return (OS_ERR_EVENT_TYPE);    }    OS_ENTER_CRITICAL();    if (pevent->OSEventGrp != 0u) {                   /* See if any task waiting for semaphore         */                                                      /* Ready HPT waiting on event                    */        (void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_SEM, OS_STAT_PEND_OK);        OS_EXIT_CRITICAL();        OS_Sched();                                   /* Find HPT ready to run                         */        return (OS_ERR_NONE);    }    if (pevent->OSEventCnt < 65535u) {                /* Make sure semaphore will not overflow         */        pevent->OSEventCnt++;                         /* Increment semaphore count to register event   */        OS_EXIT_CRITICAL();        return (OS_ERR_NONE);    }    OS_EXIT_CRITICAL();                               /* Semaphore value has reached its maximum       */    return (OS_ERR_SEM_OVF);}

Although we only need to transmit one variable of effective information, it will manage the “critical section” and also anticipate some error conditions, etc.

Finally, RTOS source code can also be considered an excellent project, especially those RTOS with relatively high popularity and installation, such as µC/OS, FreeRTOS, RT-Thread, ThreadX.

Lastly, if you have time, you can read the RTOS source code, I recommend µC/OS for reading the source code, as it can help you grasp some software architecture knowledge and understand common issues in the development process.

———— END ————

Why Not Use Global Variables for Inter-task Communication in RTOS?

● Column “Embedded Tools”

● Column “Embedded Development”

● Column “Keil Tutorial”

● Selected Tutorials for Embedded Columns

Follow the public accountReply “Join Group” to join the technical exchange group according to the rules, reply “1024” to see more content.

Why Not Use Global Variables for Inter-task Communication in RTOS?

Why Not Use Global Variables for Inter-task Communication in RTOS?

Click “Read the Original” to see more shares.

Leave a Comment

Your email address will not be published. Required fields are marked *