EmbeddedRelated.com
Forums
The 2024 Embedded Online Conference

Dumb RTOS Question

Started by Unknown August 24, 2006
Starting on my first RTOS project and can't quite see the logic to the
interprocess communications. The Zilog RTOS offers message queues, but
if the queue is empty the reading process is suspended until something
shows up in the queue. Well sorry, that isn't good because my process
has multiple things it needs to monitor periodically. It can't get hung
on just one message queue. I thought a message queue would work or have
an option to work like a ring buffer but that does not seem to be the
case. My concept is to have this process check several "queues" and
then suspend for a safe amount of time before looping back to check
them again.  Any sage advice appreciated. Thanks.


Dave

galt_57@hotmail.com wrote:
> Starting on my first RTOS project and can't quite see the logic to the > interprocess communications. The Zilog RTOS offers message queues, but > if the queue is empty the reading process is suspended until something > shows up in the queue. Well sorry, that isn't good because my process > has multiple things it needs to monitor periodically. It can't get hung > on just one message queue. I thought a message queue would work or have > an option to work like a ring buffer but that does not seem to be the > case. My concept is to have this process check several "queues" and > then suspend for a safe amount of time before looping back to check > them again. Any sage advice appreciated. Thanks. > > > Dave >
I'd think there'd be a way to sleep on lots of queues at once, or use interrupts. This is very common stuff. In unix world there is select() and poll(). Keep studying the manual for the OS, it's got to have this stuff. -Dave -- David Ashley http://www.xdr.com/dash Embedded linux, device drivers, system architecture
On Thu, 24 Aug 2006 15:20:35 -0700, galt_57 wrote:

> Starting on my first RTOS project and can't quite see the logic to the > interprocess communications. The Zilog RTOS offers message queues, but > if the queue is empty the reading process is suspended until something > shows up in the queue. Well sorry, that isn't good because my process > has multiple things it needs to monitor periodically. It can't get hung > on just one message queue. I thought a message queue would work or have > an option to work like a ring buffer but that does not seem to be the > case. My concept is to have this process check several "queues" and > then suspend for a safe amount of time before looping back to check them > again. Any sage advice appreciated. Thanks.
The function RZKReceiveFromQueue() includes a wait time parameter. Also, from the ZiLOG Real-Time Kernel v2.0.0 Reference Manual, page 15: "You can choose not to block on message queues to receive or send message queue messages. When this option is chosen, a TIMEOUT error occurs if the message queue is empty while receiving, or full while sending messages." And there is also the RZKPeekMessageQueue() function which might do for you. If you were to block on each queue for one tick, wouldn't that be safe since you say "suspend for a safe amount of time before looping back to check them again"? ~Dave~
galt_57@hotmail.com wrote:

> Starting on my first RTOS project and can't quite see the logic to the > interprocess communications. The Zilog RTOS offers message queues, but > if the queue is empty the reading process is suspended until something > shows up in the queue. Well sorry, that isn't good because my process > has multiple things it needs to monitor periodically. It can't get hung > on just one message queue. I thought a message queue would work or have > an option to work like a ring buffer but that does not seem to be the > case. My concept is to have this process check several "queues" and > then suspend for a safe amount of time before looping back to check > them again. Any sage advice appreciated. Thanks. > > > Dave >
Queues are there for processes that only have reason to run if there's something in the queue to be processed. If you just want a FIFO but have no plans to block on it then don't use the OS queue -- the OS queue adds significant overhead for just the behavior that you're decrying. I would use the word "monitoring" if I'm only interested in the current value of something -- if this is the case then don't use a queue at all -- just stuff your values (atomically, please) into registers, wake up periodically, and read them. On the other hand, if you have one RTOS task that's performing multiple 'real' tasks -- break it up, and do it now! One of the biggest software disasters I ever had the misfortune to work on featured a task that controlled two motors, with a single queue that sent messages about target positions. The task wouldn't service the queue until both motors were still, so you could pump messages in way faster than the task would take them off. A user could sit down in front of the system and flip a switch for a while until the queue overflowed. Once that happened the whole messaging system for the entire application got bent*, about half of the processes went into snits and stopped talking, and the thing would limp along until someone took pity on it and cycled power. Had the task just woken up periodically and monitored target values for the motors (or -- gasp -- had there been _two tasks_) none of that would have happened. -- Tim Wescott Wescott Design Services http://www.wescottdesign.com Posting from Google? See http://cfaj.freeshell.org/google/ "Applied Control Theory for Embedded Systems" came out in April. See details at http://www.wescottdesign.com/actfes/actfes.html
On 24 Aug 2006 15:20:35 -0700, galt_57@hotmail.com wrote in
comp.arch.embedded:

