Advertisement

Partition memory: utility services and data structures

December 11, 2017

Colin Walls-December 11, 2017


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 future article will provide a full description of Nucleus SE start-up procedures.

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

  

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 below), 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:


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 above, 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 objects 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 – pointers 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 objects 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 objects 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. A future article will include 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. Of these, three are not implemented in Nucleus SE. Details of these and of the decision to omit them was outlined above.

The next RTOS Revealed article will look at signals.


Colin Walls has over thirty years experience in the electronics industry, largely dedicated to embedded software. A frequent presenter at conferences and seminars and author of numerous technical articles and two books on embedded software, Colin is an embedded software technologist with Mentor Embedded [the Mentor Graphics Embedded Software Division], and is based in the UK. His regular blog is located at: http://blogs.mentor.com/colinwalls. He may be reached by email at colin_walls@mentor.com

< Previous
Page 2 of 2
Next >

Loading comments...