cancel
Showing results for 
Search instead for 
Did you mean: 

freeRtos and coordinating 2 tasks

SGasp.1
Senior

Hi forum ...

I am using freertos inside my stm32f7 MCU..

I have 2 tasks ..

One task is reposnsible for sending data (UART ) every *** ms to another board..

One task is responsible of reading a text file via usb and writing in a global variable the data that has to be transmitted from the other task

I want to transmit data only once the reading of 8 bytes of the file is done,,,

Which is a safe way to coordinate these 2 tasks ?

Thanks a lot

For the moment I added a delay in the task which reads the txt file and I transmit the information with the same delay of the task...

But it seems it is not working..

It seems it is loosing the sync

Can you help me ?

Thanks

5 REPLIES 5
JPeac.1
Senior

Since you are using FreeRTOS there are several services to help with synchronization. You have an input task on USB and an output task using a USART. These I/O operations are not synchronized, so you need to buffer data.

Create a message queue with the message size equal to the amount of data you extract from the USB text file. Instead of a global variable, post those completed messages to the message queue. Your input task is write only to the queue. If you receive an insufficient space error you have detected a data overrun condition, incoming data arriving faster than it can be serviced. The queue buffer size should be large enough to handle the fastest possible data arrival on the USB side, so make it a multiple of individual message size.

The output task opens the same message queue, acting as a drain on the messages being posted to it. The output task is blocked until a complete message is posted to the queue. This is your synchronization; you are guaranteed a complete message as soon as it is ready. The output task removes the message from the queue and transmits it via the USART. If multiple messages are in the queue, then the task loops, continually extracting messages and sending them until the queue is empty, at which point the task again blocks.

That's it. It will run as long as no error conditions occur. You will have to determine if the USART receiver can handle the worst case, multiple back-to-back messages sent at one time. Depending on how often data arrives on the USB side this may not be an issue. You will also have to determine how to handle error conditions, such as input overrun or USB disconnect.

Jack Peacock

SGasp.1
Senior

Hi Jpeac... Since the Input fast is running very fast once I have written the queue Can I put a delay on the Input task ?

/*delay for allowing comm task to send data*/
vTaskDelay( xDelay );

When after the delay I check if the queue is empty so I can write on it

Queue not need be empty, can handle more messages, based on size.

Delay is for leave other tasks do jobs.

JPeac.1
Senior

When you create the queue make it large enough for several messages, say, ten or more, depending on how fast data arrives. You don't need to check the queue before posting a message; the queue write call will return an error if it is already full. If your incoming data arrives in bursts then size the queue for twice the largest number of messages in a burst.

In general it's considered a bad programming practice to use timed delays unless there is no alternative. IN real time programming a spin lock (i.e. a timed delay while polling an I/O port or waiting for another process to complete) should be avoided. Rely on interrupts (more generically, events) to control the flow of your program. This gives the maximum possible CPU time to performing useful work in tasks.

If your incoming data on average arrives faster than the outgoing UART can transmit the data then you will have to either signal a failure to the host or drop some of the incoming data.

Jack Peacock

SGasp.1
Senior

Hi Jpeac.1,,, The data comes from the reading o txt file... so I think that they come very fast,,

I can read each line with a while loop for example and inserting in the queue every row.

But the communication task which is responsible to send these data to another microcontroller is set to run every 25ms...

So i think if i don't introduce a mechanism to slow down the reading the queue will be full very soon.

I cannot speed up too much the sending of the data because since these data (read from the txt file) are the update fw for a stm32f4 MCU .

Every for exmple 16 bytes i have to stop the interrupts in the stm32f4 board (blocking also the communication). for flashing the data..

So I have to send data not too fast..

I think now you have the big picture of all the process..