Bug with suspended Tasks

Hello All, I am new to FreeRTOS and to this forum, and I do not know, if I am right here with the problem. But I am found a problem. I create tasks and suspend them all right after creation. If there are only two tasks, first is suspendet, and second one unsuspends the first one, everything is ok.
But if I create three tasks, first two are suspendet, and in a third one unsuspends the two first taks, then there is an error. And it happens after creating the second task, and on trying to suspend this. And the error occurs in a vTaskSwitchContext function, at line 1629 (version 6.1.1 of FreeRTOS) when the variable uxTopReadyPriority is overrolling without to check it. I did add the check, if it is == 0, then break the while loop, and the program goes further. Hope, it helps. Alexei

Bug with suspended Tasks

Sorry, I’m struggling to follow your explanation. 
I create tasks and suspend them all right after creation.
Are you creating then suspending before the scheduler has started or after the scheduler has started? Are the tasks suspending themselves, or being suspended by another task.  What are the relative priorities of the tasks?
If there are only two tasks, first is suspendet, and second one unsuspends the first one, everything is ok.
The first is suspended, then unsuspended by the second, it works……so the first starts running once it has been unsuspended.  Ok.
But if I create three tasks, first two are suspendet, and in a third one unsuspends the two first taks, then there is an error.
So task one and task two are in the suspended state (do they suspend themselves?  is the scheduler already running when this happens?  Are you sure they are actually suspended?)
And it happens after creating the second task, and on trying to suspend this. And the error occurs in a vTaskSwitchContext function, at line 1629 (version 6.1.1 of FreeRTOS) when the variable uxTopReadyPriority is overrolling without to check it.
Can you provide a very simple/basic example to help me understand the scenario you are describing? Thanks.

Bug with suspended Tasks

Hi, I got this problem of the underflowing of uxTopReadyPriority value (i.e the value of uxTopReadyPriority became negative and kept decrementing) In the end I used a work around by: 1) Creating all tasks that runs in the system.
2) Create a TaskSuspender Task and set it to the highest priority (this Task is meant to be the first Task to run and will suspend all other Tasks). At the end of this Task, suspend itself by invoking vTaskSuspend(NULL);
3) Invoke vTaskStartScheduler(); This lets the TaskSuspender suspend all other Tasks before anything happens and the IDLE Task will be running. Hope it help. Cheers,
Ivan

Bug with suspended Tasks

Hi, As an added note, I have just tried the following:
    xTaskCreate(Task1, 
                "Task1", 
                80, 
                NULL, 
                3, 
                &xHandleTask1 );

    vTaskSuspend( xHandleTask1 );

    vTaskStartScheduler();
It works fine on my RX62N RSK with FreeRTOS v7.0.0 :) Hope it helps! Regards,
Ivan

Bug with suspended Tasks

This lets the TaskSuspender suspend all other Tasks before anything happens and the IDLE Task will be running.
Hope it help. Not really.  My questions were intended to allow me to try and replicate the problem, and see if there is a problem.  I cannot look at the issue, assist you, or comment until you answer the questions or provide me with the code. Regards.

Bug with suspended Tasks

Hello all,
So, here is my code of tasks creation
  
  xTaskCreate( vDebugTask,
               ( const signed char * const )"DebugSecondTask",
               512,
               ( void * )0,
               tskIDLE_PRIORITY + 1,
               &taskHandles[ TSK_DEBUG_TASK ]
             );
  vTaskSuspend( taskHandles[ TSK_DEBUG_TASK ] );
  xTaskCreate( vGraphicTask,
               ( const signed char * const )"GrpahicTask",
               512,
               ( void * )0,
               tskIDLE_PRIORITY + 1,
               &taskHandles[ TSK_GRAPHIC_TASK ]
             );
  vTaskSuspend( taskHandles[ TSK_GRAPHIC_TASK ] );
  queueHandles[ Q_MAIN_TASK_QUEUE ] =  xQueueCreate( MTQ_QUEUE_SIZE, sizeof( T_MTQItem ) );
  // this task must be last created, because its started first
  xTaskCreate( vMainTask,
               ( const signed char * const )"Main Task",
               1024 + 512 + (1024 * 10),
               ( void * )0,
               tskIDLE_PRIORITY + 1,
               &taskHandles[ TSK_MAIN_TASK ]
             );
  // After here no task creation !!!!
  vTaskStartScheduler();
