Calling contexts – Comtrol eCos User Manual

Page 32

Advertising
background image

Kernel Overview

Calling Contexts

eCos defines a number of contexts. Only certain calls are allowed from inside each context, for example most
operations on threads or synchronization primitives are not allowed from ISR context. The different contexts are
initialization, thread, ISR and DSR.

When eCos starts up it goes through a number of phases, including setting up the hardware and invoking C++ static
constructors. During this time interrupts are disabled and the scheduler is locked. When a configuration includes
the kernel package the final operation is a call to

cyg_scheduler_start

. At this point interrupts are enabled, the

scheduler is unlocked, and control is transferred to the highest priority runnable thread. If the configuration also
includes the C library package then usually the C library startup package will have created a thread which will call
the application’s

main

entry point.

Some application code can also run before the scheduler is started, and this code runs in initialization context.
If the application is written partly or completely in C++ then the constructors for any static objects will be run.
Alternatively application code can define a function

cyg_user_start

which gets called after any C++ static

constructors. This allows applications to be written entirely in C.

void

cyg_user_start(void)

{

/* Perform application-specific initialization here */

}

It is not necessary for applications to provide a

cyg_user_start

function since the system will provide a default

implementation which does nothing.

Typical operations that are performed from inside static constructors or

cyg_user_start

include creating threads,

synchronization primitives, setting up alarms, and registering application-specific interrupt handlers. In fact for
many applications all such creation operations happen at this time, using statically allocated data, avoiding any
need for dynamic memory allocation or other overheads.

Code running in initialization context runs with interrupts disabled and the scheduler locked. It is not permitted
to reenable interrupts or unlock the scheduler because the system is not guaranteed to be in a totally consis-
tent state at this point. A consequence is that initialization code cannot use synchronization primitives such as

cyg_semaphore_wait

to wait for an external event. It is permitted to lock and unlock a mutex: there are no other

threads running so it is guaranteed that the mutex is not yet locked, and therefore the lock operation will never
block; this is useful when making library calls that may use a mutex internally.

At the end of the startup sequence the system will call

cyg_scheduler_start

and the various threads will

start running. In thread context nearly all of the kernel functions are available. There may be some restrictions
on interrupt-related operations, depending on the target hardware. For example the hardware may require
that interrupts be acknowledged in the ISR or DSR before control returns to thread context, in which case

cyg_interrupt_acknowledge

should not be called by a thread.

At any time the processor may receive an external interrupt, causing control to be transferred from the current
thread. Typically a VSR provided by eCos will run and determine exactly which interrupt occurred. Then the VSR
will switch to the appropriate ISR, which can be provided by a HAL package, a device driver, or by the application.
During this time the system is running at ISR context, and most of the kernel function calls are disallowed. This
includes the various synchronization primitives, so for example an ISR is not allowed to post to a semaphore to
indicate that an event has happened. Usually the only operations that should be performed from inside an ISR are

32

Advertising