Skip to content

Multicore Processing

Phil Schatzmann edited this page Mar 31, 2024 · 20 revisions

So far I never needed to use any of the ESP32 multicore functionality because all the examples are very simple and everything is fitting on a single core. However if you write some more complex scenarios which are e.g. updating a screen, process user input w/o impacting the audio, you should consider to use multiple tasks. Then you need to use a save way to communicate data between the tasks.

  • Task: a simple C++ class which represents a FreeRTPS task.
  • BufferRTOS: a FreeRTOS StreamBuffer implementation using the BaseBuffer API
  • Mutex: with different implementations per platform.
  • LockGuard: a RAII class for managing the Mutex
  • SynchronizedBuffer: which allows you to use any BaseBuffer implementation in a save way

Task

If you use an processor that supports FreeRTOS, you can start multiple tasks

#include "AudioTools.h"
#include "Concurrency/Concurrency.h"

Task task("write", 3000, 10, 0);
void method(){}
task.begin(method);

BufferRTOS

If you use an ESP32, it is much more efficient to use a FreeRTOS StreamBuffer. Just write the data with writeArray() on one Task and read it back with readArray() from the other task. It is the same API you would use with any other class which is based on BaseBuffer

#include "AudioTools.h"
#include "Concurrency/Concurrency.h"

BufferRTOS<int16_t> buffer(2048, 512);

In my test sketch I was measuring a thruput of 36.57-37.93 Mbytes per second.

SynchronizedBuffer

Here is an example how to use the SynchronizedBuffer class. Just wrap one of the existing buffer classes. Here is an example of a thread-save Double Buffer:

#include "AudioTools.h"
#include "Concurrency/Concurrency.h"

audio_tools::Mutex mutex;
NBuffer<int16_t> nbuffer(512,2);
SynchronizedBuffer<int16_t> buffer(nbuffer, mutex);

In my test sketch this was giving a thuput of only 1.68 Mbytes per second.

Here is a thread-save RingBuffer

#include "AudioTools.h"
#include "Concurrency/Concurrency.h"

audio_tools::Mutex mutex;
RingBuffer<int16_t> nbuffer(512*4);
SynchronizedBuffer<int16_t> buffer(nbuffer, mutex);

and I was measuring 2.35 Mbytes per second.

Examples

Summary

I am providing the most important multi core functionality as C++ classes. Alternatively I recommend to use the arduino-freertos-addons which provides all the functionality you need in an elegant way: Just read the Readme of the project. However, if you prefer you can also use the official FreeRTOS C API.