From Arduino to RTOS

Good day,

I have a custom designed Arduino Due board driven by the Arduino Framework.
As my application has grown, I am thinking about switching the framework.

The main point is, that the Arduino framework has no threading capability.
On the other hand, there a plenty of libraries available for Arduino framework and it would be hard to re-build them all.

Currently I am using a timer based implementation as non-blocking approach.
I noticed, that PlatformIO does support Simba or Zephyr, but I am not completely sure what consequences a switch would cause.
Is the SAM3X8E compatible with one of these RTOS?

I also saw, that there are some Arduino libraries (HeliOS, FreeRTOS for Android) are out there, which introduces tasks. Would that be a valid approach to get the best from both world?
I can use the Arduino libraries and also get tasks? Could you recommend one of such libraries?

I also thought about switching the whole platform from Arduino to STM32. That said, then also the question raises to witch platform I should switch.
Technically speaking, this could be the best approach, but unfortunately also the most expensive approach. That’s why I would probably not got for that.

You see, I am not quite sure where to go and I would love to get your thoughts and guidance on that …
Best

Nobody here who can give me some guidance?

Are you still looking for advice here?

I’m only just aware of Helios, but it has a library for use with PlatformIO (add lib_deps = mannypeterson/HeliOS @ ^0.2.6 to your platformio.ini) .

While it works fine with framework = arduino (my board is an Uno, not a Due) I don’t want to be using the Arduino Language and it’s not finding its various header files when I remove the framework line. A minor problem that I’m looking into at the moment. :grin:

However, it shows promise. The obligatory Uno blink sketch, using HeliOS, takes:

RAM:   [=         ]  11.8% (used 242 bytes from 2048 bytes)
Flash: [=         ]   7.1% (used 2302 bytes from 32256 bytes)

So it’s a bit bigger than the default blink sketch which is 9 bytes of RAM and 924 bytes of Flash, but I suspect as the applications gets more complex, the overheads will diminish.

Sorry I’m not able to give you much more information at this time, but watch this space!

Some Arduino Language examples are at HeliOS/examples at master · MannyPeterson/HeliOS · GitHub if that is of any use?

Cheers,
Norm.

Hallo Norm,

thanks for your reply.
I am in fact still interested in this topic.
As I said in my first post, I started with the arudino framework and as the projects grows, I am wondering if there is a better solution. That said, I cannot change the hardware that easy.

When you say, you’re only familiar with HeliOS, it’s not the Arduino library, is it?
I am not aware, that it’s a standalone framework. I guess, that the shown overhead is constant. In a bigger project HeliOS is still the same size than in the minimalistic blink sketch.

The HeliOS library for Arduino has the advantage, that I do not have to change any library. It’s just an addition to the Arduino Framework.

Again, thanks for your impressions!
Hope to see more answers and guidance … :slight_smile:

Best,
caldi

Hi @caldicot,

I’m just getting started with HeliOS and I’ve found that it is Arduino specifc when used on an AVR microcontroller.

It expects to see at least one #define at compile time which is for a #define created by the Arduino IDE. If found it will then #include "Arduino.h" otherwise, it will throw an error.

Until I rewrite it :astonished: it can only run under framework = arduino.

So far, it looks to be ok. It does have a limit on the number of tasks it can control though. There’s an open issue on Github on the matter. 8 seems to be the limit but I’m sure a quick edit in either HeliOS.h or task.h will fix that. Arduino memory limits allowing of course.

I shall persevere, wife and/or Christmas allowing, as it looks very interesting.

Another interesting one is written about at Don't Delay() Use an Arduino Task Scheduler Today! - Hackster.io.

Disclaimer: I have a pull request open to fix a problem when millis() rollsover from 0xffffffff to 0x00000000 but I’m not sure if Kevin has merged it yet. Read the comments on the article for details.

I might revisit this one too, to see if I can get it working in AVR C/C++ code under PlatformIO.

Have fun.

Cheers,
Norm.

Norm,

it’s been a while since HeliOS 0.2.6. Now on 0.4.1, HeliOS has become much more mature. 0.5.0 will bring ability to mount filesystems. Check it out if it’s been a while.

Manny

1 Like

Hi, why not freeRTOS with ESP32 ?

Thanks for your suggestion.
Yes indeed, this is something I am currently looking into. Especially, as the ESP32 as BT and WiFi on board. They’re cheap and future proof. And I do have the possibility to let run the Arduino code on ESP32 with the framework. That said, this would probably also possible with STM32 but haven’t tested it yet.

STM32 has probably the greater platform in means of sensors, drivers and tools.
One big problem for me is, to find a reliable graphics library that is capable of graphics, fonts, buttons … even touch could be a possibility in the future.
STM32 does offer TouchGFX, unfortunately for Windows only; but at least a solution…

