July 5th, 2024

Moving to a RTOS on the RP2040

The article discusses transitioning to an RTOS on RP2040 for a hardware controller project. Initial challenges with FreeRTOS led to exploring NuttX and Zephyr, highlighting pros and cons for project utility.

Read original articleLink Icon
Moving to a RTOS on the RP2040

The article discusses the transition to a Real-Time Operating System (RTOS) on the RP2040 microcontroller for a hardware controller project. The project involves controlling PTZ cameras and a video switcher. Initially developed using the pico-sdk and FreeRTOS, the author encountered issues with debugging and hardware abstraction. They then explored Apache NuttX, which offers a Unix-like environment but faced challenges with setup and functionality. Lastly, the author tried Zephyr, which required extensive toolchain installations and had compatibility issues with the Raspberry Pi Pico board. Despite these challenges, the author appreciated Zephyr's utility setup for projects. Overall, the article highlights the author's journey in selecting an RTOS for their project, showcasing the pros and cons of each system in terms of ease of use, functionality, and compatibility with the hardware.

Link Icon 18 comments
By @DannyBee - 3 months
This author seems like they are expecting an RTOS to be the same as Arduino environment, or at least, susceptible to just hacking around and hoping it works. Most are not.

Given a lot of Arduino these days have mbed or freertos under the covers, with some way to expose it, that may have been a better route for the author's style.

Zephyr is easy to use (Clion also has good support for it), but like, you can't just choose not to install the toolchain and expect it to all work.

It also definitely supports the Pi Pico - i've used it on it before, no issues.

A simpler rundown of these RTOSen would be:

1. FreeRTOS - supported by roughly everything, but drivers and such are mostly per-SOC/device, which is a pain in the ass. The APIs are not very user friendly, but you get used to it.

To give a sense of level - if you wanted to use bluetooth with FreeRTOS, you get to find your own stack.

2. Zephyr - supports real hardware abstractions and supports most SOC. You may have to do a little board work.

If you wanted to use bluetooth with Zephyr, it has a bluetooth stack you can use, you may have to add a little support for your HCI.

3. NuttX - not great support, but very cool if you can get it working - not really highly supported by industry yet.

I never got far enough into NuttX to try bluetooth in NuttX.

There is also mbed, but we'll skip it.

In practice, people in the RTOS world will usually go with what the SOC vendor supports. So if you are using Nordic stuff, you are probably on Zephyr. If you are using NXP stuff, probably FreeRTOS, etc.

That is how they get good support.

By @bborud - 3 months
Having toolchains installed system-wide in the traditional UNIX way is painful, and dare I say it, not the smartest of approaches. If it works for you: great, but if you work on a project with multiple developers, sometimes working on multiple projects that have different targets, you will spend a lot of time trying to figure out build and configuration problems.

It also doesn't help that people keep using Python for tooling. Why would you want to insist on using a language that brings its own versioning problems and which will behave differently on each developer's computer? I've done embedded development for about a decade now (both as a hobby and professionally) and it is puzzling that people think it is okay to spend a week trying to make everyone's setup do the same thing on a project and then not see how this is a problem.

It is a problem. It is annoying. It does waste time. It is unnecessary.

Tools should be statically linked binaries. I don't care what language people use to write tools, be it Rust, Go, C, C++. I just wish people would stop prioritizing ad-hoc development and start to make robust tools that can be trusted to work the same way regardless of what's installed on your computer. Python doesn't do that. And it doesn't help that people get angry and defensive instead of taking this a bit more seriously.

That being said, things like PlatformIO are a step in the right direction. I know it is a Python project (and occasionally that turns out to be a problem, but less often that for other tools), but they have the right idea: toolchains have to be managed, SDKs have to be managed, libraries have to be managed, project configuration has to be simple, builds have to be reproducible and they have to be reproducible anywhere and anytime.

I wish more of the embedded industry would realize that it would be better to have some common efforts to structure things and not always invent their own stuff. I know a lot of people who work for some of the major MCU manufacturers and I am always disheartened when I talk to them because they tend to be very near-sighted: they are mostly busy trying to solve their own immediate problems and tend to not have a great deal of focus on developers' needs.

By @drrotmos - 3 months
Personally, I've begun switching over my RP2040 projects to Rust using Embassy. Rust did take some getting used to, but I quite like it. Not an RTOS, but it satisfies a lot of the same requirements that'd lead you to an RTOS.
By @5ADBEEF - 3 months
the pi pico is 100% supported in Zephyr. https://github.com/zephyrproject-rtos/zephyr/tree/main/board... Did the author not check the docs? https://docs.zephyrproject.org/latest/boards/raspberrypi/rpi...

