EmbeddedRelated.com
Forums
The 2024 Embedded Online Conference

Do I need a RTOS?

Started by eeboy December 23, 2008
John,

it sounds like you have your head in the sand.

On Fri, 26 Dec 2008 10:59:46 -0000, "FreeRTOS.org" <noemail@given.com>
wrote:

>"Jonathan Kirwan" <jkirwan@easystreet.com> wrote in message >news:lqv7l41uf17qlk82d7thujcn71bsrtk9m0@4ax.com... >> On Thu, 25 Dec 2008 12:38:07 +0100, "Legato" >> <legato_summ23@mailinator.com> wrote: >> >>>However, if you need to make a state-machine to get the >>>timing to work then I'd opt for an RTOS. >> >> One might. But using the idea that a state-machine is required to get >> timing done wouldn't be a reason to force the issue. >> >> On instruments that have been running around the world and have been, >> in some incarnation or another (various products in product lines) >> doing that since around 1993, I've used state machines hooked to a >> timer interrupt to handle serial eeprom updates, synchronous >> communications with a DSP, and keyboard and display updates. No >> "RTOS" involved. > >I always advocate using the right tools for the job - sometimes that is with >an RTOS, sometimes without. I like using some of these 'automated' state >machine paradigms, when that suites the job. However, while I can cut the >grass with scissors, it would work, I would always choose to use a lawn >mower if the lawn was more than one foot square.
I found a problem in the bright line drawn by the person I responded to, regarding when an operating system is appropriate. I haven't made any judgments, though, about whether or not some specific application, one where I haven't much knowledge about, should or should not use an operating system. Here, you do exactly what I don't want to do. In fact, you start out almost declaring that I decided to use a scissors to cut a lawn, when that was hardly the case at all. But I will stop short of arguing with you, since you have no idea what processor I was using or other important aspects of the project which bounded my choices. Suffice it that I've written more than one operating system before (including a widely used, large scale time-sharing system) and at the time had that very handy compile-time configurable operating system I already mentioned -- which I assure you would have been far more appropriate to the application than FreeRTOS would have been in that circumstance. And I chose not to use it, for reasons you cannot possibly know about here.
>I often give talks where one of the subjects is when an RTOS is useful and >when not, and having multiple state machines to control fast and slow device >(especially if nested) is one indicatation that an RTOS might be the best >solution.
It really depends on a lot of other factors, though. What I didn't agree with Legato about was that "that's what RTOS's are for: to get tasks with wildly different timing requirements to work smoothly." That isn't what they are made for -- not in my mind, anyway. And it doesn't rise very high on my list of considerations why I'd choose to use one. However, you talk about "multiple state machines ... especially if nested." Then we are on to a different subject. On that point, ... it depends. One of the reasons I don't like state machines is that they can easily wind up obfuscating some otherwise rather simple concept. One usually needs global variables (or static ones, anyway) to keep track of the current state of the machine so that the next invocation can start from there. That can be simply handled, for sets of trivial states, or it can get nasty-looking. So the clarity of the code depends and, thus, the appropriateness of the tool as well. But where you have a separate stack for a thread, for example, much of that "getting back to where you were, last time" goes away and the code can be very much simpler to read and maintain. I definitely appreciate the semantics of threads and processes. Anyway, separate issues. I don't want to belabor all this. I entered this area for one original reason -- to offer the idea of delta queues to a poster, with a willingness to dig into quite specific details as needed -- and for another off-hand one where I disagreed with the statement, "that's what RTOS's are for: to get tasks with wildly different timing requirements to work smoothly." Exploring all of the various boundaries where operating systems, state machines, and a bevy of other ideas may or may not be appropriate and debating those edges from varying perspectives is a matter of a book, perhaps.. or several of them. I'm not prepared to go there, right now. For now, my contributions will be limited to delta queues and my disagreement about the way Legato chose to write "that's what RTOS's are for." I don't think that's their purpose.
>In the same talk I take a piece of LCD code that I downloaded >from the net which is implemented as a state machine - then first ask the >class to tell me how it works (nobody has got it right yet), followed by >asking how it would need changing if the LCD controller changed and worked >at twice the speed (nobody has got it right yet). Finally we convert the >state machine to a piece of sequential code that uses the services of the >RTOS. > >I have not actually done the counting, but would guess there was a lines of >code ratio of about 5 to 1, and the RTOS solution is so simple you could not >mistake how it worked because all the timing information is abstracted away. >The RTOS solution is also very maintainable - especially if you had to >maintain it when somebody else had written it. Plus the RTOS solution is >many more times efficient as it does not repeatedly call a state machine >when there is nothing to do or just to click through a timing state - plus >the RTOS solution allows messages to be written to the LCD from multiple >tasks without the application writer even having to consider it - plus the >RTOS solution allows messages to be written to the LCD from interrupts >without the application writer having to consider mutual exclusion - plus >.......... The original state machine solution did work though, but I would >guess it took ages to write and even longer to debug. > >Despite being the author of a kernel I provide it for free so I have no >vested interest in going around saying "though shalt always use an RTOS", >but in the example you give I would suggest it would have been so much >simpler - maybe not if it was the first time you had been confronted with an >RTOS, but definitely after you were familiar with the concepts and methods >used. Using an RTOS would also not prevent you from using high priority >interrupts (that are not affected by critical sections) to perform other >timing critical bits of functionality.
I don't find much disagreement with the broader aspects of your comments here. Broadly, I much prefer the clarity of threads and processes. But that's broadly speaking. I can provide specific cases that would argue well that a state machine is clearer, maintainable, and far less prone to programming mistakes. But I just don't want to get that deeply into the details right now -- it's way beyond the reach I am willing to go in the near term. So if you can't imagine such cases, then for now we'll just have to disagree.
>I often give talks where one of the subjects is when an RTOS is useful and >when not, and having multiple state machines to control fast and slow device >(especially if nested) is one indicatation that an RTOS might be the best >solution. In the same talk I take a piece of LCD code that I downloaded >from the net which is implemented as a state machine - then first ask the >class to tell me how it works (nobody has got it right yet), followed by >asking how it would need changing if the LCD controller changed and worked >at twice the speed (nobody has got it right yet). Finally we convert the >state machine to a piece of sequential code that uses the services of the >RTOS.
I think a skilled programmer can pretty much argue that green is red and that blue is pink, if they've a mind to do that. But the fact remains that there are times and places for each of a rather wide variety of tool selections. Just so you understand me, as I earlier pointed out I didn't write operating systems for my health -- I needed their benefits or else others did and I understood the reasons why. I'm not attacking the idea of operating systems, generally, nor FreeRTOS specifically. I just don't want anyone imagining that this is a true line of demarcation that always applies: "that's what RTOS's are for: to get tasks with wildly different timing requirements to work smoothly." It simply isn't the line to be drawn. So far as I am concerned, anyway. Jon
"eeboy" <jason@jasonorsborn.com> wrote in message 
news:Tc2dncCA-4QBqszUnZ2dnUVZ_gqdnZ2d@giganews.com...
>I am bringing up my first ARM project (based on LM3S1439) and am looking > for some advice. In my particular target application the processor will be > communicating with several peripherals via SPI (2) and UART, maintaining a > file system, keeping track of time and date as well as performing a lot of > GPIO manipulation. The board is also designed with a few external > communications ports so that future additions can be accommodated.
<snip>
> Should I use a full blown RTOS? If not how should I structure my > application? I've had a look at FreeRTOS but it looks to be much more than > I need and slightly intimidating. > > Any suggestions? Please feel free to speak to me like a child as I am not > extremely knowledgeable of operating systems or software architecture(I am > a EE). Also, if you can point me to or provide examples that would be > extremely helpful! Help me wrap my brain around this problem.
I would say: no, you don't need an RTOS. You need to think like the EE you are and design a synchronous state-machined system that implements your functionality. I'd recommend a so-called round-robin (or, more fancily, co-operative multitasking). Implement a tight endless loop that a) deals with necessary background tasks, such as maintaining timers, and b) monitors states - e.g. flags set by timers or interrupts, or events set by other tasks. Never pend - i.e. never wait with sleeps, but by maintaining state machines and returning to the main loop - all calls *must* return within whatever latency you care to define. (There are many possible refinements to this idea, in terms of balancing high- and low-priority tasks, loop latency, responsiveness, etc, but they're now under your direct control.) Again, think in terms of a clock and synchronous state transitions. A *huge* advantage of this approach is synchronicity - as with hardware logic design, you don't have to worry about races and mutexes, since all your active tasks can be effectively atomic.(And it becomes easy enough to measure real CPU usage.) You *do*, however, need to actively limit the runtime of each call. HTH, in haste, Steve -- http://www.fivetrees.com
"eeboy" <jason@jasonorsborn.com> wrote in message 
news:O-udnRbNLLEmEszUnZ2dnUVZ_qPinZ2d@giganews.com...
> Thank you all for your input. That's exactly what I needed. I've got a lot > to look over and take in. Protothreads looks like it may be a good option. > > I stated my generalized thoughts on a suitable scheme but was having > difficulties with the problem where I needed to engage a pin, do something > else for 500ms (exactly) then return.
If the 500ms needs to be exact, consider achieving this by hardware linkage. It's not generally a good idea to do h/w IO in interrupts, but so long as it has no side-effects (a read-modify-write needs to be atomic), it can be done. Anything done by a main loop, whether cooperative or pre-emptive, is only as exact as the lengthiest route from iteration to iteration. Steve -- http://www.fivetrees.com
In message <4953E045.935749BE@yahoo.com>, CBFalconer 
<cbfalconer@yahoo.com> writes
>Chris H wrote: >> eeboy <jason@jasonorsborn.com> writes >> >>> 2) I would envision using malloc and memcpy to implement the queue. >>> Are these appropriate (efficient enough) in the embedded world? >> >> No.... MISRA-C bans malloc > >Which is a silly attitude.
Not at all
> Often malloc functions are the only way >to provide efficient use of limited memory.
Then deviate... in writing giving reason for this specific case in your project -- \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ \/\/\/\/\ Chris Hills Staffs England /\/\/\/\/ \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
Chris H wrote:
> CBFalconer <cbfalconer@yahoo.com> writes >> Chris H wrote: >>> eeboy <jason@jasonorsborn.com> writes >>> >>>> 2) I would envision using malloc and memcpy to implement the queue. >>>> Are these appropriate (efficient enough) in the embedded world? >>> >>> No.... MISRA-C bans malloc >> >> Which is a silly attitude. > > Not at all > >> Often malloc functions are the only way to provide efficient use >> of limited memory. <there was more, but the p'graph got snipped> > > Then deviate... in writing giving reason for this specific case in > your project
If they deviate from the C standard you are not using C. That only leaves a very few possibilities, such as failure to recover large enough spaces, and the use of lazy assignment (usually switch offable). That was why I mentioned assigning uniformly sized blocks. -- Merry Christmas, Happy Hanukah, Happy New Year Joyeux Noel, Bonne Annee, Frohe Weihnachten Chuck F (cbfalconer at maineline dot net) <http://cbfalconer.home.att.net>
On Sat, 27 Dec 2008 18:50:22 -0500, CBFalconer <cbfalconer@yahoo.com>
wrote:

>Chris H wrote: >> CBFalconer <cbfalconer@yahoo.com> writes >>> Chris H wrote: >>>> eeboy <jason@jasonorsborn.com> writes >>>> >>>>> 2) I would envision using malloc and memcpy to implement the queue. >>>>> Are these appropriate (efficient enough) in the embedded world? >>>> >>>> No.... MISRA-C bans malloc >>> >>> Which is a silly attitude. >> >> Not at all >> >>> Often malloc functions are the only way to provide efficient use >>> of limited memory. <there was more, but the p'graph got snipped> >> >> Then deviate... in writing giving reason for this specific case in >> your project > >If they deviate from the C standard you are not using C. That only >leaves a very few possibilities, such as failure to recover large >enough spaces, and the use of lazy assignment (usually switch >offable). That was why I mentioned assigning uniformly sized >blocks.
I think he meant "deviate [from MISRA-C]" in that MISRA-C (and I'm guessing here) permits deviations so long as the reasons for the deviation are well-documented. I think he was responding to your statement that malloc() may be uniquely appropriate, at times, and defending MISRA-C's "ban malloc" by saying that you can have exceptions to their ban, if documented. Of course, I'm just guessing. He'll need to respond, I suppose. Just offering my interpretation for what it is worth. Jon
In message <4956BF3E.C4CEE942@yahoo.com>, CBFalconer 
<cbfalconer@yahoo.com> writes
>Chris H wrote: >> CBFalconer <cbfalconer@yahoo.com> writes >>> Chris H wrote: >>>> eeboy <jason@jasonorsborn.com> writes >>>> >>>>> 2) I would envision using malloc and memcpy to implement the queue. >>>>> Are these appropriate (efficient enough) in the embedded world? >>>> >>>> No.... MISRA-C bans malloc >>> >>> Which is a silly attitude. >> >> Not at all >> >>> Often malloc functions are the only way to provide efficient use >>> of limited memory. <there was more, but the p'graph got snipped> >> >> Then deviate... in writing giving reason for this specific case in >> your project > >If they deviate from the C standard you are not using C.
Idiot you are on C.A.E not c.l.c I meant deviate from MISRA-C -- \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ \/\/\/\/\ Chris Hills Staffs England /\/\/\/\/ \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
In message <f2gdl4pqt89rv8prndfst0hin9717k1n53@4ax.com>, Jonathan Kirwan 
<jkirwan@easystreet.com> writes
>On Sat, 27 Dec 2008 18:50:22 -0500, CBFalconer <cbfalconer@yahoo.com> >wrote: > >>Chris H wrote: >>> CBFalconer <cbfalconer@yahoo.com> writes >>>> Chris H wrote: >>>>> eeboy <jason@jasonorsborn.com> writes >>>>> >>>>>> 2) I would envision using malloc and memcpy to implement the queue. >>>>>> Are these appropriate (efficient enough) in the embedded world? >>>>> >>>>> No.... MISRA-C bans malloc >>>> >>>> Which is a silly attitude. >>> >>> Not at all >>> >>>> Often malloc functions are the only way to provide efficient use >>>> of limited memory. <there was more, but the p'graph got snipped> >>> >>> Then deviate... in writing giving reason for this specific case in >>> your project >> >>If they deviate from the C standard you are not using C. That only >>leaves a very few possibilities, such as failure to recover large >>enough spaces, and the use of lazy assignment (usually switch >>offable). That was why I mentioned assigning uniformly sized >>blocks. > >I think he meant "deviate [from MISRA-C]" in that MISRA-C (and I'm >guessing here) permits deviations so long as the reasons for the >deviation are well-documented. I think he was responding to your >statement that malloc() may be uniquely appropriate, at times, and >defending MISRA-C's "ban malloc" by saying that you can have >exceptions to their ban, if documented. > >Of course, I'm just guessing. He'll need to respond, I suppose. Just >offering my interpretation for what it is worth.
Hi Jon, Your interpretation is correct. -- \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ \/\/\/\/\ Chris Hills Staffs England /\/\/\/\/ \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
In article <Z9KdnX5h3_IkGMjUnZ2dnUVZ8rudnZ2d@pipex.net>, 
steve@NOSPAMTAfivetrees.com says...
> "eeboy" <jason@jasonorsborn.com> wrote in message > news:O-udnRbNLLEmEszUnZ2dnUVZ_qPinZ2d@giganews.com... > > Thank you all for your input. That's exactly what I needed. I've got a lot > > to look over and take in. Protothreads looks like it may be a good option. > > > > I stated my generalized thoughts on a suitable scheme but was having > > difficulties with the problem where I needed to engage a pin, do something > > else for 500ms (exactly) then return. > > If the 500ms needs to be exact, consider achieving this by hardware linkage. > It's not generally a good idea to do h/w IO in interrupts, but so long as it > has no side-effects (a read-modify-write needs to be atomic), it can be > done. >
I'm not sure I understand your last sentence. Are you saying that it is not a good idea to use interupts to service hardware such as UARTS, SPI devices or other hardware I/O devices?
> Anything done by a main loop, whether cooperative or pre-emptive, is only as > exact as the lengthiest route from iteration to iteration. > > Steve
Mark Borgerson

The 2024 Embedded Online Conference