Hi Manny. I’m in Canada at the moment, but when I get back to the UK, I’ll check out the latest version.

Thanks.

I recommend considering STM32 seriously for this and future project. Wire range of MCU, extensive community support, good prices, and affordable hardware debuggers.

https://docs.platformio.org/en/latest/platforms/ststm32.html#frameworks

You can start for example playing with one of the inexpensive ‘black pill’ STM32F401 or SMT32F411 modules https://www.amazon.com/dp/B0B68N34S4 . For hardware debugger search for st-link v2, even the originals are affordable.

With proper design, even a non blocking single thread sketch can be very powerful, but there are RTOS’s available such as Zephyr.

https://docs.platformio.org/en/latest/platforms/ststm32.html#frameworks

Thanks for your thoughts. I am not very expierenced with STM32 mcus. I see two problems. The amount of hardware is overwhelming and wifi/bt is harder to add.
In addition, the project is currently built with Arduino framework and I would like to run the code on ne new platform without changes. Would this be possible?
I am working alone on this project, so I won’t be able to Port all the libraries to the new RTOS.

You are mentioning zypher. I have not used it yet, but I neared of it. What is about CubeIDE? Is this a framework or just an IDE? I would like to stick with pio. What is with Mbed os? I’ve read recently that it’s not very good?

I’ve done first tests with ESP32 and at least it’s possible to combine stuff (threads) from freeRTOS and still using the Arduino framework.
Would something similar possible with STM32?

I am going to build a custom board based on the new controller. Are there advantages or disadvantages when using STM32 or esp32?

Thanks for your input!

If you need WiFi or BT, I would consider ESP32 over STM32. Both have low cost hardware debugger which I consider a must for myself. Also, sticking with platformio is a good approach, and is what I am doing.

Platformio docs tell you what frameworks it supports for each architecture. If you switch to use an RTOS, you need to make sure to have thread safe code, e.g. protecting common resources with synchronization elements. This is something that you don’t need to worry about in a loop() style programming.

I recently completed a similar project, custom ESP32 board, platformio, and some usage of FreeRTOS. In my case, I picked the espidf framework over Arduino, with is the standard ESP32 SDK, without the Arduino abstractions.

Thanks for your thoughts and sharing your project.
It’s very interesting to see how you solved it. It should be a good guidance for me, as it’s similar to my project.

I do currently no use wifi/bt and it’s not absolutely needed. There are a few situations where it makes sense and would help to ease the process. I still would like to have it on board, to make the project future-proof. There are for sure, a few use cases I haven’t thought about, where I can use it.
Would you still go for ESP32 or use a STM32 and add an external wifi/bt chip to my schematics?
The downside of wifi/bt is, that the implementation is huge. Once enabled, I’ll loose 2/3 of the available memory on ESP32.

All my tests with ESP32 are based on espidf framework.
I am primarily keen on threading, as this is the biggest downside currently for me when only relying on Arduino framework.
I do not like, that it’s C based. I would prefer C++. I know it’s possible to write C++, but there were a few where I had (smaller) problems.

As I said, I would like to combine espidf with Arduino framework to keep my current code compatible.
I do not have the knowledge and resources to re-write every single library I am using to get rid of the Arduino layer.

My biggest concerns are about the graphics library.
I am currently using ILI9341_due lib, because it is supporting DMA (my current board is based on Arduino Due).
I looked into LVGL and the results are looking great. I was also able to setup a test project with a simulator, but didn’t manage to make it work with the actual hardware.
I am using displays with ILI9341 or ST7789 controller (240x320px) and I am not sure, if I need to write the driver for it. I hadn’t time yet to dig deeper into this, yet …

I wouldn’t add bt/wifi to an STM32, and would go with an ESP32 instead. The ESP32 is also better supported on platformio with threading out of the box (use the espidf framework). I am struggling now with setting a platformio STM32 project with FreeRTOS, and had to go through a bunch of workarounds.

As for LVGL, you may need to develop a driver but you can find examples on the internet. The driver is relatively simple and is primarily a function that renders a given rectangular area of the screen with pixels that are provided in a buffer. It doesn’t need to deal with primitives such as draw line or draw circle.

Regarding Arduino code, I saw this but didn’t play with it yet. STM32duino FreeRTOS - Arduino Reference . Potentially you can have STM32 Arduino that also have threading. Not sure how good it is.

1 Like

One thing that I learned after two weeks of struggling. If you want to use STM32 with FreeRTOS and files generated from a Cube IDE .ioc file, the way to go is baremetal (no fraemwork) rather than framework=stm32cube.

Discussion here

Example here

I am using a small shell script to update the platformio project with new files generated in the Cube IDE. There are some tweaks to do such as -I for the include files and replacing main.c and freertos.c with your own main files but much less frustration, so far, than with framework = stm32cube.

This is the script I use to update the baremetal platformio project with changes in the files generated by the cube ide project.

