What are common inter-task communication mechanisms in an RTOS?
Beyond mutexes and semaphores (which are synchronization primitives), RTOS kernels provide several mechanisms for tasks to exchange data.
Message queues are the workhorse of RTOS inter-task communication. A queue is a FIFO buffer where one task (or ISR) sends messages and another task receives them. The sender and receiver are decoupled — the sender does not need to know when the receiver processes the message. Queues are ISR-safe (using FromISR variants in FreeRTOS) and handle both synchronization and data transfer in one primitive. They are ideal for producer-consumer patterns, such as an ISR that reads a sensor and posts the value to a queue for a processing task.
Event flags (or event groups in FreeRTOS) allow a task to wait for one or more events to occur, specified as bits in a bitmask. A task can wait for "any" (OR) or "all" (AND) of the specified bits. This is useful for synchronizing on multiple conditions — for example, waiting for both "network connected" AND "configuration loaded" before starting the main application.
Direct-to-task notifications (FreeRTOS-specific) are a lightweight alternative to semaphores and event groups. Each task has a built-in 32-bit notification value that can be used as a binary semaphore, counting semaphore, event group, or simple mailbox, with significantly lower RAM overhead than a dedicated synchronization object.
Shared memory with mutexes is the simplest approach — tasks read and write shared global data protected by a mutex. It works well for small, infrequently updated data (like a configuration struct) but scales poorly and creates coupling between tasks. Queues and notifications are generally preferred for new designs because they naturally decouple producers from consumers.
Source: Operating Systems & RTOS Q&A
