I am trying to understand how a message queue works. Suppose we have an RFID reader connected to a 32-bit MCU through UART. When a tag is placed in front of the reader, it sends a 12-byte RFID data frame to the MCU. After receiving the RFID data, the MCU sends it to a laptop through another UART.
Assume there are two tasks:
RFID Read Task
MCU Send Task
My understanding is that the RFID Read Task runs until it receives a complete RFID message (12 bytes) in queue. Once the complete message is received, it places the message into a queue and then blocks waiting for the next RFID message. The MCU Send Task is blocked while waiting for data in the queue. When the RFID Read Task writes the complete message into the queue, the MCU Send Task wakes up, reads the message from the queue, sends the data to the laptop, and then blocks again waiting for the next message.
In short, can we say that task priority does not matter when the queue is empty, the RFID Read Task runs, and when the queue becomes full, it blocks? Then the MCU Send Task runs and continues until the queue becomes empty, after which it blocks again.
There are Queues (not Message Queues) and Message Buffers.
It sounds like you are describing your Read Task, to read data from a serial port into a local (to the task) buffer, and then puts the full buffer as a single item into the queue.
As such, the Send task will be blocked on the queue until something is placed in it (or its request times out). As soon as the Read task puts the message in the queue, the Send task is unblocked, and it if has a higher priority, it starts immediately. Otherwise, it waits until the Read task blocks on reading its next character. (I am assuming a single-core processor here).
Note, the Read task doesn’t just continually run when the Send task is blocked on the empty queue, unless you have a broken system, as the Read task should be blocking waiting on characters from the Uart. (I hope you are not using polling loops to handle the Uart).
Also, the Send task won’t necessarily run continuously, (unless your Uart buffer is big enough) as when the buffer fills, it will block (and allow the Read task to run if it unblocks) until more room is available.
Message Buffers work sort of like Queues, but can handle variable-sized buffers, while the basic Queue only handles fixed-sized buffers.
so RFID Read Task is normally blocked waiting for data from the RFID reader UART. As UART bytes arrive, it collects them until a complete RFID message (12 bytes) is received. Once the complete message is assembled, the RFID Read Task places the message into a queue and then goes back to waiting for the next RFID message.
The MCU Send Task is blocked while waiting for data in the queue. When the RFID Read Task places a complete message into the queue, the MCU Send Task is unblocked, reads the message from the queue, sends the data to the laptop through UART, and then blocks again waiting for the next queue message.