Additionally, you aren't intended (for many situations) to use a single "main" Zephyr install, but to include what external modules you need in your project's west.yml. If you have a number of projects sharing the same Zephyr install that's a separate discussion but installing every possible toolchain/HAL is not the only way to do things.

By @RossBencina - 3 months
No mention of ThreadX, which is open source these days

https://github.com/eclipse-threadx/threadx/

By @GianFabien - 3 months
Great comparison of RTOS choices.

Personally I find microPython to be an easier path. async/await based cooperative multi-tasking works well for me. Latest project driving 6 stepper motors and a variety of LEDS and scanning buttons - all in what appears to be real-time to the user.

By @rkangel - 3 months
I really want to get ve Hubris a try on a proper project (https://hubris.oxide.computer/reference/).

As an architectural approach it aligns closely with what I am going for in embedded land, but in C with more pain. And is not dissimilar to what you do in Erlang/Elixir in hosted land.

Embassy looks to be a good choice in more memory constrained situations where you can't afford multiple stacks.

By @boffinAudio - 3 months
Always, always, always start your new embedded project in a Virtual Machine. NEVER MIX TOOLS ON THE SAME SYSTEM.

This has been the #1 cause of quality issues for my (commercial) projects.

If you start a project with a new chipset, with a new vendor - build a new VM, install the vendors tools (and only the vendors tools) in that VM, and do your builds from there.

Do your hacking on your own (non-VM) machine, sure. That's perfectly fine.

But ALWAYS use the VM to do your releases. And, for the love of FNORD, KEEP YOUR VM IN SYNC WITH YOUR DEV WORKSTATION.

Disclaimer: currently going through the immense pains of dealing with a firmware build that absolutely has to be fixed while the original dev is on vacation - nobody can get into their workstation, the VM prepared for the task is 6 months out of date, and the customer is wondering why they should pay for the whole team to do something that one very special programmer is the only one on the planet can do .. grr ..

By @sgt - 3 months
Can't go wrong with FreeRTOS. It's basically an industry standard at this point.
By @anymouse123456 - 3 months
I've had similar experiences to the OP.

I went ahead and rolled a simple green thread timer.

It doesn't support actual process management like a real kernel, and doesn't make any guarantees about anything, but it has gotten me further than bare metal scheduling and helped me avoid the shit show that is RTOSes.

Think JavaScript timer callbacks with an optional context struct (in C)

It has allowed me to interrogate a variety of sensors, process inbound signals, make control decisions and emit commands, all at various frequencies.

I highly recommend folks try something like this before ruining your life with these slow, abstract architectures.

By @taunus - 3 months
If you want to look into Rust RTIC https://rtic.rs/2/book/en/ has rp2040 support and is very lightweight
By @roland35 - 3 months
Zypher is indeed a pain in the neck to learn. I have lots of experience with freertos, setting up tool chains, etc, but just getting a basic project with zephyr is confusing.
By @huppeldepup - 3 months
No mention of ChibiOS, unfortunately. I checked and the port still has problems installing on flash, so runs on RAM only.

I’d also like to suggest uC/OS. It doesn’t take much more than setting a timer in asm to port that rtos but I haven’t had the time myself to try it.

By @bangaladore - 3 months
I think Eclipse ThreadX is a great option (https://github.com/eclipse-threadx/threadx)

Its might be the most used ThreadX on the market in the professional space (due to its history), but its quite frankly stupid simple to use.

It was initially developed by Express Logic, then partnered tightly with Renesas, Then sold to Microsoft, and then transferred to the Eclipse foundation for good.

They also provide NetX(duo), FileX, LevelX, UsbX and GuiX with full source and the same licensing afaik. Personally I don't care for UsbX or GuiX.

By @mordae - 3 months
Rolling your own swapcontext() is not that hard on Cortex-M0 and Pico SDK let's you override couple macros to hook into its locking code.
By @demondemidi - 3 months
Gave up on freertos because printf doesn’t work? someone didn’t have the patience to read the documentation.
By @a-dub - 3 months
hm. haven't seen camelCase hard real-time task definitions since the vxworks days!
By @snvzz - 3 months
AIUI seL4 runs on that chip.

It would likely not be a bad option.