7

Partition memory

Abstract

Partition memory is a means to create dynamic data storage supported by Nucleus SE. It provides a means to handle dynamic memory in a way that is compatible with developing a real-time system. In this chapter, the operation of partition memory is outlined, with details of all the relevant application program interfaces. The implementation of partition memory in Nucleus SE is also detailed.

Keywords

RTOS; Nucleus; partition memory; dynamic memory; malloc

Memory partitions were introduced in Chapter 3, RTOS Services and Facilities, where a comparison with the standard C malloc() function was made. A partition is a memory area, obtained from a partition pool. This offers a flexible means for tasks to obtain and release data storage in a deterministic and reliable fashion.

Using partitions

In Nucleus SE, partition pools are configured at build time. There may be a maximum of 16 partition pools configured for an application. If no partition pools are configured, no data structures or service call code appertaining to partition pools are included in the application.

A partition pool is simply an area of memory, which is divided into a specific number of fixed-sized partitions. The user has complete control over the size and number of partitions in each pool. Tasks may request to be allocated memory partitions and receive a pointer to the storage area. It is the task’s responsibility not to write data outside of the partition. The partition may be deallocated by any task by passing the pointer to an application program interface (API) function. Requesting the allocation of a partition, when no more are available, may result in an error or task suspension, depending on options selected in the API call and the Nucleus SE configuration.

Configuring memory partitions

Number of partition pools

As with most aspects of Nucleus SE, the configuration of partition pools is primarily controlled by #define statements in nuse_config.h. The key setting is NUSE_PARTITION_POOL_NUMBER, which determines how many partition pools are configured for the application. The default setting is 0 (i.e., no partition pools are in use) and you can set it to any value up to 16. An erroneous value will result in a compile time error, which is generated by a test in nuse_config_check.h (this is included into nuse_config.c and hence compiled with this module), resulting in a #error statement being compiled.

Choosing a nonzero value is the “master enable” for partition pools. This results in some data structures being defined and sized accordingly. Data structures in ROM require initializing to suitable values that characterize each partition pool. There is more information on data structures later in this chapter. It also activates the API enabling settings.

API enables

Every API function (service call) in Nucleus SE has an enabling #define symbol in nuse_config.h. For partition pools, these are:

 NUSE_PARTITION_ALLOCATE

 NUSE_PARTITION_DEALLOCATE

 NUSE_PARTITION_POOL_INFORMATION

 NUSE_PARTITION_POOL_COUNT

By default, all of these are set to FALSE, thus disabling each service call and inhibiting the inclusion of any implementation code. To configure partition pools for an application, you need to select the API calls that you want to use and set their enabling symbols to TRUE.

Here is an extract from the default nuse_config.h file:

 /*** Partition pools ***/

 #define NUSE_PARTITION_POOL_NUMBER   0   /* Number of partition pools

              in the system - 0–16 */

 #define NUSE_PARTITION_ALLOCATE   FALSE   /* Service call   enabler */

 #define NUSE_PARTITION_DEALLOCATE  FALSE  /* Service call   enabler */

 #define NUSE_PARTITION_POOL_INFORMATION FALSE  /* Service   call enabler */

 #define NUSE_PARTITION_POOL_COUNT  FALSE  /* Service call   enabler */

A compile time error will result if a partition pool API function is enabled and no partition pools are configured (except for NUSE_Partition_Pool_Count(), which is always permitted). If your code uses an API call, which has not been enabled, a link time error will result, as no implementation code will have been included in the application.

Partition pool service calls

