Advertisement

Mailboxes: utility services and data structures

July 17, 2018

Colin Walls-July 17, 2018

This article continues the look at mailboxes discussed in a previous article in this RTOS Revealed series.

Mailbox Utility Services

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

Resetting a Mailbox

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

Nucleus RTOS API Call for Resetting a Mailbox

Service call prototype:

STATUS NU_Reset_Mailbox(NU_MAILBOX *mailbox);

Parameters:

mailbox – pointer to the user-supplied mailbox control block

Returns:

NU_SUCCESS – the call was completed successfully
NU_INVALID_MAILBOX – the mailbox pointer is not valid

Nucleus SE API Call for Resetting a Mailbox

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

Service call prototype:

STATUS NUSE_Mailbox_Reset(NUSE_MAILBOX mailbox);

Parameters:

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

Returns:

NUSE_SUCCESS – the call was completed successfully
NUSE_INVALID_MAILBOX – the mailbox index is not valid

Nucleus SE Implementation of Mailbox Reset

The bulk of the code of the NUSE_Mailbox_Reset() API function – after parameter checking – is selected by conditional compilation, dependent on whether support for blocking (task suspend) API calls is enabled. We will look at the two variants separately here.

If blocking is not enabled, the API function code is almost trivial. The mailbox is marked as unused by setting its entry in NUSE_Mailbox_Status[] to FALSE.

When blocking is enabled, the code becomes more complex:

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


Initially the mailbox is marked as empty.

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

Mailbox Information

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

Nucleus RTOS API Call for Mailbox Information

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

Service call prototype:

STATUS NU_Mailbox_Information(NU_MAILBOX *mailbox, CHAR *name, OPTION *suspend_type, DATA_ELEMENT *message_present, UNSIGNED *tasks_waiting, NU_TASK **first_task);

Parameters:

mailbox – pointer to the user-supplied mailbox control block
name – pointer to an 8-character destination area for the mailbox’s name. This includes space for a null terminator
suspend_type – pointer to a variable for holding the task suspend type. Valid task suspend types are NU_FIFO and NU_PRIORITY
message_present – a pointer to a variable, which will receive a value of NU_TRUE or NU_FALSE depending on whether the mailbox is full or not
tasks_waiting – a pointer to a variable which will receive the number of tasks suspended on this mailbox
first_task – a pointer to a task pointer which will receive the pointer to the first suspended task

Returns:

NU_SUCCESS – the call was completed successfully
NUSE_INVALID_MAILBOX – the mailbox pointer is not valid

Nucleus SE API Call for Mailbox Information

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

Service call prototype:

STATUS NUSE_Mailbox_Information(NUSE_MAILBOX mailbox, U8 *message_present, U8 *tasks_waiting, NUSE_TASK *first_task);

Parameters:

mailbox – the index of the mailbox about which information is being requested
message_present – a pointer to a variable, which will receive a value of TRUE or FALSE depending on whether the mailbox is full or not
tasks_waiting – a pointer to a variable which will receive the number of tasks suspended on this mailbox (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_MAILBOX – the mailbox index is not valid
NUSE_INVALID_POINTER – one or more of the pointer parameters is invalid

Nucleus SE Implementation of Mailbox Information

The implementation of this API call is quite straightforward:

*message_present = NUSE_Mailbox_Status[mailbox];
#if NUSE_BLOCKING_ENABLE
   *tasks_waiting = NUSE_Mailbox_Blocking_Count[mailbox];
   if (NUSE_Mailbox_Blocking_Count[mailbox] != 0)
   {
      U8 index;
      for (index=0; index<NUSE_TASK_NUMBER; index++)
      {
         if ((LONIB(NUSE_Task_Status[index]) ==
            NUSE_MAILBOX_SUSPEND)
            && (HINIB(NUSE_Task_Status[index]) == mailbox))
         {
            *first_task = index;
            break;
         }
      }
   }
   else
   {
      *first_task = 0;
   }
#else
   *tasks_waiting = 0;
   *first_task = 0;
#endif
return NUSE_SUCCESS;


The function returns the mailbox 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 Mailboxes

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

Nucleus RTOS API Call for Mailbox Count

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

Service call prototype:

UNSIGNED NU_Established_Mailboxes(VOID);

Parameters:

None

Returns:

The number of created mailboxes in the application

Nucleus SE API Call for Mailbox Count

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

Service call prototype:

U8 NUSE_Mailbox_Count(void);

Parameters:

None 

Returns:

The number of configured mailboxes in the application

Nucleus SE Implementation of Mailbox Count

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

Continue reading on page two >>

 

< Previous
Page 1 of 2
Next >

Loading comments...