Quality RTOS & Embedded Software

 Real time embedded FreeRTOS RSS feed 
Quick Start Supported MCUs PDF Books Trace Tools Ecosystem TCP & FAT




Loading

Question about Blocked and Suspended

Posted by Torben on May 24, 2007
Hi!

In my application I run several tasks. Now I noticed that tasks that are waiting, using vTaskDelay(), enter the blocked state, while tasks that are waiting, using xQueueReceive() with the parameter portMAX_DELAY enter the suspended state. I thought that these tasks also enter the blocked state. Can someone expail why this is and what the difference is between blocked and suspended besides waiting for a temporal event as explained on the FreeRTOS homepage?

Thx!

RE: Question about Blocked and Suspended

Posted by Dave on May 24, 2007
This was a recent change that makes tasks that block on an event wait for ever (without timeout) if portMAX_DELAY is used as the block time AND configINCLUDE_TaskSuspend is set to 1.

If configINCLUDE_TaskSuspend is zero then tasks using portMAX_DELAY to wait for an event will indeed be moved to the blocked state rather than the suspended state.

As far as the application goes it does not need to care if the task is suspended or blocked. When the event occurs that the task is waiting for the task will automatically be moved back to the ready state no matter which of the non active states it is in.

Dave.

RE: Question about Blocked and Suspended

Posted by Torben on May 25, 2007
Then what exactly is the difference between blocked and suspended? Can a task get to the running state faster out of one of the states?

RE: Question about Blocked and Suspended

Posted by embeddedc on May 25, 2007
Basically the difference is that tasks in the blocked state always have a timeout. Tasks in the suspended state are suspended indefinitely, there is no timeout.

From the users point of view tasks that block on an event are in the blocked state. You have obviously gone into the code in more detail that some so have noticed that under certain circumstances the task is actually moved into a suspended queue rather than a blocked queue, but this is an implementation detail, conceptually the task is still blocked rather than suspended.

In older versions of FreeRTOS is was not possible to block indefinitely for an event. You always had to specify a timeout. Newer versions take the longest possible timeout value, portMAX_DELAY, as an indication that the user actually wants to block indefinitely for the event. Under this circumstance moving the task to the suspended queue is just a trick that prevents the kernel from ever waking the task purely because its timeout had expired.


RE: Question about Blocked and Suspended

Posted by Torben on May 25, 2007
So I dont have to worry that a task waiting for an event with the portMAX_DELAY parameter will stop waiting after a certain time? Because that would be a problem for my implementation!

RE: Question about Blocked and Suspended

Posted by embeddedc on May 25, 2007
Thats right. The old way of waiting indefinately for an event was to do something like this -

while( xQueueReceive( xQueue, portMAX_DELAY ) != true );

This way if the task calling xQueueReceive unblocked because portMAX_DELAY ticks had expired it would automatically call xQueueReceive() again because of the while loop.

Now, provided configINCLUDE_TASK_SUSPEND is set to 1, you don't need the while loop and the code just becomes -

xQueueReceive( xQueue, portMAX_DELAY );

RE: Question about Blocked and Suspended

Posted by Darrik Spaude on July 10, 2007
That would be INCLUDE_vTaskSuspend rather than configINCLUDE_TASK_SUSPEND, correct? At least that appears to be true for 4.3.1.

RE: Question about Blocked and Suspended

Posted by Richard on July 11, 2007
Yes - there is no configINCLUDE_TASK_SUSPEND.

Regards.

Question about Blocked and Suspended

Posted by tomwbarclay on October 21, 2013

HI, fast forward to version 7.3. Same question, but slightly different issue.

I have a number of tasks that wait forever on an event. A number of them wait on the same event, but only one should be running (blocked waiting on the event) while the remainder are suspended (and should ignore the event).

I want to do this as a way of determining the behavior of the unit based on the unit mode variable. Each task does a different action when triggered by the same event.

At power up all of the tasks are created and enter the running state till they hit the wait forever on an event code line.

I manually force a task_suspend() on all the tasks, except the one that matches the desired behavior.

Point is that according to the previous comments, and I cant find any more up to date discussion, the suspended tasks will be 'resumed' if their matching trigger event occurs.

Assuming the above is true then it raises the fact that I cant use tasksuspend() and taskresume() as a hard task on/off mechanism.

In my tests I can read a task state and find it is SUSPENDED rather than the BLOCKED state I expected.

If my reading of FreeRTOS behavior is correct then I will have to re-architect my code. No problem .. I'd just like to know.

Best regards ....


Question about Blocked and Suspended

Posted by richardbarry on October 21, 2013

So the issue is you are using the reported task state to know which task is actually the active task (the one that is not genuinely suspended rather than block indefinitely) - but all the tasks report as being suspended - even the one that is blocked indefinitely.

I don't think you need to re-architect your code - just change the block time used when a task blocks on the event.

If you use a block time of portMAXDELAY, then the task will block indefinitely, but report its state as Suspended. Whereas if you use a block time of ( portMAXDELAY - 1 ) then the task will report its state as Blocked.

That means the task will not block indefinitely any more. If that is a problem or not depends on how often the events occur. If a block time of ( portMAX_DELAY - 1 ) is several weeks, and events occur every few minutes, you don't need to change anything. On the other hand if events can occur less frequently than the block period you will have to check the return value of whatever the event you are pending on is.

For example, if you are blocking on a semaphore, instead of using:

/* When this function returns you know you have the semaphore. */ xSemaphoreTake( mySemaphore, portMAX_DELAY );

