Error handling and assertions – Comtrol eCos User Manual

Page 33

Advertising
background image

Kernel Overview

ones related to the interrupt subsystem itself, for example masking an interrupt or acknowledging that an interrupt
has been processed. On SMP systems it is also possible to use spinlocks from ISR context.

When an ISR returns it can request that the corresponding DSR be run as soon as it is safe to do so, and that
will run in DSR context. This context is also used for running alarm functions, and threads can switch temporar-
ily to DSR context by locking the scheduler. Only certain kernel functions can be called from DSR context, al-
though more than in ISR context. In particular it is possible to use any synchronization primitives which cannot
block. These include

cyg_semaphore_post

,

cyg_cond_signal

,

cyg_cond_broadcast

,

cyg_flag_setbits

,

and

cyg_mbox_tryput

. It is not possible to use any primitives that may block such as

cyg_semaphore_wait

,

cyg_mutex_lock

, or

cyg_mbox_put

. Calling such functions from inside a DSR may cause the system to hang.

The specific documentation for the various kernel functions gives more details about valid contexts.

Error Handling and Assertions

In many APIs each function is expected to perform some validation of its parameters and possibly of the current
state of the system. This is supposed to ensure that each function is used correctly, and that application code is not
attempting to perform a semaphore operation on a mutex or anything like that. If an error is detected then a suitable
error code is returned, for example the POSIX function

pthread_mutex_lock

can return various error codes

including

EINVAL

and

EDEADLK

. There are a number of problems with this approach, especially in the context of

deeply embedded systems:

1. Performing these checks inside the mutex lock and all the other functions requires extra cpu cycles and adds

significantly to the code size. Even if the application is written correctly and only makes system function calls
with sensible arguments and under the right conditions, these overheads still exist.

2. Returning an error code is only useful if the calling code detects these error codes and takes appropriate action.

In practice the calling code will often ignore any errors because the programmer “knows” that the function is
being used correctly. If the programmer is mistaken then an error condition may be detected and reported, but
the application continues running anyway and is likely to fail some time later in mysterious ways.

3. If the calling code does always check for error codes, that adds yet more cpu cycles and code size overhead.

4. Usually there will be no way to recover from certain errors, so if the application code detected an error such

as

EINVAL

then all it could do is abort the application somehow.

The approach taken within the eCos kernel is different. Functions such as

cyg_mutex_lock

will not return an error

code. Instead they contain various assertions, which can be enabled or disabled. During the development process
assertions are normally left enabled, and the various kernel functions will perform parameter checks and other
system consistency checks. If a problem is detected then an assertion failure will be reported and the application
will be terminated. In a typical debug session a suitable breakpoint will have been installed and the developer can
now examine the state of the system and work out exactly what is going on. Towards the end of the development
cycle assertions will be disabled by manipulating configuration options within the eCos infrastructure package, and
all assertions will be eliminated at compile-time. The assumption is that by this time the application code has been
mostly debugged: the initial version of the code might have tried to perform a semaphore operation on a mutex, but
any problems like that will have been fixed some time ago. This approach has a number of advantages:

1. In the final application there will be no overheads for checking parameters and other conditions. All that code

will have been eliminated at compile-time.

33

Advertising