Skip to main content
Graduate II
June 3, 2024
Solved

Is it really necessary a RTOS?

  • June 3, 2024
  • 9 replies
  • 10509 views

Hi all,

I write to you because I would like to understand if it is really necessary to use an RTOS. I always develop projects with different ST processors (F4 and F7) without using RTOS. In those projects the F4/F7 processors communicate with many hardware components using SPI, I2C, RS232, GPIO and PWM. Now I need to increase the communication speed on the RS232, because I need do send few mega bytes of data every second and for that reason I need to integrate the USB with Full Speed or High Speed. Then in another new project I have to handle also a small OLED display. For all these reasons I'm thinking about the possibility to use Azure RTOS that seems well integrated with CubeMX, but I do not know which benefits I could obtain and if I could have some side effects both from performance point of view and also from developing time point of view.

In this situation is it really necessary a RTOS?

Which advantages and disadvantages could I have using a RTOS? 

Let me know!

Thank you very much for the support.

    This topic has been closed for replies.
    Best answer by Andrei Chichak

    The rules of thumb that I (and other people in the embedded community) use is, if you have some sort of communications protocol going, use an RTOS. If you're doing graphics, use an RTOS.

    Once you get a bunch of experience, you'll think "this customer really has no idea of the scope of this project and it's going to balloon in scope really soon now", use an RTOS.

    But you could also not use an RTOS, add a feature here, another device there, rebalance the timing due to coupling that wasn't intended, decide that you need just a little bit of a kind of a scheduler looking thing, and suddenly you've written a feature poor RTOS and you say "I should have used an RTOS".

    I tend to use an RTOS unless I can see that the project is going to be well bounded, small, and heavily constrained.

    The amount of effort that goes into writing code goes exponential with complexity. So if you can break up your code into multiple simple cooperating tasks, you avoid complexity and avoid having your system have exponential effort growth. I've done this by using multiple processors, each running small simple programs. But you get the same effect from using an RTOS. Each task/thread/process is simple, well defined, and small, avoiding ballooning complexity.

    Recently I read an article about the software architectures that actually work for multi-processor, high scalability, high performance systems. It pretty much came down to small processes and message passing. Lots and lots of message passing. 

    So, you can get experience in non-embedded best practices and avoid driving yourself crazy by using RTOS'

    9 replies

    Graduate II
    June 3, 2024

    Using RTOS is a matter of preference, not necessity.
    You can manage multiple jobs without using RTOS using interrupts etc.
    The advantage of RTOS is that it allows you to develop the application in smaller parts. I think it's a trade-off worth spending some processor power and RAM on.
    There are a lot of new concepts to learn in RTOS, such as semaphore, mutex etc. Once learned you will tend to use it on very simple projects as well.

    Graduate II
    June 3, 2024

    Hi @Muhammed Güler ,

    thank you very much for the answer.

    What do you mean that RTOS allows to develop the application in smaller parts?

    In case of use of a GUI application on a small LCD, does RTOS became a must?

    Regarding Azure RTOS or Free RTOS, is there a good guide, or video, or turorial that explain step by step how to create a project?

    Let me know!

    thank you very much for the support!

    Super User
    June 3, 2024

    @ennioaloisini wrote:

    What do you mean that RTOS allows to develop the application in smaller parts?


    One of the key features of an RTOS is to isolate the various parts of the application into separate Tasks.

    This makes it easier to focus on just the issues within a Task - rather than having to juggle all the functionality of the whole app at once.

    In other words, it makes your code more modular; it reduces coupling between different parts of your code:

    https://en.wikipedia.org/wiki/Coupling_(computer_programming)

    and, hopefully, allows you to increase cohesion within your Tasks:

    https://en.wikipedia.org/wiki/Cohesion_(computer_science) 

    Graduate II
    June 3, 2024

    No, an RTOS is not needed.
    You can achieve the same thing with a polling loop + interrupts + DMA. Poll for events in a main loop and handle them there. Handle high priority events in an interrupt (to prevent RX fifo from filling up) and use the DMA to reduce number of interrupts and CPU load.
    However this often requires you to write Finite State Machines since no "process" is allowed to be blocking too long.
    Sometimes that requires you to rewrite third party code or library code.
    Using an RTOS basically converts every single function into a statemachine since every thread can be interrupted at any point and return where it left off. So an RTOS can be convenient.
    An RTOS does add overhead in time since task switching takes time and processing tick event takes time too. Furthermore an RTOS needs a lot more memory since every thread has its own stack. This also increases the risks of a stackoverflow. Even a simple printf can consume a lot of memory and lead to a stack overflow.
    I have used FreeRTOS and I have done many projects with just a loop + interrupts + DMA. Using a loop is the best in most cases in my opinion, but it may take more time in planning things.

    In either case I recommend you draw timing diagrams on a piece of paper of all the processes. And set some GPIO-pins at certain events so you can see the actual timing with a logic analyzer and compare it with your design.

    Graduate II
    June 3, 2024

    Hi @unsigned_char_array 

    thank you very much for the feedback.

    In one project I just need to change the RS232 with USB and maybe it could be more conveient to do not use an RTOS, but in another one I will have to handle a small OLED with a TouchGFX application and in that case I think that it could be better to use an RTOS. Is it correct?

    Let me know!

    Thank you very much for the support.

    Graduate II
    June 3, 2024

    @ennioaloisini wrote:

    Hi @unsigned_char_array 

    thank you very much for the feedback.

    In one project I just need to change the RS232 with USB and maybe it could be more conveient to do not use an RTOS, but in another one I will have to handle a small OLED with a TouchGFX application and in that case I think that it could be better to use an RTOS. Is it correct?

    Let me know!

    Thank you very much for the support.


    In your case I would recommend an RTOS such as FreeRTOS. It may not be needed, but it makes it easier. I currently have a large project with TouchGFX and USB and use it without an RTOS, but we have calculated and measured the CPU load and timing. We also rewrote the USB library to remove busy waiting and optimize it more. At my current job part of our coding standard is to avoid an RTOS unless it is really needed. This way we avoid things like stack overflow and since we run most things in one loop it reduces most problems with concurrency and synchronization. But RTOS is also easy (just make stack size large enough) and it's ok to be a bit lazy.
    Regardless I still recommend you at least measure the CPU load by toggling some IO pins in certain parts of the code. This helps you find bottlenecks early on in development instead of surprises when you want to deliver the project.

    Super User
    June 3, 2024

    @ennioaloisini wrote:

    Hi all,

    I write to you because I would like to understand if it is really necessary to use an RTOS. I always develop projects with different ST processors (F4 and F7) without using RTOS.


    Surely, you've answered your own question there - you yourself have demonstrated in your own projects that it is not necessary to use an RTOS!

    The benefits of an RTOS come as projects get more complex, so it gets more difficult to manually manage all the different parts - especially when adding more complex peripherals like USB and graphic displays.

     

    Graduate II
    June 3, 2024

    Hi @Andrew Neil ,

    thank you very much for the answer.

    Now I have to add USB in one application and in another one both USB and graphic display. Do you think that it is better to switch to an RTOS?

    I saw that ST pushes a lot Azure RTOS. It is easy to use and robust / safe like SafeRTOS?

    Let me know!

    Thank you very much for the support!

    Super User
    June 3, 2024

    @ennioaloisini wrote:

    Now I have to add USB in one application and in another one both USB and graphic display. Do you think that it is better to switch to an RTOS?


    Can you clearly see how you'd manage the full app (both USB and graphics) without an RTOS ?

    If you feel that's getting "too complicated", then it's probably time to switch.

    If you are going to switch, it's probably a good idea to just switch your existing project first, with no other changes - don't complicate the issue with knew & unknown code!

    Then I would suggest that you just add the USB.

    Finally, add the graphics to the USB.

    It's always good to move in small steps - keep the number of unknowns to a minimum!

     

    Graduate II
    June 3, 2024

    The UART on most of the STM32 can support rates of a few Mbps, usable for things like HSPA/4G modems.

    RTOS aren't needed.

    USB expects some amount of concurrent operation, pumping the foreground tasks, see while() loops often used in main(). There are other ways to pump operation, and most time critical stuff is handled in interrupts, but other data buffer management typically needs to occur under a secondary "task" or periodic processing.

    Done many things here processing data, running a radio, multiple UART, and SSD1309 OLED, without any RTOS

    Graduate II
    June 3, 2024

    The rules of thumb that I (and other people in the embedded community) use is, if you have some sort of communications protocol going, use an RTOS. If you're doing graphics, use an RTOS.

    Once you get a bunch of experience, you'll think "this customer really has no idea of the scope of this project and it's going to balloon in scope really soon now", use an RTOS.

    But you could also not use an RTOS, add a feature here, another device there, rebalance the timing due to coupling that wasn't intended, decide that you need just a little bit of a kind of a scheduler looking thing, and suddenly you've written a feature poor RTOS and you say "I should have used an RTOS".

    I tend to use an RTOS unless I can see that the project is going to be well bounded, small, and heavily constrained.

    The amount of effort that goes into writing code goes exponential with complexity. So if you can break up your code into multiple simple cooperating tasks, you avoid complexity and avoid having your system have exponential effort growth. I've done this by using multiple processors, each running small simple programs. But you get the same effect from using an RTOS. Each task/thread/process is simple, well defined, and small, avoiding ballooning complexity.

    Recently I read an article about the software architectures that actually work for multi-processor, high scalability, high performance systems. It pretty much came down to small processes and message passing. Lots and lots of message passing. 

    So, you can get experience in non-embedded best practices and avoid driving yourself crazy by using RTOS'

    Graduate II
    June 3, 2024

    People who can only think linearly, and have a hard time thinking concurrently, should probably use an RTOS.

    It does off-load a lot of complexity, but it does bring with it a different set of issues.

    It hides Time from the problem, but it won't stop you from hitting bandwidth limitations if you always take longer to process the data than the rate it arrives.

    Graduate II
    June 3, 2024

    So what you're saying is "it's not for me, your milage may vary"?

    (or is your intent to insult?)

    Graduate II
    June 4, 2024

    Question concerning the OS supported by ST:

    Do they come with the hardware / peripheral drivers?

    If yes, do they use the HAL libraries "underneath" ?

    If yes, then for me this would be the reason to NOT use an OS.

    Graduate II
    June 4, 2024

    @LCE wrote:

    Question concerning the OS supported by ST:

    Do they come with the hardware / peripheral drivers?

    If yes, do they use the HAL libraries "underneath" ?

    If yes, then for me this would be the reason to NOT use an OS.



    FreeRTOS is just a software threading library that compiles with your code. It manages switching stacks when switching between threads and it also handles timers and communication/synchronization between threads. The only hardware it uses is the systick timer. You can use the HAL functions in your threads just like you would in a loop, just avoid accessing the same peripheral from different threads.

    Graduate II
    June 4, 2024

    Okay, my question was not accurate enough, I actually meant Azure.

    Some threads I have seen let me think it has some hardware / peripheral drivers integrated?

    Graduate II
    June 4, 2024

    @Andrew Neil yeah, sorry for "thread-jacking".

    I was just curious - I won't use any OS anytime soon.

    But concerning the original question, the underlying "hardware drivers" if any, would surely help my decision if OS or not.

    Graduate II
    June 10, 2024

    Hi all,

    thank you very much for the valuable advices.

    I am writing to you because I would like to understand how I can convert an existing program without Azure RTOS ThreadX with a program in which I use Azure RTOS ThreadX.
    For example I would like to add Azure RTOS ThreadX on an existing program that reads a series of values ​​with GPIO, ADC, or by communicating with external components with SPI and I2C and sets digital signals with PWM and GPIO. It also communicates via the serial port with another board.
    What should I do with CubeMX?
    Do I take the existing project and add ThreadX in the "Middleware" section and change the timebase source for "SYS" from SysTick to TIM6 in the "System Core" section?
    Do I need to make further changes in CubeMX?
    At the code level I will have to use Threads, but how can I structure the program?
    Currently the commands arrive on the serial port through the interrupt and I insert them into the relevant buffer which is read by a function present in the while(1) of the main. The readings of some digital and analog signals are made every few milliseconds and to do this I use interrupts. I would like to understand how I can structure the program. How can I organize at file level, today almost all the code is in the main.c file and I would like to understand with what logic I create the threads and assign them to the various activities (GPI readings, ADC readings, reading from external components with SPI and I2C, management of the serial buffer and related responses, writes to memory, etc.).

    Let me know what rules I should follow to structure the code well.

    Thank you very much for the support.

    Super User
    June 10, 2024

    That's a new question - and quite a big one.

    Please mark a solution for this thread, and then start a new thread with your new question.

    Give a link here to the new thread, so that people can find it.

    (you could also link back to this thread from the new one, if it helps for reference)

     

    Maybe also start by reviewing the introductory Azure RTOS links in this earlier post:

    https://community.st.com/t5/stm32-mcus-embedded-software/is-it-really-necessary-a-rtos/m-p/682342/highlight/true#M48348

     

    Technical Moderator
    June 10, 2024