Single buffer accessed by two threads

I am trying to understand the basic concept on how the single buffer can accessed by two threads.

For example we have a one thread that receive a date of from the sensor and store into the array buffer[ ]

In a another thread we want to transmit array buffer value to PC.

What technique do we need to use the same buffer so that the buffer used in the first thread can be accessed in the second thread

(Arduino IDE and ESP32)

To access a buffer by more than one task, it just needs to be declared in a spot that the code for both tasks can see.

The trick is making sure that the various accesses are synchronized in a way that both tasks work as desired, and the details of that depends, to an extent, on the processor that the program is being run on.

You also will tend to want to do something so that a task doesn’t just keep using CPU time when it doesn’t have any work to do.

The FreeRTOS Queue could possibly handle all your needs the way you have described, one task puts new readings onto the Queue, and the second task reads values, when available, from the Queue and sends them out.

1 Like

Can we use Mutex to share the same buffer between two threads

Yes, a Mutex can be used to handle the synchronization issues between two tasks. It won’t handle handle the likely desire to block the reader if the buffer is empty.

It is possible to use a Queue, but that might not be the most efficient for this kind of application. Queues are useful for servers and to create APIs to a server.

I would recommend reading about Stream Buffers, and here some examples.

Also worth reading is about Counting Semaphores.

A light-weight method of waking up a task is Task Notification, and more explanation here.

Many possibilities, find what feels good for your application.

We do this quite a lot, using ring buffers. The put-pointer is read/written by the first task and only read by the second task. The get-pointer is only read by the first task and read/written by the second task. The pointers are 32-bit and the processor is 32-bit, so accesses to them are atomic. Both pointers are declared volatile (or more recently are atomic C++ types) so that the reading task knows that they are likely to change.

The one possible issue with a build it yourself ring buffer is that a task can’t block to wait for data, so you need to use some other primitive to handle the blocking.

The one possible issue with a build it yourself ring buffer is that a task can’t block to wait for data, so you need to use some other primitive to handle the blocking.

Yes, we use task notifications when we need to block because the buffer is empty or full.