> Starting on my first RTOS project and can't quite see the logic to the > interprocess communications. The Zilog RTOS offers message queues, but > if the queue is empty the reading process is suspended until something > shows up in the queue. Well sorry, that isn't good because my process > has multiple things it needs to monitor periodically. It can't get hung > on just one message queue. I thought a message queue would work or have > an option to work like a ring buffer but that does not seem to be the > case. My concept is to have this process check several "queues" and > then suspend for a safe amount of time before looping back to check > them again. Any sage advice appreciated. Thanks. > > > Dave
Why do you want to implement multiple message queues? Why not have all messages for a particular task go into the same queue? That's a very common implementation. The whole point of message queues in an RTOS is that if a task has no messages to process, it should do nothing at all, and take no time doing nothing. -- Jack Klein Home: http://JK-Technology.Com FAQs for comp.lang.c http://c-faq.com/ comp.lang.c++ http://www.parashift.com/c++-faq-lite/ alt.comp.lang.learn.c-c++ http://www.contrib.andrew.cmu.edu/~ajo/docs/FAQ-acllc.html
Dave wrote:
> galt_57 wrote: > > > Starting on my first RTOS project and can't quite see the logic to the > > interprocess communications. The Zilog RTOS offers message queues, but > > if the queue is empty the reading process is suspended until something > > shows up in the queue. Well sorry, that isn't good because my process > > has multiple things it needs to monitor periodically. It can't get hung > > on just one message queue. I thought a message queue would work or have > > an option to work like a ring buffer but that does not seem to be the > > case. My concept is to have this process check several "queues" and > > then suspend for a safe amount of time before looping back to check them > > again. Any sage advice appreciated. Thanks. > > The function RZKReceiveFromQueue() includes a wait time parameter. > > Also, from the ZiLOG Real-Time Kernel v2.0.0 Reference Manual, page 15: > > "You can choose not to block on message queues to receive or send message > queue messages. When this option is chosen, a TIMEOUT error occurs if the > message queue is empty while receiving, or full while sending messages." > > And there is also the RZKPeekMessageQueue() function which might do for > you. > > If you were to block on each queue for one tick, wouldn't that be safe > since you say "suspend for a safe amount of time before looping back to > check them again"?
That is true. You have a good point. If I want to suspend for a period of time then I ought to be able to use the timeout on each queue set to half of that period. I just have not figured out this kooky RTOS stuff. The peek command copies the entire message out of the queue, which seems rather pointless. I just can't see the logic of not providing a non-blocking way to determine if there are one or more messages in the queue. I mean what is the point of that? Ring buffers worked fine for talking to ISR's. Why aren't they good enough for an RTOS?
Tim Wescott wrote:
> galt_57@hotmail.com wrote: > > > Starting on my first RTOS project and can't quite see the logic to the > > interprocess communications. The Zilog RTOS offers message queues, but > > if the queue is empty the reading process is suspended until something > > shows up in the queue. Well sorry, that isn't good because my process > > has multiple things it needs to monitor periodically. It can't get hung > > on just one message queue. I thought a message queue would work or have > > an option to work like a ring buffer but that does not seem to be the > > case. My concept is to have this process check several "queues" and > > then suspend for a safe amount of time before looping back to check > > them again. Any sage advice appreciated. Thanks. > > > > > Queues are there for processes that only have reason to run if there's > something in the queue to be processed. > > If you just want a FIFO but have no plans to block on it then don't use > the OS queue -- the OS queue adds significant overhead for just the > behavior that you're decrying. > > I would use the word "monitoring" if I'm only interested in the current > value of something -- if this is the case then don't use a queue at all > -- just stuff your values (atomically, please) into registers, wake up > periodically, and read them. > > On the other hand, if you have one RTOS task that's performing multiple > 'real' tasks -- break it up, and do it now! > > One of the biggest software disasters I ever had the misfortune to work > on featured a task that controlled two motors, with a single queue that > sent messages about target positions. The task wouldn't service the > queue until both motors were still, so you could pump messages in way > faster than the task would take them off. A user could sit down in > front of the system and flip a switch for a while until the queue > overflowed. Once that happened the whole messaging system for the > entire application got bent*, about half of the processes went into > snits and stopped talking, and the thing would limp along until someone > took pity on it and cycled power. > > Had the task just woken up periodically and monitored target values for > the motors (or -- gasp -- had there been _two tasks_) none of that would > have happened. >
Well maybe if I read enough it will start to make sense but right now it seems that there are only a few allowed ways for process to talk to each other in this Zilog scheme..
galt_57@hotmail.com wrote:
> Dave wrote: >> galt_57 wrote: >> >>> Starting on my first RTOS project and can't quite see the logic to the >>> interprocess communications. The Zilog RTOS offers message queues, but >>> if the queue is empty the reading process is suspended until something >>> shows up in the queue. Well sorry, that isn't good because my process >>> has multiple things it needs to monitor periodically. It can't get hung >>> on just one message queue. I thought a message queue would work or have >>> an option to work like a ring buffer but that does not seem to be the >>> case. My concept is to have this process check several "queues" and >>> then suspend for a safe amount of time before looping back to check them >>> again. Any sage advice appreciated. Thanks. >> The function RZKReceiveFromQueue() includes a wait time parameter. >> >> Also, from the ZiLOG Real-Time Kernel v2.0.0 Reference Manual, page 15: >> >> "You can choose not to block on message queues to receive or send message >> queue messages. When this option is chosen, a TIMEOUT error occurs if the >> message queue is empty while receiving, or full while sending messages." >> >> And there is also the RZKPeekMessageQueue() function which might do for >> you. >> >> If you were to block on each queue for one tick, wouldn't that be safe >> since you say "suspend for a safe amount of time before looping back to >> check them again"? > > That is true. You have a good point. If I want to suspend for a period > of time then I ought to be able to use the timeout on each queue set to > half of that period. I just have not figured out this kooky RTOS stuff. > The peek command copies the entire message out of the queue, which > seems rather pointless. I just can't see the logic of not providing a > non-blocking way to determine if there are one or more messages in the > queue. I mean what is the point of that? Ring buffers worked fine for > talking to ISR's. Why aren't they good enough for an RTOS? >
They are You will need a control like a semaphore to control access. Or set up a critical area. The features of the OS are there to help with the issues of tasks trying to communicate or share resources. Unlike an ISR the write to the queue could also be interrupted.
galt_57@hotmail.com wrote:

