A few bits of trivia for anyone considering NuttX:
- uses a pure software interrupt and redirects to your ISR's, so you incur additional overhead for all interrupts in your system
- ships with a homegrown c stdlib, which has several functional/security bugs (ex: vscanf will overflow if you use format specifiers other than [l]i/u), and neglects to provide gcc attributes for arg checking for the printf family functions
- build system issues $(MAKE) calls in every folder you're building, which makes it terrifically slow (especially noticeable on incremental builds)
- architecture makes it difficult to write custom drivers without building them into the kernel (eg if you want to use the kernel as a module in your project)
> - ships with a homegrown c stdlib, which has several functional/security bugs (ex: vscanf will overflow if you use format specifiers other than [l]i/u), and neglects to provide gcc attributes for arg checking for the printf family functions
Yes, it uses a custom, POSIX-compliant C library. I have never heard of any such bugs, however. All of the NuttX common code is compiler agnostic.
>- build system issues $(MAKE) calls in every folder you're building, which makes it terrifically slow (especially noticeable on incremental builds)
Re-build time is around 10 seconds or so on a lower-end to mediocre Linux box. A full build cycle (clean, reconfigure, build-from-scratch) is more like 30 seconds.
Windows-based builds are a lot longer.
>- architecture makes it difficult to write custom drivers without building them into the kernel (eg if you want to use the kernel as a module in your project)
Most RTOSen allow you to access a minimal set of kernel services from interrupt context, so that you can implement the standard top-half/bottom-half driver processing model. NuttX's managed interrupts are in this category, and almost any driver's interrupt handler needs to be as well.
Almost any RTOS on the Cortex-M profile will fully utilize the NVIC, giving you a hardware-managed preemptive FIFO scheduler even in interrupt context. NuttX's lack of this feature is a severe weakness, and a major reason to avoid using it.
Additionally, some RTOSen will provide the ability to install interrupt handlers that cannot safely access any kernel services. These are usually not capable of doing much more than provide user-defined error handling prior to taking a reboot. NuttX's raw interrupts are in this category.
> Almost any RTOS on the Cortex-M profile will fully utilize the NVIC, giving you a hardware-managed preemptive FIFO scheduler even in interrupt context. NuttX's lack of this feature is a severe weakness, and a major reason to avoid using it.
I think this is a miconception about how RTOS's can work. Certainly in a bare-metal environment (or with a minimum RTOS), prioritized interrrupt-level processing is critical. But with RTOS's like NuttX, interrupts should be very brief: You should enter the handler, perform mimimal housekeeping, and signal a prioritized thread to perform the interrupt-related operations.
This is not a oversight in the design, it is intentional replacement of prioritized interrupt handling processing with priorotized multi-tasking processing.
The NuttX interrupt handling is designed so that the context switch after signaling the prioritized thread is ZERO. The return from interrupt vectors directly in the prioritized task (assuming it is the highest priority). This is all intentional design and is very efficent in these regards.
There is no one-size, fits all RTOS. You find that some are too minimal and primitive to meet your needs (I am thinking FreeRTOS, ChibiOS, Zephyr, ...) and some may be heavier weight than is necessary for your purposes (perhaps NuttX, nucleus, RTEMS, ...) or even heavier (VxWorks, QNX, Integrity, and on up to Linux). If you want the features of one class of RTOS, then you will find the others flawed in various ways, whichever RTOS is that one that meets your needs. It is a kind of Goldilocks effect.
Please stop using indentation for quotes. It makes things impossible to read on mobile, and in this case even on desktop I had to side-scroll quite a bit to read everything.
It is a weird quirk of the HN team refusing to make it better even though it takes a few CSS tweaks. It's just one of those internet mysteries at this point.
I have used it in a few shipped products. FreeRTOS is fine as a kernel, but a the interfaces for networking or devices always felt just smashed on top of it with no clean interfaces. This also made moving between hardware revisions much more difficult. NuttX forces abstraction layers which sometimes makes it a pain to do something simple, but in the long run prevents you from shooting yourself in the foot.
Also they are having their first conference this year.
There are many products in the market running NuttX: many Sony audio recorders and bluetooth headsets; all drones/quadricopters powered by PX4 are running NuttX because PX4 is based on NuttX; Xiaomi/Pinecone are using NuttX on their products and doing great contributions to NuttX mainline; Haltian ThingSee was the first commercial IoT device powered by NuttX; Daruma DR-800 was the first thermal printer powered by NuttX; many OptoFidelity products are powered by NuttX, so if you have a good NuttX skills you can apply for this job: https://rekrytointi.com/en/vacancies/optofidelity/embedded-s... Our community is growing, even without a big company like Amazon (FreeRTOS) or Intel (Zephyr) paying our bills. It's growing because because this is a great and powerful RTOS.
I personally only used FreeRTOS but NuttX always looks cool to me. There are few open-source RTOS for microcontrollers that supports the wide range of POSIX and VFS.
A notable use case is PX4 Drone Autopilot [1], one of the most successful open source drone firmware project.
ArduPilot has switched from NuttX to ChibiOS. See the video for more information [1]. If you don't require POSIX compatibility, it's really the way to go. The kernel is very fast, and the HAL is much better compared to the typical vendor peripheral libraries. Definitely take a look at it if you've used FreeRTOS in the past. The community is excellent too with high SNR content [2], and the main developer is very responsive.
We use it at my company for several products. There is something magical about running a lightweight OS on a Cortex-M4F or Cortex-M7. It is how I imagine the early Linux days.
You get to write device drivers and dig into the OS internals. There is even a port of the uIP TCP/IP stack that can be used with development boards such as the Nucleo-144.
How's your experience with writing device drivers for NuttX? Is it easy to attach manufacture's device libraries? The biggest reason that I stick to FreeRTOS is the fear of writing device drivers from scratch for a big RTOS like NuttX.
I did some contributions to RIOT-OS [1]. Honestly it was nightmare to me because they have strict policies not allowing manufacturer drivers so I should write peripheral registers directly, which leads to a lot of bugs that is hard to debug.
I'm also a FreeRTOS user who periodically peers over the fence at NuttX, but similar fears prevent me from making the jump.
In particular, I get really nervous about scenarios where multiple low level peripherals needs to cooperate to get something to happen— thinking about something like having a DMA drive a timer to piano-play oddball serial protocols like the WS2812 one. That's enough of a nightmare in bare metal where you have total control over all the registers; I have trouble imagining an OS abstraction layer which wouldn't make it considerably worse.
Were these "strict policies" licensing issues? Or coding standard issues? IMO these issues are orthogonal to ease of integration.
Writing a simple driver for say an I2C sensor is quite doable.
However, getting a driver into mainline requires conformity both in terms of licensing and in terms of coding standards for the whole library, including 3rd party code.
I contributed to port a new microcontroller, which includes writing device (peripheral) drivers.
It was pretty much about their coding standards. I had that experience because I was contributing for mainline branch. They think avoiding abstracted manufacturer peripheral libraries (like STM32 HAL) is the best way to keep the binary small. It is pretty much appose to what Zephyr OS is doing.
I think peripheral libraries are adopting BSD license these days so the license shouldn't be an issue these days.
NuttX also has strict licensing and coding standard enforcement. Such things are a necessary component of QA and I would think that all serious RTOS's have similar standards.
I recall taking a look at NuttX when I was shopping for an RTOS for a project a while back. Ended up choosing Zephyr (https://www.zephyrproject.org/) but I'm curious if anyone here has experience with both and can contrast them a bit.
That’s the thing, hard to have experience with multiples. People generally stick to learning one or two. I know RTX and FreeRTOS differences, but I know without a doubt I’ll try NuttX.
I starting looking at RTOSes when you were lucky to have 3 or 4 options anywhere - and it wasn’t that long ago!
Now... with Amazon owning FreeRTOS... Intel and Nordic and Others going heavy in zephyr for multicore... professional but niche options like RTX, Segger’s OS, and a hundred others... and if you chip has a MPU/MMU someone is trying to get Linux on it (whether it makes sense or not!)...
I think the market is getting pretty crowded. Personally the viable options right now unless you need something large like VxWorks for Java runtime, I think it’s a choice between Amazon FreeRTOS and Zephyr.
I'm curious too. I'm currently on a project using Zephyr and while it's refreshing to use a lightweight system, there's still a lot here that's not done (e.g. filesystems). I'm kind of worried it's not getting the attention and support that was promoted for it.
It's quite easy to set up and writing drivers for it isn't really so much of a pain. I don't know if one should state it as a pain point or a good point but they do use CMake for the build system. So it's reasonably quick at least they are using a newer version of CMake than most projects I've had the joy of testing out.
Their APIs are quite linux/posix inspired in my opinion but with their own zephyr flavor on top. But I would say NuttX is probably a more mature project and Zephyr has been reworked quite heavily lately so a lot has changed but at least they'll have an LTS release soon.
The BBC Microbit supports a NXP/Freescale KL26Z. That chip is supported by NuttX so the answer would be yes, with some additional board level support.
The NXP/Freescale KL26 has very limited resources, however. I would not recommend using a higher end RTOS with very low end, severely memory constrained MCUs.
Cool. First time I've read about real-time operating systems. A pseudo filesystem that resides in RAM is very interesting. I like how they've strived for "greater scalability from the very tiny platform to the moderate platform".
RTOS are in everything! They make a ton of sense if you have a lot of resources to manage or calls to external services that may block for some time, like a modem connection. Lots of IOT products have RTOS's running under the hood, where running a kernel even as stripped back as Linux can be is too expensive computationally. And with less kernel/OS overhead, a true hard real time system can be implemented with a pretty strong guarantee of safety (not crypto safety, operational safety). There's a reason Amazon bought FreeRTOS a while back.
Professionally, I've used FreeRTOS, ThreadX, and NuttX. I'm neutral on both FreeRTOS and ThreadX, but had a really tough time with NuttX.
On a surface level, NuttX seems nice. Driver abstraction, POSIX compliant (mostly), lots of platforms/systems already integrated and working in their build system, lightweight (?), and includes some nice features out of the box like a file system. It can be nice for small projects and with people who are familiar with writing code for a Linux based project or who love to learn the internals of the system. This is rarely the case.
I had two big issues with NuttX. The first was how huge it is from the get-go. There are 10-50 files with the same name (for all the platforms) and a massive amount of build system logic, which makes discoverability and knowing where to make fixes difficult. Most companies only need 1-2 platforms, and the extra 48 laying around feels like unnecessary bloat, but deleting them feels like a sin.
My second, but probably larger, issue with NuttX was around trying to develop unit tests for the 90% of the code we added on top of it in the services layer.
NuttX is a POSIX compliant operating system, and it likes to use the same naming convention of many of the functions and files you'd find in your standard UNIX/Linux system. When you try to write a unit test for your embedded code to run on your x86 development machine, as soon as a file you are testing touches a standard header file, it's really difficult to wrangle things. You have to provide a ton of override headers (eek), stubs, fakes, and even then, as soon as someone includes a header somewhere in the include tree, it'll break that unit test that was particularly well crafted so that it would run on a Mac. If you want to run that test on a Linux machine, it would require more IFDEF's and more time. The rationale for Linux not having unit tests is that they have a massive community of nightly alpha testers to surface and fix issues. That is not a good rationale for a firmware RTOS because a simple service layer logic bug can result in a bricked device (or thousands and thousands).
There's something special about reporting a bug to Express Logic about a bug in ThreadX or (and in my case) FileX and being able to provide a simple 20 line unit test which compiles on any system without any special hackery that exposes the bug. When we tried to do this with NuttX for the various bugs found in the SmartFS module, it was actually really hard to report/reproduce these bugs since there wasn't a simple way to "package" up the environment. The "easiest" solution was to package the entire OS, a FUSE port of SmartFS, and some of our code on top, which would run in simulator mode on our machine which then could exposed the bug.
FreeRTOS and ThreadX have their issues as well, like blurred lines between upper and lower layers and lack of training wheels from the satrt, but the projects with these OS's could more easily build a modern firmware environment with unit tests, faster build times, modern build system, and crafting a full OS that worked better to solve the problems at hand.
> NuttX is a POSIX compliant operating system, and it likes to use the same naming convention of many of the functions and files you'd find in your standard UNIX/Linux system. When you try to write a unit test for your embedded code to run on your x86 development machine, as soon as a file you are testing touches a standard header file, it's really difficult to wrangle things. ...
I use a trick to do that based on the objcopy utility with the --redefine option. This is a not complicated, but still mind-bending at times.
Hard real-time without formal proofs is not only possible: it's the norm for almost all hard, real-time systems out there. It's mostly about careful coding and time analysis. Recent ones have had stronger isolation with formal verification of a few. It's not necessary to get them working most of the time, though.
Matter of fact, regulators for safety-critical fields are just starting to accept formal verification as evidence. CompCert is only tool I know of that's qualified to just one standard. If in those fields, using formal verification instead of whatever evaluators are used to can get something rejected. It can aid the development or be supplementary evidence at best.
Ultimately, an RTOS can only provide you with the tools to create a hard real-time system. The RTOS cannot guarantee that your application can meet any deadlines. That requires the proper use of those tools by the application.
If you improperly prioritize tasks or use semaphore locks improperly or keep interrupts disabled too long, then your application will not be real-time.
NOTE: NuttX does provide tools to measure interrupt latencies, response times, and critical section times. Those are helps in creating a real-time system.
So, it is not a meaningful to ask if the RTOS has been certified in some way to always meet deadlines. You should ask rather, does the OS provide the tools that you need and does your overall application meets its deadlines.
>So, it is not a meaningful to ask if the RTOS has been certified in some way to always meet deadlines.
It is meaningful. If the system doesn't offer these guarantees, no matter how good you are and how much effort you put into what's within your scope to implement, you won't be able to offer any guarantees.
This is ok if you can afford to fail. Just don't use it e.g. where human lives would be put at risk.
"Naming things" is jokingly referred to as the hardest part of computer science.
I remember a TON of articles written about Go, and how the name would impact search ratings, etc - and about how a modern language could never be called "C" because it wasn't "Googleable".
Naming things is definitely a "thing" we all talk about, constantly.
I was going to post how I can't wait to NuttX all over my embedded devices if no one had commented on this yet. Consequences to my fake internet points be damned.