This is the main() function. As you see, the scheduler is NOT yet running. to tacadia:
until there was only two tasks, everything worked fine. Since I added one task more, the problem occurs. Alexey

Bug with suspended Tasks

Apologies tacadia – in my last reply I was assuming posts 1 and 4 in this thread were from the same person.  I have just realised they are not. With regards to suspending tasks before the scheduler has been started, which from the posted code it looks like tacadia is doing – it is good to know that it is working fine in V7.  The ability to do that was only introduced in V6.1.0, so, if previously, you were using a version earlier than that, then I would not expect it to have worked. Regards.

Bug with suspended Tasks

forget to add.
All other tasks are resumed IN the last one – vMainTask.

Bug with suspended Tasks

To richardbarry:
I use FreeRTOS 6.1.1

Bug with suspended Tasks

richardbarry: Hey no worries (: Just glad to be able to help (: masteralexei: I’m not in my lab to do the code walks and tests for now, but my suspicion is 2 folds: (1) ensure that your vMainTask is really the first one that is running. For an absolute certainty, raise vMainTask’s priority to be higher than that of the other 2 Tasks.
(2) Ensure that you have enough xHeap space for memory allocation of the Tasks as well as enough Task stack space. During a context switch, the context of the Task will be pushed onto the Task Stack. You can check your memory map for this (: Hope it helps. Cheers,
Ivan

Bug with suspended Tasks

To tacadia: 1. Well, the priority are the same by all three tasks. But after creation of first  two, they are immediately suspended (Scheduler is not yet runung).
Only the last one is not suspended. I think, that if the task suspended, it will not be running, even if the task has a higher priority.
So. And as I have seen, the last created task started as first one, if all tasks are having the same priority. Or am I wrong here?
2. I think that 10 MegaBytes of Heap are enough for tree tasks :) And one more,
The bug occurs BEFORE the scheduler stared, but during the call of vTaskSuspend for the second one in my example.
the last, third task is even not yet created. That means, that there is already one task created and suspended, and another task created too, and is to suspend. A. And here you can see, on which hardware this all running:
http://www.fun-electronic.net/lang/ru/2011/03/12/some-small-news
http://www.fun-electronic.net/lang/ru/2011/04/04/displayformyevalkit

Bug with suspended Tasks

Ok – I have just had a look at this, and can confirm that there is a bug.  Here is the tracker I have just opened which documents a simple work around for the time being.  Thanks for bringing this to my attention – and congratulations for finding the first genuine bug in absolutely ages and ages!  This relates to a piece of code that was only added recently, and highlights a case that, obviously, was not tested satisfactorily. https://sourceforge.net/tracker/?func=detail&aid=3295065&group_id=111543&atid=659633 Regards.

Bug with suspended Tasks

Thanks for the congratulations :)
Hope, that FreeRTOS will have a long live :)
Thank you guys for that nice OS.

Bug with suspended Tasks

In the function vTaskSuspend(), if you replace the line (this is from FreeRTOS V7.x.x, and V6.x.x will probably not have the ‘U’ after the ‘1’):
/* The scheduler is not running, but the task that was pointed
to by pxCurrentTCB has just been suspended and pxCurrentTCB
must be adjusted to point to a different task. */
if( uxCurrentNumberOfTasks == ( unsigned portBASE_TYPE ) 1U )
with the following code:
/* The scheduler is not running, but the task that was pointed
to by pxCurrentTCB has just been suspended and pxCurrentTCB
must be adjusted to point to a different task. */
if( listCURRENT_LIST_LENGTH( &xSuspendedTaskList ) == uxCurrentNumberOfTasks ) 
…then you should find the problem fixed.  Please let me know if you still have a problem after this change. Regards.

