How to use Name Server API

The following description and code snippets show how to use the Name Server API to register, query and re-register entries in the Name Server database.

Name Server ID (name)

Name Server IDs are the keys to the Name Server database. They are implemented as 32-bit values, typically not used as one number but rather four 8-byte values (quadruplet), allowing some categorization within the keys.

Code 1. Example definition of Name Server IDs.
#define LedClientA_MID_NAMESERVERID         ((PxNameId_t){{2, 2, 0, 1}})
#define LedServer_MID_NAMESERVERID          ((PxNameId_t){{2, 2, 0, 2}})
#define LedClientB_MID_NAMESERVERID         ((PxNameId_t){{2, 2, 0, 3}})

Register

PxError_t PxNameRegister(PxNameId_t name, PxSize_t info_length, void const *info);

Parameters:

  • name - Name Server ID (key to the database) associated with the entry

  • info_length - length of the data to be stored in bytes

  • info - address of the data to be stored

Error codes:

  • PXERR_NAME_NOT_INITIALIZED - Name Server not yet initialized

  • PXERR_NAME_DEFINED - The name is already registered

  • PXERR_NAME_MEM - Not enough memory available

Description:

PxNameRegister() stores the information passed in info (value) as a new entry corresponding to name (key) in the database.

This code shows the LedServer task registering its ID (variable myID) in the Name Server so other tasks can query it and then send requests for manipulating with the LED using PXROS-HR interprocess communication.

Code 2. Example of registering a task ID to the Name Server
void LedServer_taskFunc(PxTask_t myID, PxMbx_t myMailbox, PxEvents_t myActEvents)
{
    ...

    /* Register LedServer Task in NameServer so that other tasks can query it */
    PxError_t error = PxNameRegister(LedServer_MID_NAMESERVERID, sizeof(PxTask_t), &myID);
    if (error != PXERR_NOERROR)
        PxPanic();

Query

PxError_t PxNameQuery(PxNameId_t name, PxSize_t buffer_length, void  *buffer, PxSize_t *info_length);

Parameters:

  • name - Name Server ID (key to the database) associated with the entry

  • buffer_length - length of the buffer to store the information

  • *buffer - address of the buffer to store the information

  • *info_length - the actual length of the returned entry on return (if 0 is provided, the parameter is unused)

Error codes:

  • PXERR_NAME_NOT_INITIALIZED - Name Server not yet initialized

  • PXERR_NAME_UNDEFINED - The name was not registered

  • PXERR_NAME_BUFOVERFLOW - buffer is too short to store the result

Description:

The query for the value from the Name Server requires synchronization, so the value must be registered first, and then it can be obtained. It may happen that the task having a lower priority will register the value, and then tasks with a higher priority will try to query it. However, the higher priority tasks will execute the query sooner than the registering task registers it. The synchronization must be achieved for the correct behaviour of the application.

The following code shows how to use PxNameQuery() in order to get the LedServer ID that was registered by the code snippet mentioned above.

Code 3. Simple use of PxNameQuery
/* Retrieve LedServer taskID and writtenLength from the NameServer */
PxTask_t LedServerID = PxTaskIdInvalidate();
PxSize_t writtenLength;

PxError_t error = PxNameQuery (LedServer_MID_NAMESERVERID, sizeof(PxTask_t), &LedServerID, &writtenLength);
if (error != PXERR_NOERROR)
{
    if (error == PXERR_NAME_UNDEFINED)
    {
        /* The ID is not registered in the Name Server database */
    }
    else if (error == PXERR_NAME_BUFOVERFLOW)
    {
        /* Provided buffer is too short to store the result */
    }
    else
        PxPanic();
}

Re-register

PxError_t PxNameReRegister(PxNameId_t name, PxSize_t info_length, void const *info);

Parameters:

  • name - Name Server ID (key to the database) associated with the entry

  • info_length - length of the data to be stored in bytes

  • info - address of the data to be stored

Error codes:

  • PXERR_NAME_NOT_INITIALIZED - Name Server not yet initialized

  • PXERR_NAME_UNDEFINED - The name to re-register is not registered (undefined)

  • PXERR_NAME_MEM - Not enough memory available

Description:

PxNameReRegister() overwrites an existing database entry with the information passed in info. If info_length is 0, the entry is deleted.

When the length of the entry is the same as the previous, new data are simply rewritten. If the length does not match, the new block of info_length is taken from the memory class and filled with the info. The old block is returned to the memory class. Due to the return of the blocks, the memory class is being fragmented.

The current version does not try to limit fragmentation by special algorithms. Thus, the server should not be used if frequent insertion/removal of differently sized information is necessary. All storage is taken from the Name Server’s memory class. Thus, fragmentation damages can be localized to the Name Server. The problem can be alleviated if, for this memory class, the "PXMcVarsizedAdjusted" type is used (this works quite well provided that adjustment is chosen adequately and sufficient storage is available).

Code 4. Example of re-registering LedServer task ID in the Name Server
void LedServer_taskFunc(PxTask_t myID, PxMbx_t myMailbox, PxEvents_t myActEvents)
{
    ...

    /* Re-register task in Name server */
    PxError_t error = PxNameReRegister(LedServer_MID_NAMESERVERID, sizeof(PxTask_t), &myID);
    if ( error != PXERR_NOERROR)
        PxPanic();
Code 5. Example of deleting (unregistering) LedServer task ID in the Name Server
void LedServer_taskFunc(PxTask_t myID, PxMbx_t myMailbox, PxEvents_t myActEvents)
{
    ...

    /* Unregister LedServer task from Name server */
    PxError_t error = PxNameReRegister(LedServer_MID_NAMESERVERID, 0, 0);
    if (error != PXERR_NOERROR)
        PxPanic();

Typical usage

Name Server is typically used to obtain object handles (like task ID), so the PXROS-HR interprocess communication (messages, events) can be used. As far as PXROS-HR does not provide any broadcast communication, the Name Server can also be used to share data across multiple tasks. The synchronization is guaranteed by the Name Server being a dedicated task. This implementation ensures that it is the only entity that processes requests and manipulates the database.