Task utility services

September 11, 2017

Colin Walls-September 11, 2017

I will continue to look at the RTOS services that provide additional information about tasks or operations on them.

Task Utility Services

Some additional API calls, that appertain to tasks, include obtaining a task’s ID, checking stack space, resetting a task, obtaining information about a task and ascertaining the number of tasks in a system. Nucleus RTOS and Nucleus SE each provide four basic API calls for these operations, which I will discuss here.

Obtaining the Current Task’s ID

This service call simply returns the ID of the calling task. For Nucleus RTOS, this pointer to the currently active task control block. For Nucleus SE, it is the index (0-15) of the current task.

Nucleus RTOS Call for Current Task

Service call prototype:

NU_TASK *NU_Current_Task_Pointer(VOID);

Parameters:

None

Returns:

Pointer to the currently active task control block

NU_NULL – there is no currently active task

Nucleus SE Call for Current Task

This API call supports the key functionality of the Nucleus RTOS API.

Service call prototype:

NUSE_TASK NUSE_Task_Current(void);

Parameters:

None

Returns:

Index of the current (calling) task

Nucleus SE Implementation of Current Task

The implementation of this API call is almost trivially simple: the value of the global variable NUSE_Task_Active is returned.

Checking Available Stack Space

This service call returns the available stack space (in bytes) for the current task. This only makes sense for schedulers where each task has its own stack; i.e. not Run To Completion (RTC) with Nucleus SE.

Nucleus RTOS Call for Stack Space

Service call prototype:

UNSIGNED NU_Check_Stack(VOID);

Parameters:

None

Returns:

Number of bytes of available stack for the current task

Nucleus SE Call for Stack Space

This API call supports the basic functionality of the Nucleus RTOS API. However, in Nucleus SE, a dummy parameter is required in order to easily obtain the current stack pointer value.

Service call prototype:

U16 NUSE_Task_Check_Stack(U8 dummy);

Parameters:

dummy – any value may be provided, as it is not actually used

Returns:

Number of bytes of available stack for the current task

Implementation

The code for this call is designed to be portable

If the RTC scheduler is in use, a value of 0 is returned, as it is not possible (using code that is remotely portable) to determine the available stack space.

Otherwise, the value of the stack pointer is determined by finding the address of the dummy parameter, which would be near the top of the stack. This approach is, strictly speaking, toolkit/compiler dependent, but will usually be valid. The returned value is the difference between this value and the initial stack value, converted to bytes.

Resetting a Task

This API call restores the task to its initial, unused state. This API function is unusual, compared with “reset” API functions for other kernel objects, as, although it is a reset, it does not simply initialize the task to its start-up state (with Nucleus SE this is either NUSE_READY or an entry from NUSE_Task_Initial_State[] – see Data Structures in the next article); the task is placed into a suspended state (NUSE_PURE_SUSPEND) and needs to be resumed before it will get scheduled. This behavior is compatible with the functionality of the equivalent Nucleus RTOS API call.

Nucleus RTOS Call for Task Reset

Service call prototype:

STATUS NU_Reset_Task(NU_TASK *task, UNSIGNED argc, VOID *argv);

Parameters:

task – pointer to the task control block

argc - data element that may be used to pass information to the task

argv - pointer that may be used to pass information to the task

Returns:

NU_SUCCESS – the call was completed successfully

NU_INVALID_TASK – the task pointer is not valid

NU_NOT_TERMINATED - the specified task is not in a terminated or finished state; only tasks in a terminated or finished state can be reset

Nucleus SE Call for Task Reset

This API call supports the key functionality of the Nucleus RTOS API.

Service call prototype:

STATUS NUSE_Task_Reset(NUSE_TASK task);

Parameters:

task – the index (ID) of the task to be reset

Returns:

NUSE_SUCCESS – the call was completed successfully

NUSE_INVALID_TASK – the task index is not valid

Nucleus SE Implementation of Task Reset

The main job of the NUSE_Task_Reset() API function – after parameter checking – is to simply reinitialize all the task’s data structures:

If the task is blocked on an API call, awaiting access to a kernel object, the first requirement is to adjust the blocked task counter associated with that object. This is effected by means of an initial switch statement.