Bug with suspended Tasks

To richardbarry: After made the changes, that you suggest, it works!
But I think, that it still would be nice to have that check in “while” loop in vTaskSwitchContext function. So it is safer, I think.

Bug with suspended Tasks

But I think, that it still would be nice to have that check in “while” loop in vTaskSwitchContext function. So it is safer, I think.
That code runs very often and has to be optimised, otherwise people will complain, a lot.  Also, having that check in would have simply hidden the problem that you found – two wrongs making a right as it were, or at least appearing to. FreeRTOS V7.0.0 does however have an assert in the loop thus:
        /* Find the highest priority queue that contains ready tasks. */
        while( listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxTopReadyPriority ] ) ) )
        {
            configASSERT( uxTopReadyPriority );
            --uxTopReadyPriority;
        }
Regards.

Bug with suspended Tasks

Richard,
This discussion brought up a thought for me. Currently FreeRTOS creates the idle task last, and failure to create that is fatal to starting the OS. It appears that there may also be parts of the code that assume that there is always some task to be scheduled. Would it make sense to change the creation of the idle task from the last task created to the first? This would mean that starting the schedule is much less apt to fail, and a failure to create the idle task could be reported as a failure to create the first user task. It would also make the condition of always being a task ready to run true once any task is created, as opposed to only true once the system is stated.

Bug with suspended Tasks

If you go back far enough in the history I think (from memory) the idle task used to be created when the first task was created.  It was later changed to instead be created when the scheduler was started.  I can’t remember why now, it was many years ago.  The reason might be given in the change log, but it probably pre-dates the current SVN repository. Only very recent versions of FreeRTOS have had the ability to suspend a task before the scheduler is started – the ability was added due to multiple requests from users.  When the scheduler is running there must always be a task ready to schedule (hence the idle task must never block), but prior to the introduction of this new ability there was not the same requirement before the scheduler was started. Regards.

Bug with suspended Tasks

Thanks for the heads up Richard. I’ll update the code and do more testing when I get back to the lab. Congrats on having your problem solved masteralexei :) Cheers,
Ivan

Bug with suspended Tasks

Hi Richard, This is a follow up on our issues presented in this thread. I have done the patch as you’ve suggested and yes, it doesn’t hang anymore. When I did more tests, I found out that the issue in the original code that causes the uxTopReadyPriority to underflow will arise from the following sequence of execution: 1) Create Task1
2) Suspend Task1
3) Create Task2
4) Suspend Task2 <- (under flow occurs here) When Task2 is created, uxCurrentNumberOfTasks has incremented to 2. However, with the old code, of:
/* The scheduler is not running, but the task that was pointed
to by pxCurrentTCB has just been suspended and pxCurrentTCB
must be adjusted to point to a different task. */
if( uxCurrentNumberOfTasks == ( unsigned portBASE_TYPE ) 1U )
{
    /* No other tasks are defined, so set pxCurrentTCB back to
    NULL so when the next task is created pxCurrentTCB will
    be set to point to it no matter what its relative priority
    is. */
    pxCurrentTCB = NULL;
}
else
{
    vTaskSwitchContext();
}
This causes the vTaskSwitchContext() to be invoked. When this happens, the while loop code:
/* Find the highest priority queue that contains ready tasks. */
while( listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxTopReadyPriority ] ) ) )
{
    configASSERT( uxTopReadyPriority );
    --uxTopReadyPriority;
}
Will cause the uxtopReadyPriority to underflow. I see your point of now checking the number of suspended tasks with that of the uxCurrentNumberOfTasks. This only makes sense. I thought I’d just document this here just in case someone comes by and wonder what all the underflow is about. Thanks for the help once again Richard. :) Warmest Regards,
Ivan