FreeRTOS Producer Consumer Tasks


To learn how Tasks and Queues work.

Queues and Task Priorities

Tasks of equal priority that are both ready to run are scheduled by the RTOS in a round-robin fashion.  This type of context switch is called Preemptive Context Switch.

Queues' API can also perform context switches, but this is a type of Cooperative Context Switch.  What this means is that if an xQueueSend() API is sending an item to a higher priority task that was waiting on the same queue using the xQueueReceive() API, then the sending task will switch context inside of the xQueueSend() function over to the other task.  Therefore, task priorities matter when using the queue API.

QueueHandle_t q;

void producer(void *p) /* LOW priority */
  int x = 0;
  while (1) {
    // This xQueueSend() will internally switch context over to the "consumer" task
    // because it is higher priority than this "producer" task
    // Then, when the consumer task sleeps, we will resume out of xQueueSend()
    // and go over to the next line
    xQueueSend(q, &x, 0);

void consumer(void *p) /* HIGH priority */
  int x;
  while (1) {
    xQueueReceive(q, &x, portMAX_DELAY);

void main(void)
  // Queue handle is not valid until you create it
  q = xQueueCreate(10, sizeof(int));



  • Create a producer task that polls the acceleration sensor, and determines the orientation of the board.
    • Create an enumeration such as typdef enum { invalid, up, down, left, right } orientation_t;
  • Create a queue, and have the producer task send orientation values every second to the queue.
  • Create a consumer task that is waiting on the orientation enumeration to be sent by the producer task.
  • Note down the observations by doing the following:
    • Print a message before and after sending the orientation to the queue
    • Print a message after the consumer task receives an item from the queue
    • Use the same priority for both tasks, and note down the order of the print-outs
    • Use higher priority for the receiving task (consumer task), and note down the order of the print-outs.
  • Answer these additional questions :-
    • What if you use ZERO block time while sending an item to the queue, will that make any difference?
    • What is the purpose of the block time during xQueueReceive() ?

What to turn in:

  • Submit all relevant files and files used (includes previous lab code used).
  • Turn in any the screenshots of terminal output.
  • Explanation for the different priority situations.
  • Explanation for the additional questions.

Extra Credit (This will also help when you do the future labs)

Create a terminal command: "orientation on" and "orientation off". If orientation is commanded on, resume the Producer task, otherwise suspend it. See code below on hints of how this command can get control of another task.

Command Handler Code Snippet

// At the terminal tasks taskEntry() function :
bool terminalTask::taskEntry()
    cp.addHandler(orientationCmd,  "orientation", "Two options: 'orientation on' or 'orientation off'");

// Somewhere else:
    // You can use FreeRTOS API or the wrapper resume() or suspend() methods
    if (cmdParams == "on") {
    else {
    return true;
Back to top