Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Sauermann J.Realtime operating systems.Concepts and implementation of microkernels for embedded systems.1997.pdf
Скачиваний:
29
Добавлен:
23.08.2013
Размер:
1.32 Mб
Скачать

92

4.3 Task Start-up

 

 

If currTask is not set yet (i.e. if this is the first task that is created), then a TCB for the idle task is created, and currTask is set to that TCB. For this purpose, a Task constructor without arguments is used. In view of this code, it seems more reasonable to create the idle task from the outset rather than when the first application task is created.

67if (!currTask)

68currTask = new Task();

Finally, the TCB is linked into the task chain directly after currTask (which may be the idle task, as in our example, or another task). This operation must not be interrupted, so interrupts are masked here.

70{

71os::INT_MASK old_INT_MASK = os::set_INT_MASK(os::NO_INTS);

72next = currTask->next;

73currTask->next = this;

74os::set_INT_MASK(old_INT_MASK);

75}

76}

The TCB of the newly created task is in a state as if it were put in state STARTED just before executing the first instruction of its main function.

4.3.3 Task Activation

After creating a number of tasks, these tasks need to be activated. This is done by changing the tasks’ state from STARTED to RUN.

1 // Task.cc

...

78void main()

79{

...

85for (Task * t = Task::currTask->next; t != Task::currTask; t = t->next)

86t->TaskStatus &= ~Task::STARTED;

If an application task (rather than the idle task) creates new tasks, it should activate the tasks after creating them in a similar way.

4.3.4 Task Deletion

If a task terminates, its TCB still exists. Deleting TCBs largely depends on the actual application and requires great care. Since TCBs have been allocated with the new operator, they need to be deleted with the delete operator. Also, if the TaskIDs table is used for a task (which is probably not the case for dynamically created tasks), the Task pointer needs to be removed from the table as well. In addition, it must be assured that no other task maintains a pointer to the deleted

4. Bootstrap

93

 

 

task. Finally, use of the delete operator requires use of the malloc package, in contrast to the simple allocation mechanism we used by default.

An alternative to deleting tasks (which is likely to be a risk due to memory management as discussed in Section 3.9) is to provide a pool of static tasks which put themselves in a queue when they are idle. A task requiring a dynamic task would get such a task out of the queue and send a message containing a function to be performed to it. ??? Hä ??? This leads to structures similar to those discussed for the serial router in Section 3.7. In principle, static TCB can be used instead of the new operator for TCBs. The reason why we used new rather than static TCBs has historical reasons. The first application for which our kernel was used had a DIP switch that selected one of several applications. The kernel was the same for all applications, and the actual application was selected in setupApplicationTasks() by starting different tasks depending on the DIP switch setting. Static TCB allocation would have wasted RAM for those tasks not used for a particular DIP switch setting, while allocation by new used only those TCBs actually required, thus saving a significant amount of RAM.