> Tim Wescott wrote: > >>galt_57@hotmail.com wrote: >> >> >>>Starting on my first RTOS project and can't quite see the logic to the >>>interprocess communications. The Zilog RTOS offers message queues, but >>>if the queue is empty the reading process is suspended until something >>>shows up in the queue. Well sorry, that isn't good because my process >>>has multiple things it needs to monitor periodically. It can't get hung >>>on just one message queue. I thought a message queue would work or have >>>an option to work like a ring buffer but that does not seem to be the >>>case. My concept is to have this process check several "queues" and >>>then suspend for a safe amount of time before looping back to check >>>them again. Any sage advice appreciated. Thanks. >>> >>> >> >>Queues are there for processes that only have reason to run if there's >>something in the queue to be processed. >> >>If you just want a FIFO but have no plans to block on it then don't use >>the OS queue -- the OS queue adds significant overhead for just the >>behavior that you're decrying. >> >>I would use the word "monitoring" if I'm only interested in the current >>value of something -- if this is the case then don't use a queue at all >>-- just stuff your values (atomically, please) into registers, wake up >>periodically, and read them. >> >>On the other hand, if you have one RTOS task that's performing multiple >>'real' tasks -- break it up, and do it now! >> >>One of the biggest software disasters I ever had the misfortune to work >>on featured a task that controlled two motors, with a single queue that >>sent messages about target positions. The task wouldn't service the >>queue until both motors were still, so you could pump messages in way >>faster than the task would take them off. A user could sit down in >>front of the system and flip a switch for a while until the queue >>overflowed. Once that happened the whole messaging system for the >>entire application got bent*, about half of the processes went into >>snits and stopped talking, and the thing would limp along until someone >>took pity on it and cycled power. >> >>Had the task just woken up periodically and monitored target values for >>the motors (or -- gasp -- had there been _two tasks_) none of that would >>have happened. >> > > > Well maybe if I read enough it will start to make sense but right now > it seems that there are only a few allowed ways for process to talk to > each other in this Zilog scheme.. >
Unless you're using a processor with a memory management unit they can't stop you from looking anywhere you want. If you build the application and link it as one, then you have global access to anything you make global (I'm assuming you're programming in C or assembly here). Some RTOS manuals will write about interprocess communication as if it must always be synchronous, but this is not necessarily so. Having said that, I should mention that if you _do_ choose to communicate via register, you should assume that it will change at any time, and adjust your expectations accordingly. -- Tim Wescott Wescott Design Services http://www.wescottdesign.com Posting from Google? See http://cfaj.freeshell.org/google/ "Applied Control Theory for Embedded Systems" came out in April. See details at http://www.wescottdesign.com/actfes/actfes.html
galt_57@hotmail.com wrote:

