Advertisement

RTOS diagnostics and error checking

April 23, 2019

Colin Walls-April 23, 2019

Error handling is unlikely to be a major feature of any operating system intended for embedded systems applications. This is an inevitable result of resource limitations – and all embedded systems have some kind of constraints. It is also logical, as only a limited number of embedded systems have the opportunity to behave like a desktop system – i.e. offer the user an opportunity to decide what to do next in the event of some exceptional event.

In Nucleus SE there are broadly three types of error checking:

  • Facilities to “sanity check” the selected configuration – just to make sure that selected options are consistent

  • Optionally included code to check runtime behavior

  • Specific API functions that facilitate the design of more robust code

These will all be covered in this article along with some ideas about user-implemented diagnostics.

Configuration Checks

Nucleus SE is designed to be very user-configurable so that it can be tailored to make the best use of available resources. This configurability is a challenge, as the number of options, and the interdependencies between them, is quite large. As has been described in many of the previous articles, most user configuration of Nucleus SE is performed by setting #define constants in the file nuse_config.h.

In order to help identify configuration errors, a file – nuse_config_check.h – is included (i.e. by means of a #include into nuse_config.c), which performs a number of consistency checks on the #define symbols. Here is an extract from this file:

/*** Tasks and task control ***/
#if NUSE_TASK_NUMBER < 1 || NUSE_TASK_NUMBER > 16
    #error NUSE: invalid number of tasks - must be 1-16
#endif
#if NUSE_TASK_RELINQUISH && (NUSE_SCHEDULER_TYPE == NUSE_PRIORITY_SCHEDULER)
    #error NUSE: NUSE_Task_Relinquish() selected - not valid with
                                           priority scheduler
#endif
#if NUSE_TASK_RESUME && !NUSE_SUSPEND_ENABLE
    #error NUSE: NUSE_Task_Resume() selected  - task suspend not
                                           enabled
#endif
#if NUSE_TASK_SUSPEND && !NUSE_SUSPEND_ENABLE
    #error NUSE: NUSE_Task_Suspend() selected  - task suspend not
                                           enabled
#endif
#if NUSE_INITIAL_TASK_STATE_SUPPORT && !NUSE_SUSPEND_ENABLE
    #error NUSE: Initial task state enabled - task suspend not
                                           enabled
#endif
/*** Partition pools ***/
#if NUSE_PARTITION_POOL_NUMBER > 16
    #error NUSE: invalid number of partition pools - must be 0-16
#endif
#if NUSE_PARTITION_POOL_NUMBER == 0
    #if NUSE_PARTITION_ALLOCATE
        #error NUSE: NUSE_Partition_Allocate() enabled – no
                                partition pools configured
    #endif
    #if NUSE_PARTITION_DEALLOCATE
        #error NUSE: NUSE_Partition_Deallocate() enabled – no
                                partition pools configured
    #endif
    #if NUSE_PARTITION_POOL_INFORMATION
        #error NUSE: NUSE_Partition_Pool_Information() enabled –
                                no partition pools configured
    #endif
#endif

Scroll or drag the corner of the box to expand as needed.

The checks performed include the following:

  • Verification that at least one, but no more than sixteen tasks have been configured

  • Confirmation of that selected API functions are not inconsistent with the chosen scheduler or other options

  • Verification that no more than sixteen instances of other kernel objects has been specified

  • Confirmation that API functions have not been selected for objects that are not instantiated at all

  • Ensuring that API functions for signals and system time are not selected when these facilities have not been enabled

  • Verification of selected scheduler type and associated options

In all cases, detection of an error results in the compilation of a #error statement. This normally results in the compilation being terminated with the specified message.

This file does not make it impossible to create an illogical configuration but renders it highly unlikely.

API Parameter Checking

Like Nucleus RTOS, Nucleus SE has the facility to optionally include code to verify API function call parameters at run time. Normally this would only be employed during initial debugging and testing as the memory and runtime overhead would be undesirable in production code.

Parameter checking is enabled by setting NUSE_API_PARAMETER_CHECKING in nuse_config.h to TRUE. This enables the compilation of the required additional code. Here is an example of an API function’s parameter checking:

STATUS NUSE_Mailbox_Send(NUSE_MAILBOX mailbox, ADDR *message,
                           U8 suspend)
{
      STATUS return_value;
      #if NUSE_API_PARAMETER_CHECKING
         if (mailbox >= NUSE_MAILBOX_NUMBER)
         {
               return NUSE_INVALID_MAILBOX;
         }
         if (message == NULL)
         {
               return NUSE_INVALID_POINTER;
         }
         #if NUSE_BLOCKING_ENABLE
            if ((suspend != NUSE_NO_SUSPEND) &&
                  (suspend != NUSE_SUSPEND))
            {
                  return NUSE_INVALID_SUSPEND;
            }
            #else
               if (suspend != NUSE_NO_SUSPEND)
               {
                     return NUSE_INVALID_SUSPEND;
               }
            #endif
      #endif

Scroll or drag the corner of the box to expand as needed.

This parameter checking may result in the return of an error code from the API function call. These are all negative values of the form NUSE_INVALID_xxx (e.g. NUSE_INVALID_POINTER) – a complete set of definitions is included in nuse_codes.h.

Extra application code (perhaps conditionally compiled) may be included to process these error values, but it would probably be better to use the data monitoring facilities of a modern embedded debugger to detect them.

Parameter checking introduces overheads in memory (the extra code) and run time performance, so its use is somewhat intrusive. As the full source code to Nucleus SE is available to the developer, checking and debugging can be done “by hand” on production code, if absolute precision is required.

Task Stack Checking

So long as the Run to Completion scheduler is not in use, Nucleus SE has a task stack checking facility available, which is similar to that provided in Nucleus RTOS, and provides an indication of remaining stack space. This API call – NUSE_Task_Check_Stack() – was described in detail in a previous article. Some ideas on stack error checking are discussed in the "User Diagnostics" section later in this article.

Version Information

Nucleus RTOS and Nucleus SE have an API function which simply returns version/release information about the kernel.

Nucleus RTOS API Call

Service call prototype:

CHAR *NU_Release_Information(VOID);

Parameters:

None

Returns:

Pointer to NULL-terminated version string

Nucleus SE API Call

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

Service call prototype:

char *NUSE_Release_Information(void);

Parameters:

None

Returns:

Pointer to NULL-terminated version string

Nucleus SE Implementation of Release Information

The implementation of this API call is almost trivial. A pointer to the string constant NUSE_Release_Info, which is declared and initialized in nuse_globals.c, is returned.

This string takes the form Nucleus SE - Xyymmdd, where:

X is the release status: A = alpha; B = beta; R = released
yy is the year of the release
mm is the month of release
dd is the day of release

Compatibility with Nucleus RTOS

Nucleus RTOS includes an optional facility for maintaining a history log. The kernel records details of various system activities. API functions are provided to enable the application program to:

  • enable/disable history saving

  • make a history entry

  • retrieve a history entry

This capability is not supported by Nucleus SE.

Nucleus RTOS also includes some error management macros that perform assertions and provide a means by which a user-define fatal error function may be called. These are conditionally included in an OS build. Nucleus SE does not support this type of facility.

Continue reading on page two, "User Diagnostics" >>

< Previous
Page 1 of 2
Next >

Loading comments...