Advertisement

Queues: utility services and data structures

September 18, 2018

Colin Walls-September 18, 2018

This article continues our look at queues.

Queue Utility Services

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

Resetting a Queue

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

Nucleus RTOS API Call for Resetting a Queue

Service call prototype:

STATUS NU_Reset_Queue(NU_QUEUE *queue;

Parameters:

queue – pointer to user-define queue control block

Returns:

NU_SUCCESS – the call was completed successfully
NU_INVALID_QUEUE – the queue pointer is not valid

Nucleus SE API Call for Resetting a Queue

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

Service call prototype:

STATUS NUSE_Queue_Reset(NUSE_QUEUE queue);

Parameters:

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

Returns:

NUSE_SUCCESS – the call was completed successfully
NUSE_INVALID_QUEUE – the queue index is not valid

Nucleus SE Implementation of Queue Reset

The initial part of the code of the NUSE_Queue_Reset() API function – after parameter checking – is quite straightforward. The head and tail indexes and the queue’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_Queue_Blocking_Count[queue] != 0)
{
   U8 index;             /* check whether any tasks are blocked */
                         /* on this queue */
   for (index=0; index<NUSE_TASK_NUMBER; index++)
   {
      if ((LONIB(NUSE_Task_Status[index]) == NUSE_QUEUE_SUSPEND)
           && (HINIB(NUSE_Task_Status[index]) == queue))
      {
         NUSE_Task_Blocking_Return[index] = NUSE_QUEUE_WAS_RESET;
         NUSE_Task_Status[index] = NUSE_READY;
         break;
      }
   }
   NUSE_Queue_Blocking_Count[queue]--;
}
#if NUSE_SCHEDULER_TYPE == NUSE_PRIORITY_SCHEDULER
   NUSE_Reschedule(NUSE_NO_TASK);
#endif


Each task suspended on the queue is marked as “ready” with a suspend return code of NUSE_QUEUE_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.

Queue Information

This service call obtains a selection of information about a queue. 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 Queue Information

Service call prototype:

STATUS NU_Queue_Information(NU_QUEUE *queue, CHAR *name,
VOID **start_address,UNSIGNED *queue_size, UNSIGNED *available,
UNSIGNED *messages, OPTION *message_type,
UNSIGNED *message_size, OPTION *suspend_type,
UNSIGNED *tasks_waiting, 
NU_TASK **first_task);

Parameters:

queue – pointer to the user-supplied queue control block
name – pointer to an 8-character destination area for the message-queue’s name
start_address – a pointer to a pointer, which will receive the address of the start of the queue’s data area
queue_size – a pointer to a variable for holding the total number of UNSIGNED data elements in the queue
available – a pointer to a variable for holding the number of available UNSIGNED data elements in the queue
messages – a pointer to a variable for holding the number of messages currently in the queue
message_type – pointer to a variable for holding the type of messages supported by the queue; valid message types are NU_FIXED_SIZE and NU_ VARIABLE_SIZE
message_size – pointer to a variable for holding the number of UNSIGNED data elements in each queue message; if the queue 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 queue
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_QUEUE – the queue pointer is not valid

Nucleus SE API Call for Queue Information

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

Service call prototype:

STATUS NUSE_Queue_Information(NUSE_QUEUE queue,
ADDR *start_address, U8 *queue_size, U8 *available, U8 *messages, U8 *tasks_waiting, NUSE_TASK *first_task);

Parameters:

queue – the index of the queue 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 queue’s data area
queue_size – a pointer to a variable of type U8, which will receive the total number of messages for which the queue has capacity
available – a pointer to a variable of type U8, which will receive the number of messages for which the queue has currently remaining capacity
messages – a pointer to a variable of type U8, which will receive the number of messages currently in the queue
tasks_waiting – a pointer to a variable which will receive the number of tasks suspended on this queue (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_QUEUE – the queue index is not valid
NUSE_INVALID_POINTER – one or more of the pointer parameters is invalid

Nucleus SE Implementation of Queue Information

The implementation of this API call is quite straightforward:

*start_address = NUSE_Queue_Data[queue];
*queue_size = NUSE_Queue_Size[queue];
*available = NUSE_Queue_Size[queue] - NUSE_Queue_Items[queue];
*messages = NUSE_Queue_Items[queue];
#if NUSE_BLOCKING_ENABLE
   *tasks_waiting = NUSE_Queue_Blocking_Count[queue];
   if (NUSE_Queue_Blocking_Count[queue] != 0)
   {
      U8 index;
      for (index=0; index<NUSE_TASK_NUMBER; index++)
      {
         if ((LONIB(NUSE_Task_Status[index]) ==
            NUSE_QUEUE_SUSPEND)
            && (HINIB(NUSE_Task_Status[index]) == queue))
         {
            *first_task = index;
            break;
         }
      }
   }
   else
   {
      *first_task = 0;
   }
   #else
      *tasks_waiting = 0;
      *first_task = 0;
   #endif


The function returns the queue 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 Queues

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

Nucleus RTOS API Call for Queue Count

Service call prototype:

UNSIGNED NU_Established_Queues(VOID);

Parameters:

None

Returns:

The number of created queues in the system.

Nucleus SE API Call for Queue Count

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

Service call prototype:

U8 NUSE_Queue_Count(void);
 

Parameters:

None

Returns:

The number of configured queues in the application

Nucleus SE Implementation of Queue Count

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

Continue reading on page two, Data Structures >>

 

< Previous
Page 1 of 2
Next >

Loading comments...

Most Commented