> Starting on my first RTOS project and can't quite see the logic to the > interprocess communications. The Zilog RTOS offers message queues, but > if the queue is empty the reading process is suspended until something > shows up in the queue. Well sorry, that isn't good because my process > has multiple things it needs to monitor periodically. It can't get hung > on just one message queue. I thought a message queue would work or have > an option to work like a ring buffer but that does not seem to be the > case. My concept is to have this process check several "queues" and > then suspend for a safe amount of time before looping back to check > them again. Any sage advice appreciated. Thanks. > > > Dave >
I'm looking at this thread, and I'm thinking that you need to go digging for a basic tutorial on using an RTOS. They're very handy things, but it sounds like you're misusing the features. Here's my quick, dirty, and probably wrong summation: 1. Never write a task loop inside a task. Use one RTOS task per 'real' task. 2. Think about how things need to be synchronized, and why. 2a. A message handler should be event-driven, because there's nothing to do between messages. 2b. If an out-of-date message is useless, don't bother using a queue -- just write to a spot in memory ('register') and set a semaphore. 2c. Some things are inherently periodic, like motion control loops or video interrupt handlers. There's no point in using a queue here -- just set a semaphore from your timer interrupt (or use a periodic semaphore if your OS provides it). 3. Don't synchronize things that don't need to be. If your task polls X, and your task is guaranteed to repeat fast enough to catch X in the act of doing anything interesting, just read X inside your task and be happy. 4. Think about OS resources. OS messages queues can be very expensive in terms of processor time and memory, so if you know you're going to get a ton of messages each time your task has a chance to run don't use a message queue. An example of this is serial handling -- for handling serial messages I'll have the ISR dump stuff into a ring buffer and set a semaphore. The (possibly low priority) task that services the ring buffer my not come on until there's 50 characters in the buffer, and it'll chew through all of them before going back to sleep. Better yet, if I can the ISR will dump stuff into a ring buffer and only set a semaphore on a delimiter (end-of-packet, or carriage return if it's ASCII). This _really_ trims down the clock cycles. 5. And don't forget that the 'RT' in RTOS means "real time" -- make sure you make your deadlines! I should mention that after my experience with the Worst Software Ever that I detailed in my other post I keep a string of garlic and a crucifix handy, and I wave them around whenever anyone mentions queues for anything other than strict message handling. So you can take my input as slightly biased... -- Tim Wescott Wescott Design Services http://www.wescottdesign.com Posting from Google? See http://cfaj.freeshell.org/google/ "Applied Control Theory for Embedded Systems" came out in April. See details at http://www.wescottdesign.com/actfes/actfes.html

The 2024 Embedded Online Conference