FreeRTOS Tutorial #5 ->Using Queue
This is the Fifth tutorial in the series of FreeRTOS, and today in this tutorial we are going to learn how to use Queue to communicate between the tasks. You can check the other tutorials on FreeRTOS by going HERE. Beloe is the picture of How the Queue works, and it’s self explanatory.
Queue is the easiest way to send and receive data between the tasks. We are going to use the simple queue at first, where all the elements in the Queue are of same data types, and later we will use a structured Queue, where the data types can be different.
As I mentioned, in a simple Queue all the elements are of same type. For example a Queue can only hold 5 integers, or 6 characters, or 3 unsigned integers etc.
A Queue is recognised by it’s handler, so first of all we need to create a handler for the Queue
Next, inside the main function, we will create a Queue, which can store 5 integers
If there is an error while creating a Queue, like shortage of memory, than the
xQueueCreate function return a ‘0’. Otherwise it will return any other value. The above strings will be printed on the console based on if the Queue was created successfully or not.
Inside the sender task function, we can send the data to the Queue using the following
The parameters of
xQueueSend are handler to the Queue, the address of the data to send, and the waiting time incase the Queue is full. I have specified the waiting as portMAX_DELAY, that means the task is going to wait forever for the space to become available in the Queue. For this waiting time, this task will be in the suspension.
If the data is sent successfully, the
xQueueSend function will return pdPASS, and we can print the string for the confirmation.
On the other hand, RECEIVER TASK will receive this data, and store it in a variable.
The parameters of
xQueuReceive are handler to the Queue, the address where the data is to be stored, and the waiting time incase the Queue is Empty. I have specified the waiting as portMAX_DELAY, that means the task is going to wait forever for the data to become available in the Queue. For this waiting time, this task will be in the suspended State.
Again, if the data is received successfully,
xQueueReceive will return pdTRUE, and we can display the data on the console.
If we want to send the data to the Queue from an ISR, we have to use the interrupt safe version of these functions. Below is an example of How to send the data to the Queue from an ISR
xQueueSendToFrontFromISR will send the data to the front of the Queue. All the data, which is already available in the queue, will shift back and next time if we read the Queue, we will get this particular data.
Also note that there is no waiting time here. So if the Queue is full, the function will simply timeout, as in the ISR, we can’t afford to wait for the space to become available in the Queue.
Below Shown is the result of this code.
Like I mentioned in the beginning, if we want to send the different data types, we have to use the Structured Queue.
First of all create the handler for this Queue
We need to create a structure which can store all the data types that we want to use. I will call it
Next, inside the main function, create the Queue
Here I have created a Queue which can store 2 elements of my_struct data type. Again if there is some error while creating Queue, the
xQueueCreate will return 0, or else it will return any other value.
We will now send the data to this Queue from a sender Task
Before sending the data to the Queue, we must allocate the memory to the structure. And to do that, we use the function
After allocating the memory, Load the data into the pointer to this struct.
Next, we will send this data to the Queue by passing it’s address in the parameter.
We will create another pointer to struct in the receiver function to store the received data.
After receiving the data, we will free the memory allocated by the sender Task using
The result for the above code is shown below