Right now, the biggest difference I see is in the programming style. An RTOS seems to become more useful as the system grows in size and complexity because it lets you organize the application into separate tasks, making the code easier to manage and maintain.
Not necessarily. Actually the opposite is true. In an embedded system most of the tasks are related. Seperating into more tasks means maintaining more relationships. This is a pitfall programmers tend to fall in.
Im not sure separations of concerns and implementation behind an interface call be called "Pit falls".
The "pit falls" are in doing it wrong.
If you want a lesson in how to "decouple" code corrected the litmus test is simple. Take every single c file in your project and write a "Unit test" for it.
If you can't you have a heavily coupled system and changing anyone part, changes all of it. If your project is small enough for that not to hurt later, great. Don't over engineer it. But when it is.... dont come crying.
Defining the interface between components formally is also, hardly a pitfall. Allowing them to grow organically without oversight is far more common in embedded in my eyes.
"Unit testing" is the search light for coupled code. The moment you try and "instantiate" your module and it tries to access an external item, like an MCU register, FAIL. Cannot be tested in isolation, can only be tested with external dependancies, so are you testing the code or the dependency?
"Process isolation" isn't really a thing in embedded though. So I would ask ... why do you want the execution separation? Thats a different thing to the code interface/component level separation.
In a "general purpose" big iron with virtual addressing splitting at the "Process" boundary and not the "Thread" boundary forces isolation, forces a clean interface and prevents sneaky "I'll just reference this other modules stuff for convenience".
In an RTOS, unless I am mistaken, there is nothing preventing TaskA from pilferring state from TaskB while nobody expected it.
The only reasons I can think of then is "cadence" and "idle states". If you have two (or more) tasks with different cadence (interrupt rate, duty cycle etc.) or you have tasks which will take considerable time and want other things to still work.
Basically RTOS is a framework for writing super loops (aka roll your own threading). Not much more.
Horizontal scaling is probably the other. Processing multiple things in parallel usually benefits from such a task orchestration framework.