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.
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.