Nucleus RTOS supports seven service calls, which appertain to partition pools that provide the following functionality:

 Allocate a partition: NU_Allocate_Partition(). Implemented by NUSE_Partition_Allocate() in Nucleus SE.

 Deallocate a partition: NU_Deallocate_Partition(). Implemented by NUSE_Partition_Deallocate() in Nucleus SE.

 Provide information about a specified partition pool: NU_Partition_Pool_Information(). Implemented by NUSE_Partition_Pool_Information() in Nucleus SE.

 Return a count of how many partition pools are (currently) configured for the application: NU_Established_Partition_Pools(). Implemented by NUSE_Partition_Pool_Count() in Nucleus SE.

 Add a new partition pool to the application (create): NU_Create_Partition_Pool(). Not implemented in Nucleus SE.

 Remove a partition pool from the application (delete): NU_Delete_Partition_Pool(). Not implemented in Nucleus SE.

 Return pointers to all the partition pools (currently) in the application: NU_Partition_Pool_Pointers(). Not implemented in Nucleus SE.

The implementation of each of these service calls is examined in detail.

It may be noted that no reset function is provided (in either Nucleus RTOS or Nucleus SE). This is intentional. It is very common practice for one task to allocate a partition and pass a pointer to another task (which will probably deallocate it later). If a partition pool were to be reset, all the partitions would be marked as unused, but there is no means of tracking and notifying all tasks that may be using the partitions.

Partition allocation and deallocation services

The fundamental operations, which can be performed on a partition pool, are allocating a partition (i.e., marking a partition as used and returning its address) from it and deallocating a partition (i.e., marking a partition as unused). Nucleus RTOS and Nucleus SE each provide two basic API calls for these operations, which will be discussed here.

Allocating a partition

The Nucleus RTOS API call for allocating a partition is very flexible, enabling you to suspend indefinitely, or with a timeout, if the operation cannot be completed immediately; that is, you try to allocate a partition from a pool in which all partitions are currently allocated. Nucleus SE provides the same service, except task suspend is optional and timeout is not implemented.

Nucleus RTOS API call for partition allocation

