Queue wait forever?

neilbradley wrote on Tuesday, October 17, 2006:

Is there a parameter to wait forever on a queue? I know I can set ridiculously long tick times and check the result for trueness, but I’d rather not wake up this (and other) threads without a reason. Thanks!

nobody wrote on Tuesday, October 17, 2006:

portMAX_DELAY on a 32bit architecture with a very fast 1ms tick will wake I think every 50 days?  Is this a problem?

You could encapsulate a while loop in a wait forever function as:

void myWaitFunction()
{
while( xQueueReceive(…) != 1 );
}

neilbradley wrote on Tuesday, October 17, 2006:

Yeah, I know, but I’d rather not debug a problem that would crop up once every 50 days if you know what I mean (in other words, I don’t want the thread waking up for any reason other than when it is purposefully triggered).

nobody wrote on Tuesday, October 17, 2006:

>I know, but I’d rather not debug a problem that would crop up once every 50 days

LOL.  We have all been there at some point in our careers.  I remember years ago trying to debug a problem that only occurred when you changed time zones.  As I was always in the same place when looking at the problem it took a looooooong time to find it.

neilbradley wrote on Tuesday, October 17, 2006:

Yup, exactly. I’ve been an embedded guy for FAR too long. The worst bug I ever had to debug was embedded modem firmware without a debugger. Took about 6 weeks to find a really nasty little corner case on an event that would only occur once in a blue moon. Trellis Code Modulation. Shudder…

jwestmoreland wrote on Friday, October 20, 2006:

What about something like the following:

#define EVER ;;
#define comRX_BLOCK_TIME (( portTickType ) 0xffff )

portTASK_FUNCTION ( qWaitTask, pvParameters )
{

   for (EVER)
   {
     if( xQueueReceive( xRxedChars, &cByteRxed, comRX_BLOCK_TIME ) )
    {    
          …
        }
    else  // ?
    {
      ;
    }
    } // end for

} // end task

This task only does something when something is available in the Q - otherwise times out and just waits again.  Nothing really happens if nothing is received.

HTH,
John

nobody wrote on Friday, October 20, 2006:

Yes, I’ve already looked at that possibility, but the whole idea is to never wake the task up if it never needs to be woken up. All of the other RTOSes I’ve worked with have a concept of “wait forever” (VXWorks, ThreadX, and uCOS-II to name a few), and FreeRTOS doesn’t. I don’t want any possibility of inducing a “once in a blue moon” timing problem or anything else being induced by waking up when not necessary.

jwestmoreland wrote on Friday, October 20, 2006:

Hmmm,  I’ve used it without any problem.  I have multiprocessor boards that have run literally for months without issue (at least for that). 

The source for all of the Qing code is free - you could modify it I suppose to accept a wait forever parameter - but I don’t know how that affects the other parts of the system.

Perhaps Richard can chime in on how much work it’ll be to make a change to the Qing code to make this possible.

Regards,
John

neilbradley wrote on Friday, October 20, 2006:

Call me overly paranoid, but my attitude is one of eliminating known possible instabilities or unpredictabilities in code if I know they have any potential to have an adverse effect on the system.

Though, I’ll go take a look at the queueing code. It’s highly likely that making a change to support it is easier than posting about it!

nobody wrote on Friday, October 20, 2006:

> Call me overly paranoid, but my attitude is
> one of eliminating known possible
> instabilities or unpredictabilities in code if
> I know they have any potential to have an
> adverse effect on the system.

Hmm … there’s something about the phrase “known unpredictabilities” that I find interesting … :slight_smile:

jwestmoreland wrote on Saturday, October 21, 2006:

Neil,

What about this?:

Create a ‘controller’ task that blocks on an event
and suspends your task with your Q  - once the
event is met then resume that task that has
your Q waiting with no delay - once the
event is over - the controller task suspends the task and waits for the next event or perhaps the Q task self suspends.  The controller task then waits for the next event.

Maybe something like that could be coded up.

I still don’t understand why something like my simple example above wouldn’t work.  I have a test set up that was running two tasks like that per MPU for 3+ months that ran without error.  The
only reason it stopped was because I tore the test setup down.

Regards,
John

neilbradley wrote on Saturday, October 21, 2006:

We’re apparently talking past eachother. I never said that your example above wouldn’t work. Not having a “wait forever” option on a thread is a missing feature. Threads should NEVER have to wake unless there’s a reason. My minimum standard for software is extreme predictability, and having something that wakes every “n” days, weeks, or months because of a missing feature is more than 0% chance that it can induce a bug or unpredictability into the system. Whether or not “it works” is not the point.

jwestmoreland wrote on Saturday, October 21, 2006:

Neil,

There’s no such thing as 0% chance for anything in
this world.  Are you fooling yourself into thinking
the hardware is perfect?

Whether or not it works is precisely the point.

Regards,
John

neilbradley wrote on Saturday, October 21, 2006:

There’s a 0% chance the other branch will execute and that thread will wake up on a periodic if the code is not there to do it. :wink: See?

It’s kind of a moot point at this point anwyay, as the reason I was using queues (transmit buffer for the UART) wound up crashing anyway (my manual ring buffer approach has been running for over 3 days solid now). See my other thread if you’re interested.

jwestmoreland wrote on Saturday, October 21, 2006:

Neil,

