FreeRTOS Passing Varibles (Arduino Uno)

jaxxs1 wrote on Tuesday, May 02, 2017:

Hello
Being new to FreeRTOS i’m struggling to work out how to pass char arrays from one task to another?
Before using FreeRTOS I would simply create functions and pass data received from the serial port. Once a start and stop bit was received I would then pass the data to a function to do some work.
I now have a task purely looking at the serial port in-coming data and once a command has been received I then need to pass it to another task to process the char array and perform a task.
I’m not able to work out how to pass the receive data array to the process data array task?

struct config_t{
        char *atf;   //incoming data command stored here
}config;

void TaskReadSerial( void *pvParameters );
void TaskProcessData( void *pvParameters );

How do I pass char *atf data received in TaskReadSerial to TaskProcessData?

So I’m using atmel studio and the arduino framework for a 328P AVR

Any help will be greatly appreciated

Many thanks,
Mark

rtel wrote on Tuesday, May 02, 2017:

     char *atf;   //incoming data command stored here

I presume you know this already, but in case not, this is not allocating
space to store data, merely allocating a pointer that can point to data.

There are many ways you could pass received data to another task. The
best method will depend on how many bytes are being passed.

If there are relatively few bytes, say less than 5, and if data is
arriving slowly, then you could copy the bytes into a queue
FreeRTOS task communication and synchronisation with queues, binary semaphores, mutexes, counting semaphores and recursive semaphores. Each demo
project in the FreeRTOS download demonstrates how to do this, and the
FreeRTOS book will also walk you through it
Free RTOS Book and Reference Manual. Each space in the
queue will need to be large enough to hold the maximum number of bytes
the message can contain though, hence this is only suitable for small
amounts of data. The benefit of doing it that way is each task has its
only copy of the data, so you don’t need to worry about one task
corrupting data that is being used by another task.

Another way is to have more than one buffer and just pass a pointer to
the buffer between tasks on a queue. For example, when buffer A
contains a message pass the address of A on a queue to the other task,
then start using buffer B. Once buffer B contains a full message pass
the address of B to the other task. If the other task has finished with
buffer A it can be used to hold the next message again, etc. This
scheme has the advantage that the queue only needs to hold pointers, not
the actual data, so the queue storage area is smaller. It is harder to
implement though as you need to make sure that only one task is using
any given buffer at any given time.

There are many other ways too. For example, just write the data into a
circular buffer, and use a task notification, event group, counting
semaphore, etc. to unblock the task that reads from the buffer each time
a complete message has been received.

jaxxs1 wrote on Wednesday, May 03, 2017:

Thank you for your response. I’m very new to micro development having to rely on arduino forums to get examples on how to do things (something I need to work on and get better at).
I will see if I can work through some examples and get what I need working.

Thanks,
Mark

richard_damon wrote on Friday, May 05, 2017:

One quick comment is the “Arduiino” way of doing things is very different from the RTOS way of doing thngs. The first very big question is why do you think you need a seperate task to read the data from the serial port and to process it? Presumably, the serial port is interrrupt driven (if not, that is your first thing to do). If the serial port is really just a serial port at a reasonable speed, the simplest way to get the data from the serial port to a task is a character base queue (thiis would be inefficent if it was very high speed and/or very large messages, but for typical serial protocals it isn’t that bad).

If you have multiple serial ports (or other similar streams) coming in that can possible send command to the “ProcessData” operation, then it would make sense to have a FUNCTION (not a task) that you call with the character array, and it processes it. ProcessData may need some mutual excusion within it depending on what it does.

Generally, I have one task (and only one task) for each thing I need to be waiting for that kicks off a specific set of operations.