use /* When this loop exits you know you have the semaphore. */ while( xSemaphoreTake( mySemaphore, portMAX_DELAY - 1 ) != pdPASS );

Regards.


Question about Blocked and Suspended

Posted by tomwbarclay on October 21, 2013

The issue is that I only want 1 of N tasks to be activated. Which task is active will depend on the mode of the device. A simple example may help show what I am talking about.

Imagine a box has 1 button to change mode and another button for display function as well as a display. When the user presses the mode-button the mode is changed. This stops (suspends) the existing task and starts (resumes) a new one, which does something on the display that varies with the presses on the display button. Assume there are 5 different modes for the unit. For each 'mode' there will be a separate task, giving 5 tasks in total, of which 4 are always off (suspended) and 1 is running. All the tasks have similar structure and in the forever-loop they wait on the event created by the display-button being pressed.

In this architecture the mode-button acts like a task selector switch and the display button says do something now. Each task has its own unique behavior coded after the event-wait point.

The example is of course overkill, but I am just trying to illustrate a point.

I can, (and probably will), put in timeouts into the event wait as you suggest and catch them in the code as your example shows.

My preference would have been for the RTOS to provide solid task OFF when suspended by a direct task command. Maybe its one for the future ? In my opinion it would be a strong feature to have as the existing mechanism seems to produce an undesirable side effect of blurring the task states BLOCKED and SUSPENDED.

Best regards


Question about Blocked and Suspended

Posted by richardbarry on October 21, 2013

Sorry - I'm not following this. I understand what it is you want to do, I just don't understand why you can't do it.

If you call vTaskSuspend() on a task it will go into the Suspended state and stay there indefinitely. The only way to get the task out of the Suspended state is to call vTaskResume() on that task.

If you block on an event (lets say a semaphore) then the task will block on the event as long as you tell it to. If you have an infinite timeout the only way for the task to continue is for the event to occur. If there is not an infinite time out then the task will continue if either the event occurs OR a timeout occurs (or the task gets suspended).

If the task is blocked on the event with an infinite timeout it reports itself as being suspended - but it is not suspended - it is blocked on the event. I thought that was what your problem way - you were relying on the tasks report of its own state and were confused between a task that was actually genuinely in the suspended state and one that was block indefinitely waiting for an event that just reported itself as being suspended even though it wasn't.

I think I can probably change that behaviour anyway, as the function only needs to check if the task is blocked on something. If it is, even if its block time is infinite, it could return 'Blocked'.

Regards.


Question about Blocked and Suspended

Posted by tomwbarclay on October 21, 2013

Sorry ... maybe I have got confused ..

a) When a task is blocked on an event with infinite timeout 1) It reports its suspended (by using task handle and appropriate function to get state) not that its blocked. I have tested this so I know its true. 2) In my system I did not want the master control task to suspend a minor task if the minor task was not blocked, ie the minor task was doing something. 3) (I think this is where I get confused) I understood that if the master task issued a suspend instruction to the minor task, then an event could still arrive at the minor task and activate it, (this assumption may well be wrong), even though it has been instructed to become suspended.

b) I have changed my code so that the master task simply checks that the minor task is not running (i.e.its blocked or suspended) before issuing the suspend instruction. 1) I have not yet tested this ... if assumption (a3) is indeed wrong, then this should work 2) the master task can then wake up the minor task with a resume instruction.

c) as far as I can see from the documentation, there a no side effects from suspending and already suspended task or resuming and already running task.

d) I can do what I want to do, its just a matter of selecting the coding pattern I want from the options available.

Best regards again.


Question about Blocked and Suspended

Posted by richardbarry on October 22, 2013

3) (I think this is where I get confused) I understood that if the master task issued a suspend instruction to the minor task, then an event could still arrive at the minor task and activate it, (this assumption may well be wrong), even though it has been instructed to become suspended.

When a task is suspended (by a call to vTaskSuspend()) then it is no longer blocked on the event so the event cannot wake it. The only way for a Suspended task to ever run again is for another task to resume it using vTaskResume().

Regards.


Question about Blocked and Suspended

Posted by tombarclay on October 22, 2013

Thanks for the clarification ...I understand fully now.

The confusion really started when I found that the minor task state returned SUSPENDED instead of BLOCKED.

I humbly suggest that your statement in an earlier reply ...

"I think I can probably change that behaviour anyway, as the function only needs to check if the task is blocked on something. If it is, even if its block time is infinite, it could return 'Blocked'."

is a good idea.

Best regards ...


Question about Blocked and Suspended

Posted by richardbarry on October 22, 2013

I humbly suggest that your statement in an earlier reply

Done it already - it was checked in a few hours ago :o)

else if( pxStateList == &xSuspendedTaskList )
{
    /* The task being queried is referenced from the suspended
    list.  Is it genuinely suspended or is it block 
    indefinitely? */
    if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) == NULL )
    {
        eReturn = eSuspended;
    }
    else
    {
        eReturn = eBlocked;
    }
}

Regards.


[ Back to the top ]    [ About FreeRTOS ]    [ Sitemap ]    [ ]




Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.

Latest News

FreeRTOS kernel V10 is available for immediate download. Now MIT licensed.


FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

IAR Partner

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

STMicro RTOS partner supporting ARM7, ARM Cortex-M3, ARM Cortex-M4 and ARM Cortex-M0

Texas Instruments MCU Developer Network RTOS partner for ARM and MSP430 microcontrollers

OpenRTOS and SafeRTOS