Can you tell me what is not predictable about the
following?

#define EVER ;;
#define comRX_BLOCK_TIME (( portTickType ) 0xffff )

portTASK_FUNCTION ( qWaitTask, pvParameters )
{

for (EVER)
{
if( xQueueReceive( xRxedChars, &cByteRxed, comRX_BLOCK_TIME ) )


}
else // ?
{
;
}
} // end for

} // end task

Regards,
John

neilbradley wrote on Saturday, October 21, 2006:

Sure, the timing of all other threads in the system when this thread wakes up. The sheer fact that the thread woke up will cause slop in the timing of the other threads. Why have it if it’s not needed?

nobody wrote on Saturday, October 21, 2006:

Neil,

Not sure if you’re referring to soft or hard real
time here - but for soft real time it’s well within the definition.

Have you taken statistics on timer IRQ’s?  Does your timer IRQ always start exactly at the same place and always end at the same time, every time?

What is your definition of ‘slop’?

Do your tasks always take exactly the same time to run, every time they are run?  What about your interrupts?  Do you know exactly how long they take, every time they run?

My example can probably be modified in assembly to have a penalty of a few clock cycles when the Q times out.  This is acceptable in soft real-time systems.  I know that my timer IRQ isn’t that exact (soft).

If you’re talking hard real-time - there are other issues.  Hardware needs to support it first, and usually that’s not a trivial issue.

The Q source is free - and there’s an open source pthreads project out there - so what you don’t like can be ‘fixed’.

Regards,
John

neilbradley wrote on Saturday, October 21, 2006:

Correct, I’m referring to hard real time. Really, this is all just defensive positioning and minimizing the possibility of unexpected sequences of events that MAY lead to other problems or exposure of bugs or other unexpected side effects. Plus, it’s a departure from what I’ve seen in the other RTOSes, and seems like something that the RTOS itself should support.

In regards to your first question, yes, in my specific embedded system the IRQ starts at the same place every time at all times (it doesn’t end at the same time but my real time events are at the very beginning of the IRQ).

I should probably stop talking and just take a look at the source. Might be quite easy to modify. :wink:

westmorelandeng wrote on Saturday, October 21, 2006:

Hey Neil,

Hard real-time is a different beast altogether.  I can understand where you’re coming from now.

I think FreeRTOS can support it - but I’d talk with Richard and the folks at High Integrity Systems if this is what you’re wanting to tackle.

SafeRTOS looks like it may be what you want.
It wouldn’t hurt my feelings right now if we could
flush the GPL and all of the crap that surrounds
that…

At least you’re not looking at Embedded Windows which claims - and I’m not kidding - that they can do hard real-time. 

I think you have some valid points - but I also think that some converstions with Richard will really pay off. 

I’m a great big fan of FreeRTOS because <I think> it’s the only real RTOS for memory contrained low-power systems - which is where I spend a lot of my time.  I don’t want to roll my own - I know a lot of people do that - but the peer review that happens just like what we’re doing never happens.

I think modifying the Q code is possible - I haven’t looked at what would happen if something like POSIX compliant threads (aka tasks) were to become a part of FreeRTOS - how that may change things - but it’s certainly a possiblilty.

Richard monitors all of our posts - hopefully he’ll chime in here.

Best Of Luck,
John W.

neilbradley wrote on Saturday, October 21, 2006:

Thanks for the *! I’ll have a look at SafeRTOS a bit closer.

Regarding embedded Windows, I’ve done some work with that tree under CE and PPC. It’s actually quite a different beast than Microsoft’s desktop OSes and its scheduler is actually quite good. Hard real time? We shall see… but my environment doesn’t need a UI and runs in tiny memory and flash footprints, so it’s not suitable for my purposes anyway.

I also tend to be a bit obsessive about predictability, most notably because most of the software I work on must run for years. A lot of it becomes an odds game - if there’s a potential for a problem, it’s a real problem, and therefore must be avoided. This credo has served me well over the years in many embedded products.

Thanks again for the chat. I always appreciate a different perspective. Usually, either I learn something, someone else learns something, or we both learn something, and that’s cool.

FreeRTOS is quite solid. I’m monkeying around with it on a SAM7S256P board right now. Other than the odd queue problem I mentioned before, it’s working very well. Not to sound ingrateful, but FreeRTOS feels, shall we say, incomplete to me. Maybe it’s just because I come from the world of ThreadX, uCOS-II and VXWorks which has concepts of mutexes, counting semaphores, and event flags. I’m used to them.

But the saving grace is that I recognize that "incompleteness" is not really a bad thing in this case since the FreeRTOS kernel seems so solid. I view it as a VERY solid foundation for future features. I very much like the fact that the focus seems to be on having a very solid kernel rather than kitchen-sink syndrome. Richard is obviously a very intelligent and knowledgeable engineer, and generous to boot.

I’m currently evaluating FreeRTOS to replace another well known RTOS in a commercial project I’m working on. However, these missing features I need (some of which are environmental) I’ll either have to address within the kernel itself or write my own.

If you’re reading this Richard, thanks again for FreeRTOS. I’d love to contribute somehow, but I’m unsure how to proceed.

John, thanks again. I’m up in Portland, and the next time I’m in the bay area, I’ll drop you a note. Would love to chat embedded with a colleague! See ya!