Tasks in GeMRTOS #
A task in GeMRTOS is defined as a unit of execution. The main components of a task implementation are:
- GS_TCB: this is a control block that stores the information required for task management.
- task code: this is the executable code, loaded into the system memory, that implements a task function when it is executed by a processor. Task code is implemented a subroutine function.
- task stack: this is data storage to preserve the status of a suspended task in order to resume it properly and store subroutine data. The task stack memory is reserved when the task is created. The amount of memory assigned to the task stack is defined by default.
Types of GeMRTOS tasks #
The following are the type of tasks in GeMRTOS, but more can be defined:
G_TCBType_UCOS
The G_TCBType_UCOS task type makes the task code to be executed just once. The task must be released once again for another execution if the task code does not contain an infinite loop. Initialization tasks may be implemented as a G_TCBType_UCOS task type without infinite loop in the task code. G_TCBType_UCOS tasks are often implemented as an infinite loop to keep them running. When a task with an infinite loop is executed, it will take as much processor time as possible. It is possible to use different strategies to prevent one or many system tasks from being overly greedy about processor time and starving the others:
- Assigning lowest priorities to tasks: in this way, infinite-loop tasks will be executed only when the highest priority tasks are not requiring for execution.
- Suspending the task until an event: the task is suspended inside the infinite loop, waiting for an event. The events may be timed events (to execute the task regularly) or trigger events (such as waiting for an interrupt).
- Reducing the task priority: the task priority may be reduced inside the infinite loop to let the new higher-priority task be executed. This tactic should be implemented in all the infinite-loop tasks of the scheduling list to dynamically preserve a valid relationship among the system task priorities.
- Defining a round-robin scheduling mechanism in the scheduling list: a round-robin mechanism will execute each task during a certain interval, granting the processor access to each task in the scheduling list.
G_TCBType_PERIODIC
The G_TCBType_PERIODIC task type makes the task code to be executed periodically. The period of the task is configured when the type is specified. The period of the task and the initial offset determines the future releases times of the task. If previous invocation of the task does not completes, then the previous invocation may be defined to be aborted or the next release skipped. Periodic tasks are useful to meet Nyquist and Shannon theorems in cyber-physical applications. However, if no scheduling analysis is performed, the system may became oversaturated and the deadlines missed.
G_TCBType_ISR
The G_TCBType_ISR task type determines that the task is associated with a trigger resource. The G_TCBType_ISR type of the task should be set after the task is created using the gu_trigger_register_task function.
G_TCBType_IDLE
The G_TCBType_IDLE task type determines the task that a processor executes when no task requires for execution. The IDLE task is a GeMRTOS system task and there is one for each system processor. By default, the G_TCBType_IDLE task turns the processor into sleep mode in order to save energy and reduce the system bus utilization.
Main task related functions #
Creating and initializing a task #
A task can easily be created using:
void * gu_GetTask (void * TaskCode, void * p_arg )
The gu_GetTask function creates a task with all the default assignments and returns a pointer to a GS_TCB structure of the new task. All the parameters of the task may be determining by changing the default assignments prior to task creation and most of them may be change after task creation through task related functions. The gu_GetTask function requieres only two parameters: (1) a pointer to the function subroutine that implements the task code (i.e. it is the name of the function), and (2) an argument to be passed each time that the task is invoked. The task is created with the following default values:
- Type: defined in the G_TASK_TYPE_DEFAULT parameter, set with the gu_Set_Default_Task_Type() function. After creation, type parameter of the task may be modified with: (1) the gu_trigger_register_task() function for triggerable task, or (2) gu_SetTaskType() function.
- Ready Priority: defined in the G_TASK_PRIORITY_DEFAULT parameter, set with the gu_Set_Default_Task_Priority() function. After creation, ready priority parameter may be set with the gu_SetTaskReadyPriority() function.
- Run Priority: defined in the G_TASK_PRIORITY_DEFAULT parameter, set with the gu_Set_Default_Task_Priority() function. After creation, run priority parameter may be set with the gu_SetTaskRunPriority() function.
- Deadline: defined in the G_TASK_PERIOD_DEFAULT parameter, set with the gu_Set_Default_Task_Period() function. After creation, deadline parameter may be set with the gu_SetTaskDeadline() function.
- Period: defined in the G_TASK_PERIOD_DEFAULT parameter, set with the gu_Set_Default_Task_Period() function. After creation, period parameter may be set with the gu_SetTaskPeriod() function.
- Scheduling list: defined in the G_TASK_LCB_DEFAULT parameter, set with the gu_Set_Default_Task_List() function. After creation, scheduling list parameter may be set with the gu_SetTaskList() function.
- Abort when invoked: set to G_TRUE by default. By default, task is aborted when it is released before completion. After creation, abort when invoked parameter may be set with the gu_SetTaskAbortwhenDeadline() function.
The task is created with the following paramenters:
TaskCode it is a pointer to the beginning of the task code. It is the name of the function that implements the task code.
p_arg it is a pointer that it is passed to the task function each time it is invoked. It is defined as a "void *" type, but it may be casted for different types inside the task code.
- Returns
- The gu_GetTask function returns a pointer to the GS_TCB structure of the task created. This value should be used to reference all the function called related to the task created.
Starting task execution #
A task is schedule to start execution using:
INT32 gu_StartTaskwithOffset (struct gs_tcb * ptcb, unsigned int hours, unsigned int minutes, unsigned int seconds, unsigned int ms )
The gu_StartTaskwithOffset function sets a previously created task for execution. The gu_StartTaskwithOffset function allows defingning an offset for the first time execution of the task. This offset helps to schedule the starting time of the tasks.
The task is started with the following paramenters:
ptcb It is a pointer to the GS_TCB structure of the task (returned by the gu_GetTask() function when task was created).
hours Number of hours of the starting offset.
minutes Number of minutes of the starting offset.
seconds Number of seconds of the starting offset.
ms Number of miliseconds of the starting offset.
- Returns
- The gu_StartTaskwithOffset function returns G_TRUE when successful.
Suspending the execution of a task for a certain interval #
A task can be suspended for a certain interval using:
INT32 gu_TASK_Sleep (INT32 hours, INT32 minutes, INT32 seconds, INT32 ms )
The gu_TASK_Sleep function suspends the execution of the current task for a defined interval. This function may be used inside of the infinite loop of a run-once task, in order to produce a repetitive execution of the code in the loop.
The task is suspended with the following paramenters:
hours Number of hours of the suspension interval.
minutes Number of minutes of the suspension interval.
seconds Number of seconds of the suspension interval.
ms Number of miliseconds of the suspension interval.
- Returns
- The gu_TASK_Sleep function returns G_TRUE.