Advertisement

Pipes: utility services and data structures

November 13, 2018

Colin Walls-November 13, 2018

This article continues our look at pipes.

Pipe Utility Services

Nucleus RTOS has four API calls which provide utility functions associated with pipes: reset pipe, return information about a pipe, return number of pipes in the application and return pointers to all pipes in the application. The first three of these are implemented in Nucleus SE.

Resetting a Pipe

This API call restores the pipe to its initial, unused state. Any messages stored in the pipe are lost. Any tasks which were suspended on the pipe are resumed and receive a return code of NUSE_PIPE_WAS_RESET.

Nucleus RTOS API Call for Resetting a Pipe

Service call prototype:

STATUS NU_Reset_Pipe(NU_PIPE *pipe;

Parameters:

pipe – pointer to user-defined pipe control block

Returns:

NU_SUCCESS – the call was completed successfully
NU_INVALID_PIPE – the pipe pointer is not valid

Nucleus SE API Call for Resetting a Pipe

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

Service call prototype:

STATUS NUSE_Pipe_Reset(NUSE_PIPE pipe);

Parameters:

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

Returns:

NUSE_SUCCESS – the call was completed successfully
NUSE_INVALID_PIPE – the pipe index is not valid

Nucleus SE Implementation of Pipe Reset

The initial part of the code of the NUSE_Pipe_Reset() API function – after parameter checking – is quite straightforward. The head and tail indexes and the pipe’s message count are all set to zero.

When blocking is enabled, additional code takes care of waking up any suspended tasks, thus:

while (NUSE_Pipe_Blocking_Count[pipe] != 0)
{
   U8 index;           /* check whether any tasks are blocked */
                                              /* on this pipe */
   for (index=0; index<NUSE_TASK_NUMBER; index++)
   {
      if ((LONIB(NUSE_Task_Status[index]) == NUSE_PIPE_SUSPEND)
         && (HINIB(NUSE_Task_Status[index]) == pipe))
      {
         NUSE_Task_Blocking_Return[index] = NUSE_PIPE_RESET;
         NUSE_Task_Status[index] = NUSE_READY;
         break;
      }
   }
   NUSE_Pipe_Blocking_Count[pipe]--;
}
#if NUSE_SCHEDULER_TYPE == NUSE_PRIORITY_SCHEDULER
   NUSE_Reschedule(NUSE_NO_TASK);
#endif


Each task suspended on the pipe is marked as “ready” with a suspend return code of NUSE_PIPE_WAS_RESET. After this process is complete, if the Priority scheduler is in use, a call is made to NUSE_Reschedule(), as one or more higher priority tasks may have been readied and needs to be allowed to run.

Pipe Information

This service call obtains a selection of information about a pipe. The Nucleus SE implementation differs from Nucleus RTOS in that it returns less information, as object naming, variable message size and suspend ordering are not supported and task suspend may not be enabled.

Nucleus RTOS API Call for Pipe Information

Service call prototype:

STATUS NU_Pipe_Information(NU_PIPE *pipe, CHAR *name,
VOID **start_address,UNSIGNED *pipe_size, UNSIGNED *available,
UNSIGNED *messages, OPTION *message_type, UNSIGNED *message_size,
OPTION *suspend_type, UNSIGNED *tasks_waiting,

NU_TASK **first_task);

Parameters:

pipe – pointer to the user-supplied pipe control block
name – pointer to an 8-character destination area for the message-pipe’s name
start_address – a pointer to a pointer, which will receive the address of the start of the pipe’s data area
pipe_size – a pointer to a variable for holding the total number of bytes in the pipe
available – a pointer to a variable for holding the number of available bytes in the pipe
messages – a pointer to a variable for holding the number of messages currently in the pipe
message_type – pointer to a variable for holding the type of messages supported by the pipe; valid message types are NU_FIXED_SIZE and NU_ VARIABLE_SIZE
message_size – pointer to a variable for holding the number of bytes in each pipe message; if the pipe supports variable-length messages, this number is the maximum message size
suspend_type – pointer to a variable for holding the task suspend type. Valid task suspend types are NU_FIFO and NU_PRIORITY
tasks_waiting – a pointer to a variable which will receive the number of tasks suspended on this pipe
first_task – a pointer to a task pointer; the pointer of the first suspended task is placed in this task pointer

Returns:

NU_SUCCESS – the call was completed successfully
NU_INVALID_PIPE – the pipe pointer is not valid

Nucleus SE API Call for Pipe Information

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

Service call prototype:

STATUS NUSE_Pipe_Information(NUSE_PIPE pipe,
ADDR *start_address, U8 *pipe_size, U8 *available, U8 *messages,
U8 *message_size, U8 *tasks_waiting, NUSE_TASK *first_task);

Parameters:

pipe – the index of the pipe about which information is being requested
start_address – a pointer to a variable of type ADDR, which will receive the address of the start of the pipe’s data area
pipe_size – a pointer to a variable of type U8, which will receive the total number of messages for which the pipe has capacity
available – a pointer to a variable of type U8, which will receive the number of messages for which the pipe has currently remaining capacity
messages – a pointer to a variable of type U8, which will receive the number of messages currently in the pipe
message size – a pointer to a variable of type U8, which will receive the size of messages handled by this pipe
tasks_waiting – a pointer to a variable which will receive the number of tasks suspended on this pipe (nothing returned if task suspend is disabled)
first_task – a pointer to a variable of type NUSE_TASK which will receive the index of the first suspended task (nothing returned if task suspend is disabled)

Returns:

NUSE_SUCCESS – the call was completed successfully
NUSE_INVALID_PIPE – the pipe index is not valid
NUSE_INVALID_POINTER – one or more of the pointer parameters is invalid

Nucleus SE Implementation of Pipe Information

The implementation of this API call is quite straightforward:

*start_address = NUSE_Pipe_Data[pipe];
*pipe_size = NUSE_Pipe_Size[pipe];
*available = NUSE_Pipe_Size[pipe] - NUSE_Pipe_Items[pipe];
*messages = NUSE_Pipe_Items[pipe];
*message_size = NUSE_Pipe_Message_Size[pipe];
#if NUSE_BLOCKING_ENABLE
   *tasks_waiting = NUSE_Pipe_Blocking_Count[pipe];
   if (NUSE_Pipe_Blocking_Count[pipe] != 0)
   {
      U8 index;
      for (index=0; index<NUSE_TASK_NUMBER; index++)
      {
         if ((LONIB(NUSE_Task_Status[index]) == NUSE_PIPE_SUSPEND)
              && (HINIB(NUSE_Task_Status[index]) == pipe))
         {
            *first_task = index;
            break;
         }
      }
   }
   else
   {
      *first_task = 0;
   }
#else
   *tasks_waiting = 0;
   *first_task = 0;
#endif


The function returns the pipe status. Then, if blocking API calls is enabled, the number of waiting tasks and the index of the first one are returned (otherwise these two parameters are set to 0).

Obtaining the Number of Pipes

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

Nucleus RTOS API Call for Pipe Count

Service call prototype:

UNSIGNED NU_Established_Pipes(VOID);

Parameters:

None

Returns:

The number of created pipes in the system.

Nucleus SE API Call for Pipe Count

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

Service call prototype:

U8 NUSE_Pipe_Count(void);

Parameters:

None

Returns:

The number of configured pipes in the application

Nucleus SE Implementation of Pipe Count

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

Continue reading on page two >>

 

 

< Previous
Page 1 of 2
Next >

Loading comments...

Most Commented