Service call prototype:

  STATUS NU_Allocate_Partition(

  NU_PARTITION_POOL *pool,

  VOID **return_pointer,

  UNSIGNED (suspend);

Parameters:

 pool—pointer to the partition pool to be utilized;

 return_pointer—a pointer to a pointer that will receive the address of the allocated partition;

 suspend—specification for task suspend; may be NU_NO_SUSPEND or NU_SUSPEND or a timeout value in ticks (1–4,294,967,293).

Returns:

 NU_SUCCESS—The call was completed successfully.

 NU_NO_PARTITION—No partitions are available.

 NU_INVALID_POOL—The partition pool pointer is invalid.

 NU_INVALID_POINTER—The data return pointer is NULL.

 NU_INVALID_SUSPEND—Suspend was attempted from a nontask thread.

 NU_TIMEOUT—No partition is available even after suspending for the specified timeout period.

 NU_POOL_DELETED—Partition pool was deleted, while the task was suspended.

Nucleus SE API call for allocating

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

Service call prototype:

  STATUS NUSE_Partition_Allocate(

  NUSE_PARTITION_POOL pool,

  ADDR *return_pointer,

  U8 suspend);

Parameters:

 pool—the index (ID) of the partition pool to be utilized;

 return_pointer—a pointer to a variable of type ADDR, which will receive the address of the allocated partition;

 suspend—specification for task suspend; may be NUSE_NO_SUSPEND or NUSE_SUSPEND.

Returns:

 NUSE_SUCCESS—The call was completed successfully.

 NUSE_NO_PARTITION—No partitions are available.

 NUSE_INVALID_POOL—The partition pool index is invalid.

 NUSE_INVALID_POINTER—The data return pointer is NULL.

 NUSE_INVALID_SUSPEND—Suspend was attempted from a nontask thread or when blocking API calls were not enabled.

Nucleus SE implementation of partition allocation

The bulk of the code of the NUSE_Partition_Allocate() 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 code for this API call is quite straightforward:

if (NUSE_Partition_Pool_Partition_Number[pool]==NUSE_Partition_Pool_Partition_Used[pool])

{

 return_value=NUSE_NO_PARTITION;   /* no free partitions */
}
else
{
 /* point to status byte of 1st partition */
 ptr=(U8 *)NUSE_Partition_Pool_Data_Address[pool];
 while (*ptr!=0)   /* find an unused partition */
 {
  ptr +=NUSE_Partition_Pool_Partition_Size[pool] + 1;
 }
 *ptr=0x80 | pool; /* mark used */
        /* need pool number for deallocation */
 NUSE_Partition_Pool_Partition_Used[pool]++;
 *return_pointer=ptr + 1;
 return_value=NUSE_SUCCESS;
}

First, the availability of free partitions is checked and an error returned (NUSE_ NO_PARTITION) if there is none. The partitions are then stepped through, inspecting the first byte for a zero value (meaning unused). When this is found, an in-use flag is written, incorporating the index of the partition pool (see “Deallocating a sartition” section), and a pointer to the next byte (the start of the real data area) returned. For an explanation of the partition pool data structures, see “Data structures” section.

If blocking is enabled, the code for this API call is a little more complex:

do
{
 if (NUSE_Partition_Pool_Partition_Number[pool]==
   NUSE_Partition_Pool_Partition_Used[pool])
 {
   if (suspend==NUSE_NO_SUSPEND)
   {
     return_value=NUSE_NO_PARTITION;  /* no free partitions */
   }
   else
   {           /* block task */
     NUSE_Partition_Pool_Blocking_Count[pool]++;
     NUSE_Suspend_Task(NUSE_Task_Active, (pool << 4) |
      NUSE_PARTITION_SUSPEND);
     return_value=     NUSE_Task_Blocking_Return[NUSE_Task_Active];
     if (return_value!=NUSE_SUCCESS)
     {

      suspend=NUSE_NO_SUSPEND;

     }
   }
 }
 else
 {
   /* point to status byte of 1st partition */
   ptr=(U8 *)NUSE_Partition_Pool_Data_Address[pool];
   while ( *ptr!=0)   /* find an unused partition */
   {
     ptr +=NUSE_Partition_Pool_Partition_Size[pool] + 1;
   }
   *ptr=0x80 | pool; /* mark used */
           /* need pool number for deallocation */
   NUSE_Partition_Pool_Partition_Used[pool]++;
   *return_pointerptr + 1;
   return_value=NUSE_SUCCESS;
   suspend=NUSE_NO_SUSPEND;
 }
} while (suspend==NUSE_SUSPEND);

The code is enclosed in a do…while loop, which continues, while the parameter suspend has the value NUSE_SUSPEND.

If a partition is available, it is marked as being in use, as described earlier, and the data pointer is set up. The suspend variable is set to NUSE_NO_SUSPEND and the API call exits with NUSE_SUCCESS.

If no partitions are available and suspend is set to NUSE_NO_SUSPEND, the API call exits with NUSE_ NO_PARTITION. If suspend was set to NUSE_SUSPEND, the task is suspended. On return (i.e., when the task is woken up), if the return value is NUSE_SUCCESS, indicating that the task was woken because a partition has been deallocated, the code loops back to the top. Of course, since there is no reset API function for partition pools, this is the only possible reason for the task to be woken, but the process of checking NUSE_Task_Blocking_Return[] is retained for consistency with the handling of blocking with other object types.

Deallocating a partition

Deallocating a partition in Nucleus RTOS and Nucleus SE simply makes it available for allocation again. No check is made (or could be made) on whether any task is still using the partition; this is the responsibility of the applications programmer. Only the pointer to the data area is required in order to deallocate a partition.

Nucleus RTOS API call for partition deallocation

Service call prototype:

STATUS NU_Deallocate_Partition(VOID *partition);

Parameters:

partition—pointer to the data area (as returned by NU_Allocate_Partition()) of the partition to be deallocated.

Returns:

NU_SUCCESS—The call was completed successfully.

NU_INVALID_POINTER—The partition pointer is NULL or does not appear to point to a valid, in-use partition.

Nucleus SE API call for partition deallocation

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

Service call prototype:

STATUS NUSE_Partition_Deallocate(ADDR partition);

Parameters:

partition—pointer to the data area (as returned by NUSE_Partition_Allocate()) of the partition to be deallocated.

Returns:

NUSE_SUCCESS—The call was completed successfully.

NUSE_INVALID_POINTER—The partition pointer is NULL or does not appear to point to a valid, in-use partition.

Nucleus SE implementation of partition deallocation

Instead of being implemented in blocking and nonblocking forms, the NUSE_Partition_Deallocate() API function simply contains a conditionally compiled section that deals with task unblocking. This code implements the actual partition deallocation:

pool=*((U8*)partition-1) & 0x0f;   /* extract pool index  number */
*((U8*)partition-1)=0;      /* mark unused */
NUSE_Partition_Pool_Partition_Used[pool]--;  /* decrement   count */
return_value=NUSE_SUCCESS;

First the index of the partition pool is extracted from the partition status byte. Then, the status is set to “unused,” the usage count decremented and success reported on return.

If task blocking is enabled, this code is included to take care of waking up any tasks waiting on the partition pool:

if (NUSE_Partition_Pool_Blocking_Count[pool]!=0)
{
 U8 index;     /* check whether a task is blocked */
        /* on this partition pool */
 NUSE_Partition_Pool_Blocking_Count[pool]--;
 for (index=0; index<NUSE_TASK_NUMBER; index++)
 {
  if ((LONIB(NUSE_Task_Status[index])==
   NUSE_PARTITION_SUSPEND)
   && (HINIB(NUSE_Task_Status[index])==pool))
  {
   NUSE_Task_Blocking_Return[index]=NUSE_SUCCESS;
   NUSE_Wake_Task(index);
   break;
  }
 }
}

If any tasks are blocked on allocation of a partition in this pool, the first in the table is woken.

Partition pool utility services

Nucleus RTOS has three API calls that provide utility functions associated with partition pools: return information about a partition pool, return number of partition pools in the application, and return pointers to all partition pools in the application. The first two of these are implemented in Nucleus SE.

Obtaining partition pool information

This service call obtains a selection of information about a partition pool. 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 partition pool information

Service call prototype:

  STATUS NU_Partition_Pool_Information(

  NU_PARTITION_POOL *pool,

  CHAR *name,

  VOID **start_address,

  UNSIGNED *pool_size,

  UNSIGNED *partition_size,

  UNSIGNED *available,

  UNSIGNED *allocated,

  OPTION *suspend_type,

  UNSIGNED *tasks_waiting,

  NU_TASK **first_task);

Parameters:

 pool—pointer to the partition pool about which information is being requested;

 name—pointer to an 8-character destination area for the partition pool’s name; this includes space for the NULL terminator;

 start_address—a pointer to a variable, which will receive a pointer to the start of the partition pool data area;

 pool_size—a pointer to a variable, which will receive the size of the partition pool (in bytes);

 partition_size—a pointer to a variable, which will receive the size of partitions in this pool;

 available—a pointer to a variable, which will receive the number of partitions currently available in this pool;

 allocated—a pointer to a variable, which will receive the number of partitions currently in use in this pool;

 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 partition pool;

 first_task—a pointer to a task pointer into which is placed the pointer of the first suspended task.

Returns:

 NU_SUCCESS—The call was completed successfully.

 NU_INVALID_POOL—The partition pool pointer is not valid.

Nucleus SE API call for partition pool information

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

Service call prototype:

  STATUS NUSE_Partition_Pool_Information(

  NUSE_PARTITION_POOL pool,

  ADDR *start_address,

  U32 *pool_size,

  U16 *partition_size,

  U8 *available,

  U8 *allocated,

  U8 *tasks_waiting,

  NUSE_TASK *first_task);

Parameters:

 pool—the index of the partition pool about which information is being requested;

 start_address—a pointer to a variable, which will receive a pointer to the start of the partition pool data area;

 pool_size—a pointer to a variable, which will receive the size of the partition pool (in bytes);

 partition_size—a pointer to a variable, which will receive the size of partitions in this pool;

 available—a pointer to a variable, which will receive the number of partitions currently available in this pool;

 allocated—a pointer to a variable, which will receive the number of partitions currently in use in this pool;

 tasks_waiting—a pointer to a variable which will receive the number of tasks suspended on this partition pool (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_POOL—The partition pool index is not valid.

 NUSE_INVALID_POINTER—One or more of the pointer parameters is invalid.

Nucleus SE implementation of partition pool information

The implementation of this API call is quite straightforward:

STATUS NUSE_Partition_Pool_Information( NUSE_PARTITION_POOL pool,
 ADDR *start_address, U32 *pool_size, U16 *partition_size,
 U8 *available, U8 *allocated, U8 *tasks_waiting,
 NUSE_TASK *first_task)
{
 #if NUSE_API_PARAMETER_CHECKING
  if (pool >=NUSE_PARTITION_POOL_NUMBER)
  {
    return NUSE_INVALID_POOL;
  }
  if ((start_address==NULL) || (pool_size==NULL) ||
    (partition_size==NULL) || (available==NULL) ||
    (allocated==NULL) || (tasks_waiting==NULL) ||
    (first_task==NULL))
   {
    return NUSE_INVALID_POINTER;
   }
 #endif
 NUSE_CS_Enter();
 *start_address=NUSE_Partition_Pool_Data_Address[pool];
 *pool_size=NUSE_Partition_Pool_Partition_Number[pool] *
    NUSE_Partition_Pool_Partition_Size[pool];
 *partition_size=NUSE_Partition_Pool_Partition_Size[pool];
 *available=NUSE_Partition_Pool_Partition_Number[pool] –
    NUSE_Partition_Pool_Partition_Used[pool];
 *allocated=NUSE_Partition_Pool_Partition_Used[pool];
 #if NUSE_BLOCKING_ENABLE
  *tasks_waiting=NUSE_Partition_Pool_Blocking_Count[pool];
  if (NUSE_Partition_Pool_Blocking_Count[pool]!=0)
  {
   U8 index;

   for (index=0; index<NUSE_TASK_NUMBER; index++)

   {
    if ((LONIB(NUSE_Task_Status[index])==
     NUSE_PARTITION_SUSPEND)
     && (HINIB(NUSE_Task_Status[index])==pool))
    {
     *first_task=index;
     break;
    }
   }
  }
  else
  {
   *first_task=0;
  }
 #else
  *tasks_waiting=0;
  *first_task=0;
 #endif
 NUSE_CS_Exit();
 return NUSE_SUCCESS;
}

The function returns the partition pool 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 partition pools

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

Nucleus RTOS API call for number of partition pools

Service call prototype:

UNSIGNED NU_Established_Partition_Pools(VOID);

Parameters:

 None

Returns:

 The number of created partition pools in the application

Nucleus SE API call for number of partition pools

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

Service call prototype:

  U8 NUSE_Partition_Pool_Count(void);

Parameters:

 None

Returns:

 The number of configured partition pools in the application

Nucleus SE implementation of number of partition pools

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

Data structures

Partition pools utilize a number of data structures—in ROM and RAM—which, like other Nucleus SE objects, are a series of tables, included and dimensioned according to the number of pools configured and options selected.

I strongly recommend that application code does not access these data structures directly, but uses the provided API functions. This avoids incompatibility with future versions of Nucleus SE and unwanted side-effects and simplifies porting of an application to Nucleus RTOS. The details of data structures are included here to facilitate easier understanding of the working of the service call code and for debugging.

Kernel RAM data

These data structures are:

NUSE_Partition_Pool_Partition_Used[]—This is an array of type U8, with one entry for each configured partition pool, which contains a count of the number of partitions currently in use.

NUSE_Partition_Pool_Blocking_Count[]—This type U8 array contains the counts of how many tasks are blocked on each partition pool. This array only exists if blocking API call support is enabled.

These data structures are all initialized to zeros by NUSE_Init_Partition_Pool() when Nucleus SE starts up. This is logical, as it renders every partition in every pool unused. A full description of Nucleus SE start-up procedures may be found in Chapter 17, Nucleus SE Initialization and Start-Up.

Here are the definitions of these data structures in nuse_init.c file.

 RAM U8 NUSE_Partition_Pool_Partition_Used [NUSE_PARTITION_POOL_NUMBER];

 #if NUSE_BLOCKING_ENABLE

 RAM U8 NUSE_Partition_Pool_Blocking_Count [NUSE_PARTITION_POOL_NUMBER];

 #endif

User RAM

It is the user’s responsibility to provide an area of RAM for data storage for each configured partition pool. The size of this RAM area must accommodate the size and number of partitions configured (see “ROM data” section), with an additional byte for each partition in the pool. Each partition has a data area preceded by a single status byte.

ROM data

These data structures are:

 NUSE_Partition_Pool_Data_Address[]—This is an array of type ADDR, with one entry for each configured partition pool, which contains the address of the start of the data storage area.

 NUSE_Partition_Pool_Partition_Number[]—This is an array of type U8, with one entry for each configured partition pool, which contains the number of partitions in the pool.

 NUSE_Partition_Pool_Partition_Size[]—This is an array of type U16, with one entry for each configured partition pool, which contains the partition size for the pool.

These data structures are all declared and initialized (statically, of course) in nuse_config.c, this:

 ROM ADDR NUSE_Partition_Pool_Data_Address [NUSE_PARTITION_POOL_NUMBER]=

 {

  /* address of partition pools ------ */

 };

 ROM U8 NUSE_Partition_Pool_Partition_Number [NUSE_PARTITION_POOL_NUMBER]=

 {

  /* number of partitions in each pool ------ */

 };

 ROM U16 NUSE_Partition_Pool_Partition_Size [NUSE_PARTITION_POOL_NUMBER]=

 {

  /* partition sizes ------ */

  /* in bytes */

 };

Partition pool data footprint

Like all kernel objects in Nucleus SE, the amount of data memory required for partition pools is readily predictable.

The ROM data footprint (in bytes) for all the partition pools in an application may be computed thus:

 NUSE_PARTITION_POOL_NUMBER * (sizeof(ADDR) + 2)

The kernel RAM data footprint for all the partition pools in an application, when blocking API calls is enabled, is simply two bytes per partition pool. If blocking is disabled, only one byte is required.

The user RAM size for each partition pool varies, but, as mentioned earlier, may be computed for a pool of index n thus:

 NUSE_Partition_Pool_Partition_Number[n] *  (NUSE_Partition_Pool_Partition_Size[n] + 1)

Unimplemented API calls

Three partition pool API calls found in Nucleus RTOS are not implemented in Nucleus SE:

Create partition pool

This API call creates a partition pool. It is not needed with Nucleus SE, as tasks are created statically.

Service call prototype:

  STATUS NU_Create_Partition_Pool(

  NU_PARTITION_POOL *pool,

  CHAR *name,

  VOID *start_address,

  UNSIGNED pool_size,

  UNSIGNED partition_size,

  OPTION suspend_type);

Parameters:

 pool—pointer to a user-supplied partition pool control block; this will be used as a “handle” for the partition pool in other API calls.

 name—pointer to a 7-character, NULL-terminated name for the partition pool;

 start_address—specifies the starting address for the partition pool memory area.

 pool_size—the total number of bytes in the memory area.

 partition_size—the number of bytes for each partition in the pool. There is a small amount of memory “overhead” associated with each partition; this overhead is required by the two data pointers used.

 suspend_type—specifies how tasks suspend on the partition pool; valid options for this parameter are NU_FIFO and NU_PRIORITY.

Returns:

 NU_SUCCESS—indicates successful completion of the service.

 NU_INVALID_POOL—indicates the partition pool control block pointer is NULL.

 NU_INVALID_MEMORY—indicates the memory area specified by start_ address is NULL.

 NU_INVALID_SIZE—indicates the partition size is either 0 or larger than the total partition memory area.

 NU_INVALID_SUSPEND—indicates the suspend_type parameter is invalid.

Delete partition pool

This API call deletes a previously created partition pool. It is not needed with Nucleus SE, as tasks are created statically and cannot be deleted.

Service call prototype:

  STATUS NU_Delete_Partition_Pool(NU_PARTITION_POOL *pool);

Parameters:

 pool—pointer to partition pool control block.

Returns:

 NU_SUCCESS—indicates successful completion of the service.

 NU_INVALID_POOL—indicates the partition pool pointer is invalid.

Partition pool pointers

This API call builds a sequential list of pointers to all partition pools in the system. It is not needed with Nucleus SE, as tasks are identified by a simple index, not a pointer, and it would be redundant.

Service call prototype:

  UNSIGNED NU_Partition_Pool_Pointers(

  NU_PARTITION_POOL **pointer_list,

  UNSIGNED maximum_pointers);

Parameters:

 pointer_list—pointer to an array of NU_PARTITION_POOL pointers; this array will be filled with pointers to established partition pools in the system.

 maximum_pointers—the maximum number of pointers to place in the array.

Returns:

 The number of NU_PARTITION_POOL pointers placed into the array.

Compatibility with Nucleus RTOS

With all aspects of Nucleus SE, it was my goal to maintain as high a level of applications code compatibility with Nucleus RTOS as possible. Partition pools are no exception and, from a user’s perspective, they are implemented in much the same way as in Nucleus RTOS. There are areas of incompatibility, which have come about where I determined that such an incompatibility would be acceptable, given that the resulting code is easier to understand, or, more likely, could be made more memory efficient. Otherwise, Nucleus RTOS API calls may be almost directly mapped onto Nucleus SE calls. Chapter 20, Using Nucleus SE, provides further information on using Nucleus SE for users of Nucleus RTOS.

Object identifiers

In Nucleus RTOS, all objects are described by a data structure—a control block—which has a specific data type. A pointer to this control block serves as an identifier for the partition pool. In Nucleus SE, I decided that a different approach was needed for memory efficiency, and all kernel objects are described by a number of tables in RAM and/or ROM. The size of these tables is determined by the number of each object type that is configured. The identifier for a specific object is simply an index into those tables. So, I have defined NUSE_PARTITION_POOL as being equivalent to U8; a variable—not a pointer—of this type then serves as the task identifier. This is a small incompatibility, which is easily handled if code is ported to or from Nucleus RTOS. Object identifiers are normally just stored and passed around and not operated on in any way.

Nucleus RTOS also supports naming of partition pools. These names are only used for target-based debug facilities. I omitted them from Nucleus SE to save memory.

Partition size and number

In Nucleus RTOS a partition pool is configured in terms of the overall pool size and the partition size (which carries a two-pointer overhead); these parameters are expressed as type UNSIGNED, which is probably 32 bits. In Nucleus SE a partition pool is configured in terms of partition size (to which an additional byte of overhead is added) and number of partitions; these parameters are expressed as a U16 and U8, respectively.

Unimplemented API calls

Nucleus RTOS supports seven service calls to work with partition pools. Three of these service calls are not implemented in Nucleus SE. Details of these and of the decision to omit them were outlined earlier.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.189.2.122