Why do RTOS tasks have to be executed in infinite loop?
Asked Answered
R

3

10

Hi I'm a newbie in RTOS and in almost every document I read, it indicates that the tasks must be in infinite loop but none states why. Can anyone help explain this? Thanks

Reganregard answered 10/3, 2015 at 7:43 Comment(4)
Well, because they would otherwise fall off the end and so terminate or crash, leaving nothing to do.Campbellite
This depends on the RTOS. You can have an RTOS that handles the return from a task function gracefully. But micro-controller design claims to save resources. It can be cheaper to skip this end-of-task handling.Cameleer
Your assertion is false. RTOS can have both infinite loop tasks and terminating tasks. The main loop of any embedded system is most certainly an infinite loop. Another example: A clock task will most likely be an infinite loop. In contraast, a task to send an email notification will most likely be implemented as a terminating task to be re-incarnated when there is again need to send another email -- possibly hours, or days later. (The email task as infinite loop polling for pending emails would waste resources as its task slot could be used by another ad-hoc task.)Ecumenicist
Please refrain from posting answers in the comments section. If you have an answer, post it as such.Veritable
V
5

They don't, but if a task function runs to completion, the task is terminated.

You could perhaps choose to instantiate a new run-to-completion task every time one is needed, but instantiating a task is time consuming and potentially non-deterministic, so not suited to hard real-time response. It is more efficient and responsive to have a task wait on some blocking object such as an event, semaphore or timer, so that it can respond deterministically every time it is required. On the other hand, if you have many different non-real-time tasks that only need to run occasionally, the run-to-completion pattern can save resources.

At least one task needs to run indefinitely however - if everything just stops your system will do nothing until the power is cycled or reset asserted (by a watchdog timer for example).

RTOS implementations vary, you will need to check how your RTOS handles terminating thread functions. You may need an explicit termination call to ensure resources are released by the kernel.

If you have a system that needs some form of controlled graceful shut-down, you need not code tasks as infinite loops, but have the loop exit conditionally so that the task can terminate on request, e.g;

while( (event_flags & TERMINATE) == 0 )
{
    event_flags = eventWait( WAIT_FOREVER ) ;

    // handle events
    ...
}
Veritable answered 10/3, 2015 at 19:37 Comment(0)
H
10

I don't think it's entirely accurate to say that "an RTOS task must be an infinite loop". I think a more correct statement is that "for many RTOS, a task must not return". The reason for this is that the RTOS scheduler, which calls the task initially, is not designed to handle a return from the task. If a task did return then the RTOS scheduler may assert an error.

I can guess at a few reasons why many RTOS schedulers don't handle returns from tasks. First, an infinite loop is the most typical type of task that is implemented in embedded systems. A task that ends is much less common. Second, the RTOS scheduler may have to be more complex in order to handle returning tasks. Third, the RTOS designer may not have wanted to assume what should be done when a task returns and instead they want the task designer to call an appropriate task termination routine explicitly.

An infinite loop is not the only solution for many RTOS that don't allow tasks to return. The RTOS may provide a task termination routine that deletes the task from the task list so that it is never scheduled again. If a task calls the task termination routine then the task doesn't have to be an infinite loop and it also won't return to it's caller. (i.e., The RTOS task termination routine does not return so the task that calls it also does not return.) For example, FreeRTOS has vTaskDelete() and uC/OS-II has OSTaskDel() for deleting tasks that are not infinite loops.

An infinite loop is a common type of task in embedded systems because many embedded systems just do the same thing over and over again. Many embedded systems are unlike a PC in that they don't have a user interacting with them, starting and terminating various tasks or applications.

Heman answered 10/3, 2015 at 15:34 Comment(0)
V
5

They don't, but if a task function runs to completion, the task is terminated.

You could perhaps choose to instantiate a new run-to-completion task every time one is needed, but instantiating a task is time consuming and potentially non-deterministic, so not suited to hard real-time response. It is more efficient and responsive to have a task wait on some blocking object such as an event, semaphore or timer, so that it can respond deterministically every time it is required. On the other hand, if you have many different non-real-time tasks that only need to run occasionally, the run-to-completion pattern can save resources.

At least one task needs to run indefinitely however - if everything just stops your system will do nothing until the power is cycled or reset asserted (by a watchdog timer for example).

RTOS implementations vary, you will need to check how your RTOS handles terminating thread functions. You may need an explicit termination call to ensure resources are released by the kernel.

If you have a system that needs some form of controlled graceful shut-down, you need not code tasks as infinite loops, but have the loop exit conditionally so that the task can terminate on request, e.g;

while( (event_flags & TERMINATE) == 0 )
{
    event_flags = eventWait( WAIT_FOREVER ) ;

    // handle events
    ...
}
Veritable answered 10/3, 2015 at 19:37 Comment(0)
S
4

In normal C language implementation that come shipped along with any GPOS (General purpose Operating System) like Linux, Windows, Mac OSX, the C runtime library is responsible for initiating the task(can be called as thread/process in GPOS context) as well as acting as a collector when the task ends.

Meaning, crt (C runtime) will call main() of the task to initiate it and when the task returns with the return statement, the control is passed back to the crt of the OS.

In RTOS, although you can program using the C language, there is no specific implementation of the crt per-se. The "Startup" function (usually written in assembly) calls on to main. However, this Startup code does not have any mechanism to collect the return value of the task and hence it is required for the task to run in an infinite loop to keep the control within the task itself. If not, the CPU/MCU will not have any return address to go to.

However, the task can be ended by using the Task management API's provided by the RTOS. in which case, the control will go to the code that called the task_kill() (representational) API from the RTOS.

Salley answered 10/3, 2015 at 12:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.