freeRTOS: How to pass data between tasks?

14.7k views Asked by At

I am looking for an example that present a proper way to pass data between tasks:

Lets say I have a display, keyboard and some sensors eg. internal ADCs. I would like to show values from all sensors at some time on a display. After pressing a button, changing a view and presenting some text. After pressing another, going back to values.

I would use global variables, but it is described everywhere as a bad idea. On the other hand, if I used Queues (xQueueCreate, xQueueReceive, xQueueSend), I wouldnt have all data to display it and I believe that creating a copy after receiving them is just losing memory.

1

There are 1 answers

0
koper89 On

You already mentioned some of possible solutions, but saying that you're loosing memory because you copy data, it's always the case if you want to secure this data from i.e. writing from two different places, anyway just by using FreeRTOS you already decided to loose a lot of memory for i.e. context switching, task handling and all other resources that FreeRTOS uses. Possible solutions are:

  1. Global variable - The reason's why it's a bad idea, is because ideally you want to limit access to variable (scope). As well it's hard to keep it safe, because during task switch other task could write to the same variable, and possible corrupt your data. But if you protect it right i.e. lock the variable using some kind of flag, it's perfectly fine solution, and using i.e. sempahore or queue to notify display task that data is filled.

  2. Queues - you could send from multiple tasks and as you said keeping in display task copy of variables, it's much safer option, and it doesn't have to be loosing memory, because you don't have to store it any other place, you could just read sensor, then put it in queue, and then when you received it in display task you change your previous value. So task which read's data from let's say ADC doesn't need to store it in between reads.

  3. Queues - but a little bit different that you proposed, if you got direct flow in system let's say first you check keyboard, then sensor, then something else you could send queue with struct from TASK1 -> TASK2 -> TASK3 -> ... TASKX -> DISPLAY_TASK this way variable would have certain flow, and you would make sure that you always have all data in one place.
  4. You could use the same paramater in all structs (pvParameters in taskCreation), so you would point to the same structure, in this case to protect data you could use mutex during write to variable (so you know only 1 task at a time got access to this variable). You could use mutex in global variable option as well.