Dual core MCUs support?

Hi guys,
I was wondering if arduinoIDE supports dual core MCUs better than (micro)-python does?
The RP2040 and STM3 would perform better if we would use both cores in the best possible way.
I don’t know if that is implemented in sFOC somehow, but it would compensate the fact, that these MCUs run at relative low clock rates.

I thought of splitting the tasks in two main chunks: FOC control and user interface.
One core could do all the math, while the other shows motor.monitoring and commander interface on a local OLED touchscreen.

Another option would be to run ATAN2 approximation on one core while the other does all the PID stuff…

Is that possible with arduinoIDE at all?
I know the ESP32 has two cores, but I haven’t seen any example in IDE using both.

Sorry if I’m talking BS, but I had some exciting projects with Docker containers running on my multicore network cluster, but that’s Linux

No, Arduino framework is designed to be simple, and originated on a single-core 8-bit ATMega MCU, and so it has no concept of threads or parallelism, other than simple interrupts.

However, because the framework is so simple, it is generally possible to use Arduino framework in conjunction with other frameworks that can handle multiple threads and processors. An example of this would be FreeRTOS as used on ESP32, STM32 H7 or RP2040 MCUs.

However however, you should also keep in mind that parallelism in embedded development, at least in the performance-critical domains like motor control, is fundamentally unlike that of managed code (JavaScript, .NET or Java, etc) or loosely coupled systems (microservices, docker) in the sense that these abstractions provide all the fundamental synchronisation blocks so that you only have to deal with application-level parallelism.

On the MCU, parallel really means at the same time, and this means you could be reading/writing the same memory locations or peripherals at the same time as some other process - with disastrous consequences.

So I think you suggestion of separating comms and motor control onto different cores is a natural division, and as long as you take care how you pass values between the two processes this can work well.
On the other hand, trying to move trig functions onto the second core will be painful and not very beneficial, I suspect.

I know multi threading support is implemented for the pico. I don’t know if you can access it in arduino.

I can use multiple threads in micropython but the basal functionality is still not really done. It keeps crashing etc. I can do a test where I do the same thing on one core and the other core, and on one core it crashes while the other it’s fine. So it’s a bit borked. I don’t know if the threading support under C++ for the pico is any better.

You don’t need simplefoc to support multiple threading, the way it works is that you execute the function you want on whatever core you want. So you could run the motor.loop() function on one core and then use the other core for whatever. That would make a lot of sense. What I was thinking of doing is running the waveform generation on one core and everything else on the other core. This is because communication etc. takes time in a blocking way under arduino sometimes, and this causes glitches in the waveform which leads to noise production and vibration. This could be overcome by using both cores.

However as Runger points out the cores can trip over each other and cause issues, I have read that there are provisions to prevent this and make things easier for the programmer. In the pico there is a prioritizaton scheme that helps, if both cores try to access something core 0 just gets priority for instance.

However the pico does not have floating point hardware while the g431 MCU does, it has an m4 core. This makes it a lot faster, in my testing the mcu at 168 mhz ran motor.loop() seven times faster than an m0 core at 64 mhz.

Thank you both for taking my suggestion serious.
I have some experience with Siemens S5 SPS-coding, where we used to use semaphores to handle access to critical subsystems.
In case of a dual core, I see shared registers , RAM and comm periphery like SPI, serial
as critical.

If both threads have a less timing critical connection, we could use a semaphore like this:

//pseudo code
while (! RAM-access)
   NOP
else
   go_on with your code

For more time-critical stuff it would be helpful to know, how much time a subroutine takes.
Then it wouldn’t matter, which core runs this subroutine. The other core could do something else, while waiting for the result

It would be interesting to see if it’s possible to have two motor/sensor combos controlled in split brain fashion by one dual core MCU.
One core for each combo with a bit of semaphore handling…

That would require a new inter-core comm class.
Some of the required structures are already there in every compiler, since any MCU has to deal with HW-implemented stuff like SPI or CAN or quad encoders. Dealing with a second core is pretty similar IMHO.

FreeRTOS on ESP32 provides all that synchronisation stuff like semaphores.I missed it though on STM32 (G431), but that’s not multicore anyway.

1 Like

Don’t expect too much there. If you are in an ISR, it is your responsibilty to synchronize things. Typically, the compiler won’t do it for you (exceptions may exist).

Yeah semaphore locks are supported in the C++ libraries for the pico I have read that.

This example for RP2040 ==>
https://github.com/earlephilhower/arduino-pico/blob/master/libraries/rp2040/examples/Multicore/Multicore.ino
I have not tested …

2 Likes

I’ve digged deeper into the multicore subject and there seems to be some outdated stuff popping up in google search.
Then I found a readTheDocs link, which automatically lists the latest info.
It seems the arduinoIDE knows some routines for multithreading/multicore which should work on all STM3 M0 MCUs. (mainly mbed.h and Scheduler.h)
I’ve just started reading it, but hoped to gain some interest here. Some of the stuff is over my head.
So far my impression is, to run low prio tasks and (USB-) comms on core0 and leave core1 for time critical number crunching.
Inter-core memory is available and semaphore-like voids too ( void rp2040.idleOtherCore()

Most people use FreeRTOS with Arduino, which is well documented and supported in many processors. For example ESP32 Dual Core using FreeRTOS and Arduino IDE - Multitasking. You can assign tasks to specific cores on the ESP32 and ensure that the time-critical portions are run on the processor not handling WiFi or Bluetooth communcation, improving the real time handling.

If you search for “arduino freertos rp2040” (no quotes) you will also find quite a lot of documentation and videos

1 Like

I wouldn’t mind to use another platform, but I’m afraid I wouldn’t get support from the devs here?
I guess, the average user would also shy away, if the whole thing gets too complicated.

Over at RepRapFirmware they use freeRTOS too, it might be helpful to port simpleFOC library to freeRTOS. Would be a lower hurdle, if they ever decide to implement it.
They also use the Cortex M0 MCU on some boards. I might ask there, if and how they use dual core.

Why not get something working without FreeRTOS or threading first? It really is not necessary for motor control, nor many other applications.

The difference in complexity between Arduino’s simple single threaded model and any kind of threading system implemented on bare metal is huge.