Page 1 of 1

freeRTOS: How to pass data between tasks

Posted: Fri Jan 06, 2017 11:32 pm
by Espagnole
Lets say I have 3 tasks: 1. for display and keyboard, 2. and 3. for ADC measurements.
How should I pass data between them?

Code: Select all

int ADC_VALUE_1 = 0;
int ADC_VALUE_2 = 0;

void display_and_keyboard_task(void *pvParameters) {
	while (1) {
		if (shouldInit()) {
			init();
		}
		if (xSemaphoreTake(display_semaphore, 10 / portTICK_RATE_MS) == pdTRUE) {
			if (flags & UPDATE_VIEW) {
				switch (view) {
				case MAIN: {
					// ...
					writeToDisplay("ADC1 ", ADC_VALUE_1, "ADC2 ", ADC_VALUE_2);
					break;
				}
				// case ...: ...
				}
			}
		}
		readKeyboard();
	}
}
void adc1_task(void *pvParameters) {
	while (1) {
		ADC_VALUE_1 = measure();
		flags |= UPDATE_VIEW;
		xSemaphoreGive(display_semaphore);
		vTaskDelay(100 / portTICK_RATE_MS);
	}
}
void adc2_task(void *pvParameters) {
	while (1) {
		ADC_VALUE_2 = measure();
		flags |= UPDATE_VIEW;
		xSemaphoreGive(display_semaphore);
		vTaskDelay(200 / portTICK_RATE_MS);
	}
}

Re: freeRTOS: How to pass data between tasks

Posted: Sat Jan 07, 2017 10:28 am
by WiFive

Re: freeRTOS: How to pass data between tasks

Posted: Sat Jan 07, 2017 10:41 am
by Espagnole
I absolutely know what queues are.
Take a look: 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.
If I used Queues (xQueueCreate, xQueueReceive, xQueueSend), I wouldnt have all data to display it; I believe that creating a copy after receiving them is just losing memory and it's not the point because project will grow up and these values will be needed in the other places.

I would use global variables, but it is described everywhere as a bad idea (I still dont believe and dont know the reason of its being bad).
Variables are single int (32-bit variable) from each ADC task, only ADC writes to its variable. Other tasks will read it. ADC task and display task DO NOT work on the some core.

Re: freeRTOS: How to pass data between tasks

Posted: Sat Jan 07, 2017 12:46 pm
by rudi ;-)
Espagnole wrote:
Take a look: 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 (I still dont believe and dont know the reason of its being bad).
Variables are single int (32-bit variable) from each ADC task, only ADC writes to its variable. Other tasks will read it. ADC task and display task DO NOT work on the some core.

hi

why not share/swap pointer pointer address?
https://github.com/ESP32DE/News-spread- ... _bt.c#L179

and set the new val after get the ADC
https://github.com/ESP32DE/News-spread- ... _bt.c#L207

have a look to the break of const variable by swap pointer and address.
https://github.com/ESP32DE/News-spread- ... n/app_bt.c

and RTFM of rtos :mrgreen:
(fun)

hope this helps

best wishes
rudi ;-)

Re: freeRTOS: How to pass data between tasks

Posted: Sat Jan 07, 2017 1:32 pm
by WiFive
You can use shared (global) memory with a mutex. Then use a queue or event group to tell the task when the value changes so you don't have to refresh the display if nothing changed.

Re: freeRTOS: How to pass data between tasks

Posted: Sat Jan 07, 2017 1:40 pm
by Espagnole
@rudi You have const string in memory so you can change the pointer. I have new data, so I would have a variable and change its value.
Anyway, if changing 1 word pointer is ok, changing 1 word variable wold be also.
Where is the key that "it is described everywhere as a bad idea"?

Re: freeRTOS: How to pass data between tasks

Posted: Sat Jan 07, 2017 2:05 pm
by rudi ;-)
Espagnole wrote: Where is the key that "it is described everywhere as a bad idea"?
the key is, you not can controll the access / modification on this var by this way.
you not know, when who or how the var was changed. it can be that an ealier process have change the var,
the next process change too, then you miss the prev val.

like WiFive mentioned, better to inform with event group ( tags ) and work with the que.

hope this helps.
btw you can use the share ( global var ) on this way with pointer too,
the way when you then "set" and "read" the value is the "key".

best wishes
rudi ;-)

Re: freeRTOS: How to pass data between tasks

Posted: Sat Jan 07, 2017 2:39 pm
by Espagnole
I don't get it
you not know, when who or how the var was changed. it can be that an ealier process have change the var,
the next process change too, then you miss the prev val.
I pass data to a display. User wouldnt see a difference between data refreshed every 5ms and 200ms. Moreover when I refresh it only last value is interesting for me.

What about that situation?

Is it possible that when the two tasks operate independently on different cores, one is writing to the variable, the second reading at the same time, some bits in byte would be a part of the new value and some of the old value? What about larger data: string (char array) some changed, some not?

Re: freeRTOS: How to pass data between tasks

Posted: Sat Jan 07, 2017 2:52 pm
by WiFive
Espagnole wrote: Is it possible that when the two tasks operate independently on different cores, one is writing to the variable, the second reading at the same time, some bits in byte would be a part of the new value and some of the old value? What about larger data: string (char array) some changed, some not?
Yes that is why you use mutex.