Requirements for programs

To Contents

To previous page

To next page

 




Requirements for programs

eCos programs do not have to satisfy any unusual requirements, but there are always some differences between a program written for a real-time operating system as opposed to one written for a time sharing, virtual memory system like UNIX or Windows NT.

This chapter contains checklist of things to remember when writing eCos programs.

cyg_user_start()

The entry point for eCos user programs is usually cyg_user_start() instead of main() , although main() can be used if the ISO C library package is selected. Complete detail on the start-up sequence is given in System start-up .

Necessary headers

Any program which uses eCos system calls must have the following line at the top of the file:

 
#include <cyg/kernel/kapi.h>

and the programmer must make sure that cyg/kernel/kapi.h is available in the compiler include path. This can be done by setting the C_INCLUDE_PATH environment variable or by including the -I flag on the compiler command line.

Necessary link instructions

The eCos configuration and building process (described in Getting Started with eCos and eCos User's Guide ) builds a single library, libtarget.a , which contains the selected eCos components. The libtarget.a library does not contain any user libraries: If you put some of your source in libraries, you will have to explicitly include those libraries in the linking instruction.

You also need to link to the GNU C Compiler runtime support library ( libgcc.a ).

You should not link to the standard C++ library. This can be achieved with the -nostdlib option.

You should only link to libtarget.a and libgcc.a using the linker script target.ld provided with eCos. The command line for linking should look like

 
gcc [options] [object files] -Ttarget.ld -nostdlib 

Interrupt and exception handlers

In eCos a distinction is made between exceptions and interrupts.

exceptions

are the result of some action by the currently executing code. Examples of exceptions are divide by zero, illegal instruction, bad memory access, etc.

interrupts

are the result of a signal source which is conceptually asynchronous with the currently executing code. Examples of interrupts sources are the real-time clock, external and on chip peripherals and so forth.

This distinction is made in the eCos hardware abstraction layer (HAL) to provide a cleaner and more portable mechanism for installing interrupt handlers and exception handlers. Individual hardware platforms can have different ways of naming and handling interrupts, which is why this abstraction layer was chosen.

Interrupts and exceptions are both associated with vectors , which are labeled by vector numbers (see Exception handling and Interrupt handling ).

There are distinct spaces for exception and interrupt vectors. These are called "exception vector numbers" and "interrupt vector numbers". System calls which install exception handlers use the exception vector number, and the system calls which install interrupt handlers use the interrupt vector number to specify which interrupt or exception should be handled by the handler.

The details of the vector layout depend on the microprocessor and interrupt controller, and are documented in the relevant API sections.

Interrupt handlers are actually a pair of functions, one of which (the interrupt service routine, or ISR ) is executed immediately and runs with that interrupt disabled. Since interrupts are disabled for the duration of the ISR, the ISR should be very brief and should not use any system services.

After the ISR exits, but before the kernel scheduler is invoked again, a delayed service routine ( DSR ) will be invoked. It executes with scheduling disabled, but with interrupts enabled, so that further invocations of the same DSR can be queued. The DSR can use some producer-side system calls, but it should be carefully crafted to avoid using any call that might put its thread to sleep. One of the few examples of safe calls is cyg_semaphore_post() ; the non-blocking versions of some system calls are also safe. A call that is unsafe is cyg_mutex_lock() , since it will block if the mutex is already locked by another thread.

Finally, eCos has a formalism for installing low level handlers which bypass the kernel mechanisms described above. A program can install a vector service routine ( VSR ) which will be invoked instead of the kernel's usual exception or interrupt handling. The VSR will typically be written in assembly language.

VSRs are associated with vector numbers in the exception space, just like exception handlers (although there are some variations -- architectures in which there are no exceptions in the eCos sense). The main difference between VSRs and exception handlers is that VSRs bypass the kernel's usual mechanisms.

Memory allocation

Most eCos system calls expect you to pass the address of pre-allocated memory for the objects created in that system call. This is frequently the preferred way of doing things for embedded applications, where programmers want to allocate all memory statically and have fine control over that resource.

In contrast, some eCos system calls also allow a NULL pointer to be passed. In such a case the kernel will allocate the memory or select default size. This feature is not supported in the current release, and a warning flag is placed in the documentation for those routines (like cyg_thread_create() ).

eCos provides dynamic memory allocation, based on memory pools, a useful and flexible approach to memory management inspired by the µ ITRON compatibility layer. These are described in Memory pools .

If you configure your system to use the Standard C Library you can also use the standard malloc() library call.

Assertions and bad parameter handling

This section describes how the eCos kernel and basic packages behave when system calls are invoked with bad parameters.

In eCos, the basic kernel assertion behavior is configuration-dependent.

By default, assertions are turned off in the kernel. If the kernel is configured to turn them on, the kernel will make basic assertions, such as checking for invalid parameters when system calls are invoked. If an assertion fails, the kernel will print a message to the diagnostic output channel and stop executing.

If the kernel is configured with assertions disabled (usually when the application has been thoroughly debugged), it will not do any checking.

The configuration sections referenced above also describe the use of preconditions, postconditions and loop invariants. These are no different from ordinary assertions, but they are used in specialized circumstances, and the programmer would wish to select their presence individually.


Requirements for programs

To Contents

To previous page

To next page