Queue wait forever?

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!

Queue wait forever?

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 ); }

Queue wait forever?

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).

Queue wait forever?

>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.

Queue wait forever?

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….

Queue wait forever?

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

Queue wait forever?

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.

Queue wait forever?

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

Queue wait forever?

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!

Queue wait forever?

> 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 … :)

Queue wait forever?

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

Queue wait forever?

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.

Queue wait forever?

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

Queue wait forever?

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. ;-) 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.

Queue wait forever?

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

Queue wait forever?

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?

Queue wait forever?

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

Queue wait forever?

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. ;-)

Queue wait forever?

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.

Queue wait forever?

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!

Queue wait forever?

Neil, I have taken a lot of VxWorks training and have worked with that too – but I find it a little heavy handed…<don’t want to go there…> I may do some uC/OS-II ports soon – depends on a few things…. I cut my teeth so to speak on Nucleus – which I consider full featured – especially at the time (1993).  Started as a Ph.D. thesis if memory serves me at CalTech… I agree with your comments re: FreeRTOS.  Hail to Richard! for sure. I’m in San Jose – so, please, next time you’re down here indeed drop me a line.  We used to have a nice place downtown called the Pig ‘N Whistle – but that’s gone the way of the dinosaurs so to speak.  We don’t have the uBreweries that you guys have up in Portland – but we do have some… I’d like to meet with you as well next time you’re here. Best Regards, John W.

Queue wait forever?

I think there may be an easy option if you want a task to block without a timeout on a queue. If a task appears in a delayed task list it is blocked with a timeout.  When the time out occurs the task will be woken from within the tick ISR. If a task appears on the suspended task list it remains on the suspended task list until such a time that another task or an ISR un-suspends it.  It can therefore remain on the suspended task list indefinitely. When a task blocks on a queue vTaskPlaceOnEventList() is called.  This places the calling task onto a delayed task list – to be woken when the block time expires.  If instead the task were to be placed on a suspended task list it would remain blocked/suspended until such a time that the queue event it was waiting for occurred. Within vTaskPlaceOnEventList() the two lines: if( xTimeToWake < xTickCount ) { ____/* Wake time has overflowed.  Place this item in the overflow list. */ ____vListInsert( ( xList * ) pxOverflowDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) ); } else { ____/* The wake time has not overflowed, so we can use the current block list. */ ____vListInsert( ( xList * ) pxDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) ); } would become: if( xTimeToWake == BLOCK_FOREVER ) { ____vListInsertEnd( ( xList * ) xSuspendedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) ); } else if( xTimeToWake < xTickCount ) { ____/* Wake time has overflowed.  Place this item in the overflow list. */ ____vListInsert( ( xList * ) pxOverflowDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) ); } else { ____/* The wake time has not overflowed, so we can use the current block list. */ ____vListInsert( ( xList * ) pxDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) ); } This would result in the event list item being on the queue in priority order, and the generic (state) list item being on the suspended list. I have not tested this or done a full analysis, but it seems straight forward.  The problem would be what value to use for BLOCK_FOREVER, as the block time is an unsigned value all possible values are valid block times.  You could take portMAX_DELAY to mean that you want to block for ever, or you could introduce a new parameter to the function to indicate that you wanted to block forever – in which case the block time would be ignored. Regards.

Queue wait forever?

Richard, Thanks for the test code. I can code it up soon (or Neil too) – to see how it works – but developing a test case that really proves it’s OK will take some practical test time. I’m using the example that I pointed out above – and it’s OK for soft real-time – I can code up what you’ve suggested but I’ll get the same result (I assume) since in my case I know that I almost never hit the timeout case – and if and when I do – it’s not a big deal.  I suppose I can play with the timeout values (making them relatively small) so test times aren’t into months… Thanks again! John

Queue wait forever?

I have updated tasks.c in Subversion to include this.  I quite like this change – it offers a run time efficiency improvement when blocking with portMAX_DELAY with a tiny code size increase. Regards.

Queue wait forever?

Excellent! Thank you! Now I’ll just have to install Subversion. ;-)

Queue wait forever?

Try this: http://tortoisesvn.tigris.org/

Queue wait forever?

Will the API documentation on the FreeRTOS web site be updated with this information? By the way, I think there is plenty of other useful information in this forum that also should be in the docs.

Queue wait forever?

Its on the todo list ;-) Regards.

Queue wait forever?

I wish I found this thread sooner, but I am wondering if there is currently any use for specifying xTicksToWait = 0: xQueueReceive( xQueue, &( pxRxedMessage ), ( portTickType ) 0 ) I thought that it would be reasonable if 0 meant no timeout. Or does anyone already use that to really mean "don’t wait", or what exactly would it do? But still, I have no complaint myself to use portMAX_DELAY, except that some others might have used that value and expected it to check back on occasion (perhaps rare cases). That means those would have to be changed to portMAX_DELAY-1 or something.

Queue wait forever?

Passing zero as the pararameter means don’t wait.  Return immediately even when no data is available. In the latest version using portMAX_DELAY causes it to block to wait indefinitely if you have INCLUDE_vTaskSuspend defined as 1.  Otherwise it will cause it to block for portMAX_DELAY ticks – about 40 days on a 32 bit architecture with a tick frequency of 1KHz.

Queue wait forever?

Oh yes, for some reason I had forgot. So waiting 0 ensures it will not block. Fairly important in many cases :)