Then, the task’s data structures are initialized (mainly to zeros, except for its context block) by calling the initialization routine NUSE_Init_Task(). The operation of this function is covered in more detail in a future article, where we look at system initialization. Lastly, the task’s status is set to NUSE_PURE_SUSPEND.

Obtaining Task Information

This service call obtains a selection of information about a task. The Nucleus SE implementation differs from Nucleus PLUS in that it returns less information, as object naming, preemption option and time slice are not supported and priority would be redundant.

Nucleus RTOS Call for Obtain Task Information

Service call prototype:

STATUS NU_Task_Information(NU_TASK *task, CHAR *name, DATA_ELEMENT *task_status, UNSIGNED *scheduled_count, OPTION *priority, OPTION *preempt, UNSIGNED *time_slice, VOID **stack_base, UNSIGNED *stack_size, UNSIGNED *minimum_stack;

Parameters:

task – pointer to the task about which information is being requested

name – pointer to an 8-character destination area for the task’s name; this includes space for the null terminator

task_status – a pointer to a variable, which will receive the current value of the task status

scheduled_count – a pointer to a variable which will receive a count of the number times this task has been scheduled

priority – pointer to a variable to hold the task’s priority

preempt – pointer to a variable to hold the task’s preempt option; NU_PREEMPT indicates the task is preemptable, while NU_NO_PREEMPT indicates the task is not preemptable

time_slice – pointer to a variable to hold the task’s time slice value; a value of zero indicates that time slicing for this task is disabled

stack_base – a pointer to a variable which will receive the address of the task’s stack

stack_size – a pointer to a variable which will receive the size of the task’s

minimum_stack – pointer to a variable to hold the minimum amount of bytes left in the task’s stack

Returns:

NU_SUCCESS – the call was completed successfully

NU_INVALID_TASK – the task pointer is not valid

Nucleus SE Call for Obtain Task Information

This API call supports the key functionality of the Nucleus PLUS API.

Service call prototype:

STATUS NUSE_Task_Information(NUSE_TASK task, U8 *task_status, U16 *scheduled_count, ADDR *stack_base, U16 *stack_size);

Parameters:

task – the index of the task about which information is being requested

task_status – a pointer to a U8 variable, which will receive the current value of the task status (nothing returned if task suspend is disabled)

scheduled_count – a pointer to a U16 variable which will receive a count of the number times this task has been scheduled (nothing returned if schedule count is disabled)

stack_base – a pointer to an ADDR variable which will receive the address of the task’s stack (nothing returned if the RTC scheduler is in use)

stack_size – a pointer to a U16 variable which will receive the size of the task’s stack (nothing returned if the RTC scheduler is in use)

Returns:

NUSE_SUCCESS – the call was completed successfully

NUSE_INVALID_TASK – the task index is not valid

NUSE_INVALID_POINTER – one or more of the pointer parameters is invalid

Nucleus SE Implementation of Obtain Task Information

The implementation of this API call is quite straightforward:

The function returns the task status, taking into account the various configuration options.

Obtaining the Number of Tasks

This service call returns the number of tasks configured in the application. Whilst in Nucleus RTOS this will vary over time and the returned value will represent the current number of tasks, in Nucleus SE the value returned is set at build time and cannot change.

Nucleus RTOS Call for Number of Tasks

Service call prototype: 

UNSIGNED NU_Established_Tasks(VOID);

Parameters:

None

Returns:

The number of established (i.e. created, but not deleted) tasks in the application

Nucleus SE Call for Number of Tasks

This API call supports the key functionality of the Nucleus PLUS API.

Service call prototype:

U8 NUSE_Task_Count(void);

Parameters:

None

Returns:

The number of configured tasks in the application

Implementation

The implementation of this API call is almost trivially simple: the value of the #define symbol NUSE_TASK_NUMBER is returned.

The next article will look at the Nucleus SE data structures associated with tasks and some additional API calls that are not supported by Nucleus SE.


Colin Walls has over thirty years experience in the electronics industry, largely dedicated to embedded software. A frequent presenter at conferences and seminars and author of numerous technical articles and two books on embedded software, Colin is an embedded software technologist with Mentor Embedded [the Mentor Graphics Embedded Software Division], and is based in the UK. His regular blog is located at: http://blogs.mentor.com/colinwalls. He may be reached by email at colin_walls@mentor.com

 

Loading comments...