#!/bin/bash -x

dst="../platformio-baremetal"

rm -r $dst/lib/Core
cp -r Core $dst/lib/Core

# Patch Core related stuff
mv  $dst/lib/Core/Src/freertos.c  $dst/lib/Core/Src/freertos.c.ignored
mv  $dst/lib/Core/Src/main.c  $dst/lib/Core/Src/main.c.ignored

rm -rf $dst/src/startup
mv $dst/lib/Core/Startup $dst/src/startup

rm -r $dst/lib/Drivers
cp -r Drivers $dst/lib/Drivers

rm -r $dst/lib/Middlewares
cp -r Middlewares $dst/lib/Middlewares

rm -r $dst/lib/USB_DEVICE
cp -r USB_DEVICE $dst/lib/USB_DEVICE

cp STM32H750VBTX_FLASH.ld  $dst/STM32H750VBTX_FLASH.ld

And my platformio.ini looks like this

[env:weact_mini_h750vbtx]
platform = ststm32
board = weact_mini_h750vbtx
build_type = debug
debug_tool = stlink
upload_protocol = stlink
debug_build_flags = -O0 -ggdb3 -g3
board_build.ldscript = STM32H750VBTX_FLASH.ld
lib_archive = no
lib_deps = 
  Core
  Drivers
  Middlewares
  USB_DEVICE
build_flags =
  -mfpu=fpv4-sp-d16 
  -mfloat-abi=softfp  -Wl,-Map,${BUILD_DIR}/firmware.map
  -mthumb 
  -D debug
  -D USE_HAL_DRIVER
  -Ilib/Core/Inc
  -Ilib/Core/ThreadSafe
  -Ilib/Drivers/CMSIS/Device/ST/STM32H7xx/Include
  -Ilib/Drivers/CMSIS/Include
  -Ilib/Drivers/STM32H7xx_HAL_Driver/Inc
  -Ilib/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc
  -Ilib/Middlewares/ST/STM32_USB_Device_Library/Core/Inc
  -Ilib/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS
  -Ilib/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/Include
  -Ilib/Middlewares/Third_Party/FreeRTOS/Source/include
  -Ilib/Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F
  -Ilib/USB_DEVICE/App
  -Ilib/USB_DEVICE/Target

Thanks. I think ESP32 is not a too bad choice.
I’ll try to develop a prototype … :grinning:

I really appreciate your detailed insights in your projects and your progress and thoughts.

I recommend having a hardware debugger. It makes things much simpler. For ESP32, this one works great for me Amazon.com (cost $28 about 6 months ago).

Good point! Thanks for pointing this out. It’s actually something I haven’t considered yet.
But I totally agree. I need an easy solution for debugging, especially during the initial phase of development.

For my better understanding: Is it possible to debug through USB or do I have to connect via JTAG or something similar?
I do have the Atmel ICE debugger for my current custom Arduino Due compatible board.
But It’s not very handy as I have to open the enclosure and the connection is not too stable.

Do you recommend including the debugger in my schematics or is this typically an external tool, I’ll connect when necessary?
Placing these components makes the production board only more expensive, as it is (hopefully) usually not used. Though, when problems occur, it can be helpful if it’s onboard…

Yes, it needs to be jtag, such that the debugger has full control over the MCU. I suggest including it in the design, and then you have the option to populate only a few development units though, those connectors are inexpensive. For example, if you are using JLCPCB SMD service to assemble your boards you can use this one PZ127VS-12-10-H10-A38 | XFCN | Pin Headers | JLCPCB , and the electrical are here ble_stepper_motor_analyzer/stepper_monitor.pdf at main · zapta/ble_stepper_motor_analyzer · GitHub .

I also recommend adding the standard ESP32 DTR/RTS circuit because it will simplify reflashing the boards via the USB port (not related to the jtag debugger, user in the field or when you develop without the debugger).

Thanks for your amazing guidance! It’s really helpful!
Yes indeed, I am planning to use the JLCPCB assembling service. I am also currently designing the schematics with EasyEDA due to this reason. As you might have noticed, I am no expert in electronic engineering, but it feels like a solid toolchain :wink:

I have an older STM32 development board and as far as I remember it was possible to debug through the USB connection as the debugger was on this board.
Would this be possible with ESP32, too? If I got you right, I need the JTAG connector on my board and in addition also the ESP32 Prog board for debugging, right?

I was not aware, that DTR/RTS are necessary for flashing - thanks!
My current design offers only a pin header where I can plugin the ESP32 DevKit board. In the first step, I want to bring all sensors and accessories together and see if it’s working.

Once it is running, I will try to replace the DevKit with a custom ESP32 design…
So for the current prototype flashing is not a problem, but for the next gen it will be important :slight_smile:

Though, I should add the JTAG connector for debugging, as it is not available on the DevKit afaik.