|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Programming With eCos
|
Programming With eCos
|
|
|
|
|
Programming With eCos
|
Programming With eCos
|
|
|
The following chapters of this manual comprise a simple tutorial
|
The following chapters of this manual comprise a simple tutorial
|
for configuring and building eCos, building and running eCos tests,
|
for configuring and building eCos, building and running eCos tests,
|
and finally building three stand-alone example programs which use
|
and finally building three stand-alone example programs which use
|
the eCos API to perform some simple tasks.
|
the eCos API to perform some simple tasks.
|
|
|
You will need a properly installed eCos system, with the correct
|
You will need a properly installed eCos system, with the correct
|
versions of the GNU toolchain. On Windows
|
versions of the GNU toolchain. On Windows
|
you will be using the bash command line interpreter that comes with
|
you will be using the bash command line interpreter that comes with
|
Cygwin, with the environment variables set as described in the
|
Cygwin, with the environment variables set as described in the
|
toolchain documentation.
|
toolchain documentation.
|
|
|
|
|
The Development Process
|
The Development Process
|
|
|
Most development projects using eCos would contain some (or
|
Most development projects using eCos would contain some (or
|
most) of the following:
|
most) of the following:
|
|
|
|
|
eCos Configuration
|
eCos Configuration
|
|
|
eCos is configured to provide the desired API (the inclusion
|
eCos is configured to provide the desired API (the inclusion
|
of libc, uitron, and the disabling of certain undesired funtions,
|
of libc, uitron, and the disabling of certain undesired funtions,
|
etc.), and semantics (selecting scheduler, mutex behavior, etc.).
|
etc.), and semantics (selecting scheduler, mutex behavior, etc.).
|
See .
|
See .
|
|
|
It would normally make sense to enable eCos assertion checking
|
It would normally make sense to enable eCos assertion checking
|
at this time as well, to catch as many programming errors during
|
at this time as well, to catch as many programming errors during
|
the development phase as possible.
|
the development phase as possible.
|
|
|
Note that it should not be necessary to spend much time on
|
Note that it should not be necessary to spend much time on
|
eCos configuration initially. It may be important to perform fine
|
eCos configuration initially. It may be important to perform fine
|
tuning to reduce the memory footprint and to improve performance
|
tuning to reduce the memory footprint and to improve performance
|
later when the product reaches a testable state.
|
later when the product reaches a testable state.
|
|
|
|
|
|
|
Integrity check of the eCos configuration
|
Integrity check of the eCos configuration
|
|
|
While we strive to thoroughly test eCos, the vast number
|
While we strive to thoroughly test eCos, the vast number
|
of configuration permutations mean that the particular configuration
|
of configuration permutations mean that the particular configuration
|
parameters used for your project may not have been tested. Therefore,
|
parameters used for your project may not have been tested. Therefore,
|
we advise running the eCos tests after the project's
|
we advise running the eCos tests after the project's
|
eCos configuration has been determined. See .
|
eCos configuration has been determined. See .
|
|
|
Obviously, this should be repeated if the configuration changes
|
Obviously, this should be repeated if the configuration changes
|
later on in the development process.
|
later on in the development process.
|
|
|
|
|
|
|
Application Development - Target Neutral Part
|
Application Development - Target Neutral Part
|
|
|
While your project is probably targeting a specific architecture
|
While your project is probably targeting a specific architecture
|
and platform, possibly custom hardware, it may be possible to perform
|
and platform, possibly custom hardware, it may be possible to perform
|
part of the application development using simulated or synthetic
|
part of the application development using simulated or synthetic
|
targets.
|
targets.
|
|
|
There are three good reasons for doing this:
|
There are three good reasons for doing this:
|
|
|
|
|
|
|
|
|
It may be possible by this means to perform application
|
It may be possible by this means to perform application
|
development in parallel with the design/implementation
|
development in parallel with the design/implementation
|
of the target hardware, thus providing more time for developing
|
of the target hardware, thus providing more time for developing
|
and testing functionality, and reducing time-to-market.
|
and testing functionality, and reducing time-to-market.
|
|
|
|
|
|
|
The build-run-debug-cycle may be faster when the application
|
The build-run-debug-cycle may be faster when the application
|
does not have to be downloaded to a target via a serial interface.
|
does not have to be downloaded to a target via a serial interface.
|
Debugging is also likely to be more responsive when you do not have to
|
Debugging is also likely to be more responsive when you do not have to
|
to communicate with the remote GDB stubs in RedBoot via serial. It
|
to communicate with the remote GDB stubs in RedBoot via serial. It
|
also removes the need for manually or automatically resetting the
|
also removes the need for manually or automatically resetting the
|
target hardware.
|
target hardware.
|
|
|
|
|
|
|
|
|
New hardware can often be buggy. Comparing the behaviour of the
|
New hardware can often be buggy. Comparing the behaviour of the
|
program on the hardware and in the simulator or synthetic target may
|
program on the hardware and in the simulator or synthetic target may
|
allow you to identify where the problems lie.
|
allow you to identify where the problems lie.
|
|
|
|
|
|
|
|
|
|
|
This approach is possible because all targets (including
|
This approach is possible because all targets (including
|
simulators and synthetic ones) provide the same basic API: that
|
simulators and synthetic ones) provide the same basic API: that
|
is, kernel, libc, libm, uitron, infra, and to some extent, HAL and
|
is, kernel, libc, libm, uitron, infra, and to some extent, HAL and
|
IO.
|
IO.
|
|
|
Synthetic targets are especially suitable as they allow you
|
Synthetic targets are especially suitable as they allow you
|
to construct simulations of elaborate devices by interaction with
|
to construct simulations of elaborate devices by interaction with
|
the host system, where an IO device API can hide the details from
|
the host system, where an IO device API can hide the details from
|
the application. When switching to hardware later in the development
|
the application. When switching to hardware later in the development
|
cycle, the IO driver is properly implemented.
|
cycle, the IO driver is properly implemented.
|
|
|
|
|
|
|
Simulators can also do this, but it all depends on the
|
Simulators can also do this, but it all depends on the
|
design and capabilities of the simulator you use. Some, like
|
design and capabilities of the simulator you use. Some, like
|
SID or
|
SID or
|
Bochs provide
|
Bochs provide
|
complete hardware emulation, while others just support enough of the
|
complete hardware emulation, while others just support enough of the
|
instruction set to run compiled code.
|
instruction set to run compiled code.
|
|
|
|
|
Therefore, select a simulator or synthetic target and use
|
Therefore, select a simulator or synthetic target and use
|
it for as long as possible for application development. That is,
|
it for as long as possible for application development. That is,
|
configure for the selected target, build eCos, build the application
|
configure for the selected target, build eCos, build the application
|
and link with eCos, run and debug. Repeat the latter two steps until
|
and link with eCos, run and debug. Repeat the latter two steps until
|
you are happy with it.
|
you are happy with it.
|
|
|
Obviously, at some time you will have to switch to the intended
|
Obviously, at some time you will have to switch to the intended
|
target hardware, for example when adding target specific feature
|
target hardware, for example when adding target specific feature
|
support, for memory footprint/performance characterization,
|
support, for memory footprint/performance characterization,
|
and for final tuning of eCos and the application.
|
and for final tuning of eCos and the application.
|
|
|
|
|
|
|
|
|
Application Development - Target Specific Part
|
Application Development - Target Specific Part
|
|
|
Repeat the build-run-debug-cycle while performing final tuning
|
Repeat the build-run-debug-cycle while performing final tuning
|
and debugging of application. Remember to disable eCos assertion
|
and debugging of application. Remember to disable eCos assertion
|
checking if you are testing any performance-related aspects, it can
|
checking if you are testing any performance-related aspects, it can
|
make a big difference.
|
make a big difference.
|
|
|
It may be useful to switch between this and the previous step
|
It may be useful to switch between this and the previous step
|
repeatedly through the development process; use the simulator/synthetic
|
repeatedly through the development process; use the simulator/synthetic
|
target for actual development, and use the target hardware to continually
|
target for actual development, and use the target hardware to continually
|
check memory footprint and performance. There should be little cost
|
check memory footprint and performance. There should be little cost
|
in switching between the two targets when using two separate build
|
in switching between the two targets when using two separate build
|
trees.
|
trees.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Configuring and Building eCos from Source
|
Configuring and Building eCos from Source
|
|
|
This chapter documents the configuration of eCos. The process is
|
This chapter documents the configuration of eCos. The process is
|
the same for any of the supported targets: you may select a
|
the same for any of the supported targets: you may select a
|
hardware target (if you have a board available), any one of the
|
hardware target (if you have a board available), any one of the
|
simulators, or a synthetic target (if your host platform has synthetic
|
simulators, or a synthetic target (if your host platform has synthetic
|
target support).
|
target support).
|
|
|
|
|
|
|
|
|
eCos Start-up Configurations
|
eCos Start-up Configurations
|
|
|
There are various ways to download an executable image to a
|
There are various ways to download an executable image to a
|
target board, and these involve different ways of preparing the
|
target board, and these involve different ways of preparing the
|
executable image. In the eCos Hardware Abstraction Layer (HAL package)
|
executable image. In the eCos Hardware Abstraction Layer (HAL package)
|
there are configuration options to support the different download
|
there are configuration options to support the different download
|
methods. summarizes the
|
methods. summarizes the
|
ways in which an eCos image can be prepared for different types of
|
ways in which an eCos image can be prepared for different types of
|
download. This is not an exhaustive list, some targets define
|
download. This is not an exhaustive list, some targets define
|
additional start-up types of their own. Where a ROM Monitor is
|
additional start-up types of their own. Where a ROM Monitor is
|
mentioned, this will usually be RedBoot, although on some older, or
|
mentioned, this will usually be RedBoot, although on some older, or
|
low resource, targets you may need to use CygMon or the GDB stubs ROM,
|
low resource, targets you may need to use CygMon or the GDB stubs ROM,
|
see the target documentation for details.
|
see the target documentation for details.
|
|
|
|
|
Configuration for various download methods
|
Configuration for various download methods
|
|
|
|
|
|
|
Download method
|
Download method
|
HAL configuration
|
HAL configuration
|
|
|
|
|
|
|
|
|
|
|
Burn hardware ROM
|
Burn hardware ROM
|
ROM or ROMRAM start-up
|
ROM or ROMRAM start-up
|
|
|
|
|
|
|
Download to ROM emulator
|
Download to ROM emulator
|
ROM or ROMRAM start-up
|
ROM or ROMRAM start-up
|
|
|
|
|
|
|
Download to board with ROM Monitor
|
Download to board with ROM Monitor
|
RAM start-up
|
RAM start-up
|
|
|
|
|
|
|
Download to simulator without ROM Monitor
|
Download to simulator without ROM Monitor
|
ROM start-up
|
ROM start-up
|
|
|
|
|
|
|
Download to simulator with ROM Monitor
|
Download to simulator with ROM Monitor
|
RAM start-up
|
RAM start-up
|
|
|
|
|
|
|
Download to simulator ignoring devices
|
Download to simulator ignoring devices
|
SIM configuration
|
SIM configuration
|
|
|
|
|
|
|
Run synthetic target
|
Run synthetic target
|
RAM start-up
|
RAM start-up
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
You cannot run an application configured for RAM start-up
|
You cannot run an application configured for RAM start-up
|
on the simulator directly: it will fail during start-up. You can
|
on the simulator directly: it will fail during start-up. You can
|
only download it to the simulator if
|
only download it to the simulator if
|
you are already running RedBoot in the simulator,
|
you are already running RedBoot in the simulator,
|
as described in the toolchain documentation
|
as described in the toolchain documentation
|
or you load through the
|
or you load through the
|
SID
|
SID
|
GDB debugging component. This is not the same as the simulated
|
GDB debugging component. This is not the same as the simulated
|
stub, since it does not require a target program to be running to
|
stub, since it does not require a target program to be running to
|
get GDB to talk to it. It can be done before letting the simulator
|
get GDB to talk to it. It can be done before letting the simulator
|
run
|
run
|
or you use the ELF loader component to get a program into memory.
|
or you use the ELF loader component to get a program into memory.
|
|
|
|
|
|
|
|
|
Configuring eCos' HAL package for simulation should
|
Configuring eCos' HAL package for simulation should
|
rarely be needed for real development; binaries built with such
|
rarely be needed for real development; binaries built with such
|
a kernel will not run on target boards at all,
|
a kernel will not run on target boards at all,
|
and the MN10300 and
|
and the MN10300 and
|
TX39 simulators can run binaries built for stdeval1 and jmr3904
|
TX39 simulators can run binaries built for stdeval1 and jmr3904
|
target boards.
|
target boards.
|
The main use for a ``simulation'' configuration
|
The main use for a ``simulation'' configuration
|
is if you are trying to work around problems with the device drivers
|
is if you are trying to work around problems with the device drivers
|
or with the simulator. Also note that when using a TX39 system configured
|
or with the simulator. Also note that when using a TX39 system configured
|
for simulator start-up you should then invoke the simulator with
|
for simulator start-up you should then invoke the simulator with
|
the
|
the
|
option instead of
|
option instead of
|
|
|
|
|
|
|
|
|
If your chosen architecture does not have simulator support,
|
If your chosen architecture does not have simulator support,
|
then the combinations above that refer to the simulator do not apply.
|
then the combinations above that refer to the simulator do not apply.
|
Similarly, if your chosen platform does not have RedBoot
|
Similarly, if your chosen platform does not have RedBoot
|
ROM support, the combinations listed above that use
|
ROM support, the combinations listed above that use
|
RedBoot do not apply.
|
RedBoot do not apply.
|
|
|
|
|
The debugging environment for most developers will be either
|
The debugging environment for most developers will be either
|
a hardware board or the simulator, in which case they will be able
|
a hardware board or the simulator, in which case they will be able
|
to select a single HAL configuration.
|
to select a single HAL configuration.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Configuration Tool on Windows and Linux Quick Start
|
Configuration Tool on Windows and Linux Quick Start
|
|
|
|
|
|
|
Note that the use of the Configuration Tool
|
Note that the use of the Configuration Tool
|
is described in detail in
|
is described in detail in
|
LINKEND="THE-ECOS-CONFIGURATION-TOOL">.
|
LINKEND="THE-ECOS-CONFIGURATION-TOOL">.
|
|
|
The Configuration Tool (see )
|
The Configuration Tool (see )
|
has five main elements: the configuration window,
|
has five main elements: the configuration window,
|
the conflicts window,
|
the conflicts window,
|
the properties window, the short
|
the properties window, the short
|
description window,
|
description window,
|
and the output window.
|
and the output window.
|
|
|
|
|
Configuration Tool
|
Configuration Tool
|
![]()
|
![]()
|
|
|
|
|
Start by opening the templates window via Build->Templates.
|
Start by opening the templates window via Build->Templates.
|
Select the desired target (see ).
|
Select the desired target (see ).
|
|
|
|
|
Template selection
|
Template selection
|
![]()
|
![]()
|
|
|
|
|
Make sure that the configuration is correct for the target
|
Make sure that the configuration is correct for the target
|
in terms of endianness, CPU model, Startup type, etc. (see ).
|
in terms of endianness, CPU model, Startup type, etc. (see ).
|
|
|
|
|
Configuring
|
Configuring
|
for the target
|
for the target
|
![]()
|
![]()
|
|
|
|
|
Next, select the Build->Library menu
|
Next, select the Build->Library menu
|
item to start building eCos (see
|
item to start building eCos (see
|
LINKEND="FIGURE-SELECTING-THE-BUILD-LIBRARY-MENU-ITEM">). The
|
LINKEND="FIGURE-SELECTING-THE-BUILD-LIBRARY-MENU-ITEM">). The
|
application will configure the sources, prepare a build tree, and
|
application will configure the sources, prepare a build tree, and
|
build the libtarget.a library, which contains the
|
build the libtarget.a library, which contains the
|
eCos kernel and other packages.
|
eCos kernel and other packages.
|
|
|
|
|
Selecting the Build Library menu item
|
Selecting the Build Library menu item
|
![]()
|
![]()
|
|
|
|
|
|
|
The Save As dialog box will appear, asking
|
The Save As dialog box will appear, asking
|
you to specify a directory in which to place your save file. You
|
you to specify a directory in which to place your save file. You
|
can use the default, but it is a good idea to make a subdirectory,
|
can use the default, but it is a good idea to make a subdirectory,
|
called ecos-work for example.
|
called ecos-work for example.
|
|
|
|
|
Save file dialog
|
Save file dialog
|
![]()
|
![]()
|
|
|
|
|
The first time you build an eCos library for a specific
|
The first time you build an eCos library for a specific
|
architecture, the Configuration Tool may prompt
|
architecture, the Configuration Tool may prompt
|
you for the location of the appropriate build tools (including
|
you for the location of the appropriate build tools (including
|
make and
|
make and
|
TARGET-gcc) using a
|
TARGET-gcc) using a
|
Build Tools dialog box (as shown in
|
Build Tools dialog box (as shown in
|
LINKEND="FIGURE-BUILD-TOOLS-DIALOG">). You can select a location from
|
LINKEND="FIGURE-BUILD-TOOLS-DIALOG">). You can select a location from
|
the drop down list, browse to the directory using the
|
the drop down list, browse to the directory using the
|
Browse button, or type in the location of the
|
Browse button, or type in the location of the
|
build tools manually.
|
build tools manually.
|
|
|
|
|
Build tools dialog
|
Build tools dialog
|
![]()
|
![]()
|
|
|
|
|
The Configuration Tool may also prompt you
|
The Configuration Tool may also prompt you
|
for the location of the user tools (such as cat and
|
for the location of the user tools (such as cat and
|
ls) using a User Tools dialog
|
ls) using a User Tools dialog
|
box (as shown in ). As with
|
box (as shown in ). As with
|
the Build Tools dialog, you can select a location
|
the Build Tools dialog, you can select a location
|
from the drop down list, browse to the directory using the
|
from the drop down list, browse to the directory using the
|
Browse button, or type in the location of the
|
Browse button, or type in the location of the
|
user tools manually. Note that on Linux, this will often be
|
user tools manually. Note that on Linux, this will often be
|
unnecessary as the tools will already be on your PATH.
|
unnecessary as the tools will already be on your PATH.
|
|
|
|
|
User tools dialog
|
User tools dialog
|
![]()
|
![]()
|
|
|
|
|
When the tool locations have been entered, the Configuration
|
When the tool locations have been entered, the Configuration
|
Tool will configure the sources, prepare a build tree,
|
Tool will configure the sources, prepare a build tree,
|
and build the libtarget.a library, which contains
|
and build the libtarget.a library, which contains
|
the eCos kernel and other packages.
|
the eCos kernel and other packages.
|
|
|
The output from the configuration process and the building
|
The output from the configuration process and the building
|
of libtarget.a will be shown in the output
|
of libtarget.a will be shown in the output
|
window.
|
window.
|
|
|
Once the build process has finished you will have a kernel
|
Once the build process has finished you will have a kernel
|
with other packages in libtarget.a. You should
|
with other packages in libtarget.a. You should
|
now build the eCos tests for your particular configuration.
|
now build the eCos tests for your particular configuration.
|
|
|
You can do this by selecting Build -> Tests.
|
You can do this by selecting Build -> Tests.
|
Notice that you could have selected Tests instead
|
Notice that you could have selected Tests instead
|
of Library in the earlier step and it would
|
of Library in the earlier step and it would
|
have built both the library and the tests,
|
have built both the library and the tests,
|
but this would increase the build time substantially, and if you
|
but this would increase the build time substantially, and if you
|
do not need to build the tests it is unnecessary.
|
do not need to build the tests it is unnecessary.
|
|
|
|
|
Selecting the Build Tests menu item
|
Selecting the Build Tests menu item
|
![]()
|
![]()
|
|
|
|
|
will guide you through running one
|
will guide you through running one
|
of the test cases you just built on the selected target,
|
of the test cases you just built on the selected target,
|
using GDB.
|
using GDB.
|
|
|
|
|
|
|
|
|
|
|
|
|
Ecosconfig on Windows and Linux Quick Start
|
Ecosconfig on Windows and Linux Quick Start
|
|
|
As an alternative to using the graphical
|
As an alternative to using the graphical
|
Configuration Tool, it is still possible to
|
Configuration Tool, it is still possible to
|
configure and build a kernel by editing a configuration file manually
|
configure and build a kernel by editing a configuration file manually
|
and using the ecosconfig command.
|
and using the ecosconfig command.
|
|
|
|
|
Manual configuration and the ecosconfig command are
|
Manual configuration and the ecosconfig command are
|
described in detail in .
|
described in detail in .
|
|
|
|
|
|
|
To use the ecosconfig command you need to start a
|
To use the ecosconfig command you need to start a
|
shell. In Windows you need to start a
|
shell. In Windows you need to start a
|
CygWin bash shell, not a
|
CygWin bash shell, not a
|
DOS command line.
|
DOS command line.
|
|
|
|
|
|
-->
|
|
|
The following instructions assume that the
|
The following instructions assume that the
|
PATH and ECOS_REPOSITORY
|
PATH and ECOS_REPOSITORY
|
environment variables have been setup correctly as described in
|
environment variables have been setup correctly as described in
|
LINKEND="user-guide-installation-linux">. They also assume Linux
|
LINKEND="user-guide-installation-linux">. They also assume Linux
|
usage but equally well apply to Windows running Cygwin.
|
usage but equally well apply to Windows running Cygwin.
|
|
|
Before invoking ecosconfig you need to
|
Before invoking ecosconfig you need to
|
choose a directory in which to work. For the purposes of this tutorial,
|
choose a directory in which to work. For the purposes of this tutorial,
|
the default path will be BASE_DIR/ecos-work.
|
the default path will be BASE_DIR/ecos-work.
|
Create this directory and change to it by typing:
|
Create this directory and change to it by typing:
|
|
|
|
|
$ mkdir BASE_DIR/ecos-work
|
$ mkdir BASE_DIR/ecos-work
|
$ cd BASE_DIR/ecos-work
|
$ cd BASE_DIR/ecos-work
|
|
|
|
|
To see what options can be used with ecosconfig,
|
To see what options can be used with ecosconfig,
|
type:
|
type:
|
|
|
$ ecosconfig --help
|
$ ecosconfig --help
|
|
|
The available packages, targets and templates may be listed
|
The available packages, targets and templates may be listed
|
as follows:
|
as follows:
|
|
|
|
|
$ ecosconfig list
|
$ ecosconfig list
|
|
|
|
|
Here is sample output from ecosconfig showing
|
Here is sample output from ecosconfig showing
|
the usage message.
|
the usage message.
|
|
|
|
|
Getting help from ecosconfig
|
Getting help from ecosconfig
|
|
|
|
|
$ ecosconfig --help
|
$ ecosconfig --help
|
Usage: ecosconfig [ qualifier ... ] [ command ]
|
Usage: ecosconfig [ qualifier ... ] [ command ]
|
commands are:
|
commands are:
|
list : list repository contents
|
list : list repository contents
|
new TARGET [ TEMPLATE [ VERSION ] ] : create a configuration
|
new TARGET [ TEMPLATE [ VERSION ] ] : create a configuration
|
target TARGET : change the target hardware
|
target TARGET : change the target hardware
|
template TEMPLATE [ VERSION ] : change the template
|
template TEMPLATE [ VERSION ] : change the template
|
add PACKAGE [ PACKAGE ... ] : add package(s)
|
add PACKAGE [ PACKAGE ... ] : add package(s)
|
remove PACKAGE [ PACKAGE ... ] : remove package(s)
|
remove PACKAGE [ PACKAGE ... ] : remove package(s)
|
version VERSION PACKAGE [ PACKAGE ... ] : change version of package(s)
|
version VERSION PACKAGE [ PACKAGE ... ] : change version of package(s)
|
export FILE : export minimal config info
|
export FILE : export minimal config info
|
import FILE : import additional config info
|
import FILE : import additional config info
|
check : check the configuration
|
check : check the configuration
|
resolve : resolve conflicts
|
resolve : resolve conflicts
|
tree : create a build tree
|
tree : create a build tree
|
qualifiers are:
|
qualifiers are:
|
--config=FILE : the configuration file
|
--config=FILE : the configuration file
|
--prefix=DIRECTORY : the install prefix
|
--prefix=DIRECTORY : the install prefix
|
--srcdir=DIRECTORY : the source repository
|
--srcdir=DIRECTORY : the source repository
|
--no-resolve : disable conflict
|
--no-resolve : disable conflict
|
resolution
|
resolution
|
--version : show version and copyright
|
--version : show version and copyright
|
$
|
$
|
|
|
|
|
|
|
|
|
|
|
ecosconfig output —
|
ecosconfig output —
|
list of available packages, targets and templates
|
list of available packages, targets and templates
|
|
|
|
|
$ ecosconfig list
|
$ ecosconfig list
|
Package CYGPKG_CYGMON (CygMon support via eCos):
|
Package CYGPKG_CYGMON (CygMon support via eCos):
|
aliases: cygmon
|
aliases: cygmon
|
versions: &Version;
|
versions: &Version;
|
Package CYGPKG_DEVICES_WALLCLOCK_DALLAS_DS1742 (Wallclock driver for Dallas 1742):
|
Package CYGPKG_DEVICES_WALLCLOCK_DALLAS_DS1742 (Wallclock driver for Dallas 1742):
|
aliases: devices_wallclock_ds1742 device_wallclock_ds1742
|
aliases: devices_wallclock_ds1742 device_wallclock_ds1742
|
versions: &Version;
|
versions: &Version;
|
Package CYGPKG_DEVICES_WALLCLOCK_SH3 (Wallclock driver for SH3 RTC module):
|
Package CYGPKG_DEVICES_WALLCLOCK_SH3 (Wallclock driver for SH3 RTC module):
|
aliases: devices_wallclock_sh3 device_wallclock_sh3
|
aliases: devices_wallclock_sh3 device_wallclock_sh3
|
versions: &Version;
|
versions: &Version;
|
Package CYGPKG_DEVICES_WATCHDOG_ARM_AEB (Watchdog driver for ARM/AEB board):
|
Package CYGPKG_DEVICES_WATCHDOG_ARM_AEB (Watchdog driver for ARM/AEB board):
|
aliases: devices_watchdog_aeb device_watchdog_aeb
|
aliases: devices_watchdog_aeb device_watchdog_aeb
|
versions: &Version;
|
versions: &Version;
|
Package CYGPKG_DEVICES_WATCHDOG_ARM_EBSA285 (Watchdog driver for ARM/EBSA285 board):
|
Package CYGPKG_DEVICES_WATCHDOG_ARM_EBSA285 (Watchdog driver for ARM/EBSA285 board):
|
aliases: devices_watchdog_ebsa285 device_watchdog_ebsa285
|
aliases: devices_watchdog_ebsa285 device_watchdog_ebsa285
|
versions: &Version;
|
versions: &Version;
|
…
|
…
|
|
|
|
|
|
|
|
|
|
|
Selecting a Target
|
Selecting a Target
|
|
|
To configure for a listed target, type:
|
To configure for a listed target, type:
|
|
|
|
|
$ ecosconfig new <target>
|
$ ecosconfig new <target>
|
|
|
|
|
For example, to configure for the ARM PID development board,
|
For example, to configure for the ARM PID development board,
|
type:
|
type:
|
|
|
|
|
$ ecosconfig new pid
|
$ ecosconfig new pid
|
|
|
|
|
You can then edit the generated file,
|
You can then edit the generated file,
|
ecos.ecc, setting the options as required for the
|
ecos.ecc, setting the options as required for the
|
target (endianess, CPU model, Startup type, etc.). For detailed
|
target (endianess, CPU model, Startup type, etc.). For detailed
|
information about how to edit the ecos.ecc file,
|
information about how to edit the ecos.ecc file,
|
see the CDL Writer's Guide and
|
see the CDL Writer's Guide and
|
LINKEND="editing-an-ecos-savefile">.
|
LINKEND="editing-an-ecos-savefile">.
|
|
|
|
|
Create a build tree for the configured target by typing:
|
Create a build tree for the configured target by typing:
|
|
|
|
|
$ ecosconfig tree
|
$ ecosconfig tree
|
|
|
|
|
|
|
If there are any problem with the configuration,
|
If there are any problem with the configuration,
|
ecosconfig will tell you. The most likely cause of
|
ecosconfig will tell you. The most likely cause of
|
this is mistakes when editing the ecos.ecc file.
|
this is mistakes when editing the ecos.ecc file.
|
You can check whether the configuration you have made is correct,
|
You can check whether the configuration you have made is correct,
|
without building the tree with the following command:
|
without building the tree with the following command:
|
|
|
|
|
|
|
$ ecosconfig check
|
$ ecosconfig check
|
|
|
|
|
|
|
If this reports any conflicts you can get
|
If this reports any conflicts you can get
|
ecosconfig to try and resolve them itself by typing:
|
ecosconfig to try and resolve them itself by typing:
|
|
|
|
|
|
|
$ ecosconfig resolve
|
$ ecosconfig resolve
|
|
|
|
|
|
|
See for more details.
|
See for more details.
|
|
|
|
|
You can now run the command make or make
|
You can now run the command make or make
|
tests, after which you will be at the same point you
|
tests, after which you will be at the same point you
|
would be after running the Configuration Tool
|
would be after running the Configuration Tool
|
— you can start developing your own applications,
|
— you can start developing your own applications,
|
following the steps in .
|
following the steps in .
|
|
|
The procedure shown above allows you to do very coarse-grained
|
The procedure shown above allows you to do very coarse-grained
|
configuration of the eCos kernel: you can select which packages
|
configuration of the eCos kernel: you can select which packages
|
to include in your kernel, and give target and start-up options.
|
to include in your kernel, and give target and start-up options.
|
But you cannot select components within a package, or set the very
|
But you cannot select components within a package, or set the very
|
fine-grained options.
|
fine-grained options.
|
|
|
To select fine-grained configuration options you will need to
|
To select fine-grained configuration options you will need to
|
edit the configuration file ecos.ecc in the
|
edit the configuration file ecos.ecc in the
|
current directory and regenerate the build tree.
|
current directory and regenerate the build tree.
|
|
|
|
|
You should follow the manual configuration process described
|
You should follow the manual configuration process described
|
above very carefully, and you should read the comments in each file
|
above very carefully, and you should read the comments in each file
|
to see when one option depends on other options or packages being
|
to see when one option depends on other options or packages being
|
enabled or disabled. If you do not, you might end up with an inconsistently
|
enabled or disabled. If you do not, you might end up with an inconsistently
|
configured kernel which could fail to build or might execute
|
configured kernel which could fail to build or might execute
|
incorrectly.
|
incorrectly.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Running an eCos Test Case
|
Running an eCos Test Case
|
|
|
In or
|
In or
|
LINKEND="using-ecosconfig-on-linux"> you created the eCos test cases
|
LINKEND="using-ecosconfig-on-linux"> you created the eCos test cases
|
as part of the build process. Now it is time to try and run one.
|
as part of the build process. Now it is time to try and run one.
|
|
|
|
|
|
|
|
|
|
|
Using the Configuration Tool
|
Using the Configuration Tool
|
|
|
Test executables that have been linked using the
|
Test executables that have been linked using the
|
Build->Tests operation against the current
|
Build->Tests operation against the current
|
configuration can be executed by selecting Tools->Run
|
configuration can be executed by selecting Tools->Run
|
Tests.
|
Tests.
|
|
|
When a test run is invoked, a property sheet is displayed, see
|
When a test run is invoked, a property sheet is displayed, see
|
. Press the Uncheck
|
. Press the Uncheck
|
All button and then find and check just one test,
|
All button and then find and check just one test,
|
bin_sem0 for example.
|
bin_sem0 for example.
|
|
|
|
|
|
|
Run tests
|
Run tests
|
![]()
|
![]()
|
|
|
|
|
|
|
Now press the Properties button to set up
|
Now press the Properties button to set up
|
communications with the target. This will bring up a properties dialog
|
communications with the target. This will bring up a properties dialog
|
shown in . If you have
|
shown in . If you have
|
connected the target board via a serial cable, check the
|
connected the target board via a serial cable, check the
|
Serial radio button, and select the serial port
|
Serial radio button, and select the serial port
|
and baud rate for the board. If the target is connected via the
|
and baud rate for the board. If the target is connected via the
|
network select the TCP/IP button and enter the IP
|
network select the TCP/IP button and enter the IP
|
address that the board has been given, and the port number (usually
|
address that the board has been given, and the port number (usually
|
9000).
|
9000).
|
|
|
|
|
|
|
Properties dialog box
|
Properties dialog box
|
![]()
|
![]()
|
|
|
|
|
|
|
Click OK on this dialog and go back to the Run
|
Click OK on this dialog and go back to the Run
|
Tests dialog. Press the Run button and
|
Tests dialog. Press the Run button and
|
the selected test will be downloaded and run. The
|
the selected test will be downloaded and run. The
|
Output tab will show you how this is
|
Output tab will show you how this is
|
progressing. If it seems to stop for a long time, check that the
|
progressing. If it seems to stop for a long time, check that the
|
target board is correctly connected, and that eCos has been correctly
|
target board is correctly connected, and that eCos has been correctly
|
configured -- especially the start-up type.
|
configured -- especially the start-up type.
|
|
|
|
|
|
|
When the program runs you should see a couple of line similar to this appear:
|
When the program runs you should see a couple of line similar to this appear:
|
|
|
|
|
|
|
PASS:<Binary Semaphore 0 OK>
|
PASS:<Binary Semaphore 0 OK>
|
EXIT:<done>
|
EXIT:<done>
|
|
|
|
|
|
|
This indicates that the test has run successfully.
|
This indicates that the test has run successfully.
|
|
|
|
|
See for
|
See for
|
further details.
|
further details.
|
|
|
|
|
|
|
|
|
|
|
|
|
Using the command line
|
Using the command line
|
|
|
Start a command shell (such as a Cygwin shell window in Windows)
|
Start a command shell (such as a Cygwin shell window in Windows)
|
with the environment variables set as described in the toolchain
|
with the environment variables set as described in the toolchain
|
documentation. Change to the directory in which you set up your build
|
documentation. Change to the directory in which you set up your build
|
tree, and invoke GDB on the test
|
tree, and invoke GDB on the test
|
program.
|
program.
|
|
|
To run the bin_sem0 test (which will
|
To run the bin_sem0 test (which will
|
test the kernel for the correct creation and destruction of binary
|
test the kernel for the correct creation and destruction of binary
|
semaphores) type:
|
semaphores) type:
|
|
|
|
|
$ TARGET-gdb -nw install/tests/kernel/&Version;/tests/bin_sem0
|
$ TARGET-gdb -nw install/tests/kernel/&Version;/tests/bin_sem0
|
|
|
|
|
You should see output similar to the following in the command
|
You should see output similar to the following in the command
|
window:
|
window:
|
|
|
|
|
GNU gdb THIS-GDB-VERSION
|
GNU gdb THIS-GDB-VERSION
|
Copyright 2001 Free Software Foundation, Inc.
|
Copyright 2001 Free Software Foundation, Inc.
|
GDB is free software, covered by the GNU General Public License, and you are
|
GDB is free software, covered by the GNU General Public License, and you are
|
welcome to change it and/or distribute copies of it under certain conditions.
|
welcome to change it and/or distribute copies of it under certain conditions.
|
Type "show copying" to see the conditions.
|
Type "show copying" to see the conditions.
|
There is absolutely no warranty for GDB. Type "show warranty" for details.
|
There is absolutely no warranty for GDB. Type "show warranty" for details.
|
This GDB was configured as "--host=THIS-HOST --target=THIS-TARGET".
|
This GDB was configured as "--host=THIS-HOST --target=THIS-TARGET".
|
(gdb)
|
(gdb)
|
|
|
|
|
If you are trying to run a synthetic target test on Linux, skip the following connection and download
|
-->Linux, skip the following connection and download
|
steps. Otherwise, connect to the target by typing:
|
steps. Otherwise, connect to the target by typing:
|
|
|
|
|
(gdb) set remotebaud 38400
|
(gdb) set remotebaud 38400
|
(gdb) target remote /dev/ttyS0
|
(gdb) target remote /dev/ttyS0
|
|
|
on Linux or
|
on Linux or
|
|
|
(gdb) set remotebaud 38400
|
(gdb) set remotebaud 38400
|
(gdb) target remote com1
|
(gdb) target remote com1
|
|
|
on Windows or
|
on Windows or
|
|
|
(gdb) target sim
|
(gdb) target sim
|
|
|
to use a simulator in either host O/S.
|
to use a simulator in either host O/S.
|
|
|
|
|
Check the documentation for the target board for the actual baud rate
|
Check the documentation for the target board for the actual baud rate
|
to use when connecting to real targets.
|
to use when connecting to real targets.
|
|
|
|
|
|
|
You will see output similar to the following:
|
You will see output similar to the following:
|
|
|
|
|
Remote debugging using /dev/ttyS1
|
Remote debugging using /dev/ttyS1
|
0x0000d50c in ?? ()
|
0x0000d50c in ?? ()
|
at BASE_DIR/kernel/&Version;/src/common/kapi.cxx:345
|
at BASE_DIR/kernel/&Version;/src/common/kapi.cxx:345
|
|
|
Current language: auto; currently c++
|
Current language: auto; currently c++
|
(gdb)
|
(gdb)
|
|
|
|
|
|
|
Or if you are using the simulator:
|
Or if you are using the simulator:
|
|
|
|
|
|
|
Connected to the simulator.
|
Connected to the simulator.
|
(gdb)
|
(gdb)
|
|
|
|
|
Now download the program to the target with
|
Now download the program to the target with
|
|
|
|
|
(gdb) load
|
(gdb) load
|
|
|
|
|
You should see output similar to the following on your screen:
|
You should see output similar to the following on your screen:
|
|
|
|
|
Loading section .text, size 0x4b04 lma 0x108000
|
Loading section .text, size 0x4b04 lma 0x108000
|
Loading section .rodata, size 0x738 lma 0x10cb08
|
Loading section .rodata, size 0x738 lma 0x10cb08
|
Loading section .data, size 0x1c0 lma 0x10d240
|
Loading section .data, size 0x1c0 lma 0x10d240
|
Start address 0x108000, load size 21500
|
Start address 0x108000, load size 21500
|
Transfer rate: 24571 bits/sec, 311 bytes/write.
|
Transfer rate: 24571 bits/sec, 311 bytes/write.
|
(gdb)
|
(gdb)
|
|
|
|
|
You are now ready to run your program. If you type:
|
You are now ready to run your program. If you type:
|
|
|
|
|
(gdb) continue
|
(gdb) continue
|
|
|
|
|
you will see output similar to the following:
|
you will see output similar to the following:
|
|
|
|
|
Continuing.
|
Continuing.
|
PASS:<Binary Semaphore 0 OK>
|
PASS:<Binary Semaphore 0 OK>
|
EXIT:<done>
|
EXIT:<done>
|
|
|
|
|
|
|
If you are using a simulator or the synthetic target rather
|
If you are using a simulator or the synthetic target rather
|
than real hardware, you must use the GDB command
|
than real hardware, you must use the GDB command
|
“run” rather than “continue” to
|
“run” rather than “continue” to
|
start your program.
|
start your program.
|
|
|
|
|
You can terminate your GDB session with
|
You can terminate your GDB session with
|
Control+C, otherwise it will sit in the
|
Control+C, otherwise it will sit in the
|
“idle” thread and use up CPU time. This is not a problem
|
“idle” thread and use up CPU time. This is not a problem
|
with real targets, but may have undesirable effects in simulated or
|
with real targets, but may have undesirable effects in simulated or
|
synthetic targets. Type quit and you are
|
synthetic targets. Type quit and you are
|
done.
|
done.
|
|
|
|
|
|
|
|
|
|
|
|
|
Testing Filters
|
Testing Filters
|
|
|
While most test cases today run solely in the target environment,
|
While most test cases today run solely in the target environment,
|
some packages may require external testing infrastructure and/or
|
some packages may require external testing infrastructure and/or
|
feedback from the external environment to do complete testing.
|
feedback from the external environment to do complete testing.
|
|
|
The serial package is an example of this. The network package
|
The serial package is an example of this. The network package
|
also contains some tests that require programs to be run on a
|
also contains some tests that require programs to be run on a
|
host. See the network Tests and Demonstrations
|
host. See the network Tests and Demonstrations
|
section in the network documentation in the eCos Reference
|
section in the network documentation in the eCos Reference
|
Guide. Here we will concentrate on the serial tests since
|
Guide. Here we will concentrate on the serial tests since
|
these are applicable to more targets.
|
these are applicable to more targets.
|
|
|
|
|
Since the serial line is also used for communication with
|
Since the serial line is also used for communication with
|
GDB, a filter is inserted in the communication pathway between
|
GDB, a filter is inserted in the communication pathway between
|
GDB and the serial device which is connected to the hardware target.
|
GDB and the serial device which is connected to the hardware target.
|
The filter forwards all communication between the two, but also
|
The filter forwards all communication between the two, but also
|
listens for special commands embedded in the data stream from the
|
listens for special commands embedded in the data stream from the
|
target.
|
target.
|
|
|
When such a command is seen, the filter stops forwarding data
|
When such a command is seen, the filter stops forwarding data
|
to GDB from the target and enters a special mode. In this mode
|
to GDB from the target and enters a special mode. In this mode
|
the test case running on the target is able to control the filter,
|
the test case running on the target is able to control the filter,
|
commanding it to run various tests. While these tests run, GDB is
|
commanding it to run various tests. While these tests run, GDB is
|
isolated from the target.
|
isolated from the target.
|
|
|
As the test completes (or if the filter detects a target crash)
|
As the test completes (or if the filter detects a target crash)
|
the communication path between GDB and the hardware target is re-established,
|
the communication path between GDB and the hardware target is re-established,
|
allowing GDB to resume control.
|
allowing GDB to resume control.
|
|
|
In theory, it is possible to extend the filter to provide
|
In theory, it is possible to extend the filter to provide
|
a generic framework for other target-external testing components,
|
a generic framework for other target-external testing components,
|
thus decoupling the testing infrastructure from the (possibly limited)
|
thus decoupling the testing infrastructure from the (possibly limited)
|
communication means provided by the target (serial, JTAG, Ethernet,
|
communication means provided by the target (serial, JTAG, Ethernet,
|
etc).
|
etc).
|
|
|
Another advantage is that the host tools do not need to
|
Another advantage is that the host tools do not need to
|
know about the various testing environments required by the eCos
|
know about the various testing environments required by the eCos
|
packages, since all contact with the target continues to happen
|
packages, since all contact with the target continues to happen
|
via GDB.
|
via GDB.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Building and Running Sample Applications
|
Building and Running Sample Applications
|
|
|
The example programs in this tutorial are included, along
|
The example programs in this tutorial are included, along
|
with a Makefile, in the examples directory
|
with a Makefile, in the examples directory
|
of the eCos distribution. The first program you will run is a hello
|
of the eCos distribution. The first program you will run is a hello
|
world-style application, then you will run a more complex
|
world-style application, then you will run a more complex
|
application that demonstrates the creation of threads and the use
|
application that demonstrates the creation of threads and the use
|
of cyg_thread_delay(), and finally you will run
|
of cyg_thread_delay(), and finally you will run
|
one that uses clocks and alarm handlers.
|
one that uses clocks and alarm handlers.
|
|
|
The Makefile depends on an externally
|
The Makefile depends on an externally
|
defined variable to find the eCos library and header files. This
|
defined variable to find the eCos library and header files. This
|
variable is INSTALL_DIR and must be set to the
|
variable is INSTALL_DIR and must be set to the
|
pathname of the install directory created in
|
pathname of the install directory created in
|
linkend="using-configtool-windows-linux">.
|
linkend="using-configtool-windows-linux">.
|
|
|
|
|
|
|
INSTALL_DIR may be either be set in the shell
|
INSTALL_DIR may be either be set in the shell
|
environment or may be supplied on the command line. To set it in the
|
environment or may be supplied on the command line. To set it in the
|
shell do the following in a bash shell:
|
shell do the following in a bash shell:
|
|
|
|
|
|
|
$ export INSTALL_DIR=BASE_DIR/ecos-work/arm_install
|
$ export INSTALL_DIR=BASE_DIR/ecos-work/arm_install
|
|
|
|
|
|
|
You can then run make without any extra parameters
|
You can then run make without any extra parameters
|
to build the examples.
|
to build the examples.
|
|
|
|
|
|
|
Alternatively, if you can do the following:
|
Alternatively, if you can do the following:
|
|
|
|
|
|
|
$ make INSTALL_DIR=BASE_DIR/ecos-work/arm_install
|
$ make INSTALL_DIR=BASE_DIR/ecos-work/arm_install
|
|
|
|
|
|
|
|
|
|
|
eCos Hello World
|
eCos Hello World
|
|
|
The following code is found in the file hello.c
|
The following code is found in the file hello.c
|
in the examples directory:
|
in the examples directory:
|
|
|
|
|
eCos hello world program listing
|
eCos hello world program listing
|
|
|
|
|
/* this is a simple hello world program */
|
/* this is a simple hello world program */
|
#include <stdio.h>
|
#include <stdio.h>
|
int main(void)
|
int main(void)
|
{
|
{
|
printf("Hello, eCos world!\n");
|
printf("Hello, eCos world!\n");
|
return 0;
|
return 0;
|
}
|
}
|
|
|
|
|
To compile this or any other program that is not part of the
|
To compile this or any other program that is not part of the
|
eCos distribution, you can follow the procedures described below. Type
|
eCos distribution, you can follow the procedures described below. Type
|
this explicit compilation command (assuming your current working
|
this explicit compilation command (assuming your current working
|
directory is also where you built the eCos kernel):
|
directory is also where you built the eCos kernel):
|
|
|
|
|
$ TARGET-gcc -g -IBASE_DIR/ecos-work/install/include hello.c -LBASE_DIR/ecos-work/install/lib -Ttarget.ld -nostdlib
|
$ TARGET-gcc -g -IBASE_DIR/ecos-work/install/include hello.c -LBASE_DIR/ecos-work/install/lib -Ttarget.ld -nostdlib
|
|
|
|
|
The compilation command above contains some standard GCC
|
The compilation command above contains some standard GCC
|
options (for example, enables debugging), as well
|
options (for example, enables debugging), as well
|
as some mention of paths
|
as some mention of paths
|
( allows files
|
( allows files
|
like cyg/kernel/kapi.h to be found, and
|
like cyg/kernel/kapi.h to be found, and
|
allows the linker to
|
allows the linker to
|
find ).
|
find ).
|
|
|
The executable program will be called a.out.
|
The executable program will be called a.out.
|
|
|
|
|
Some target systems require special options to be passed to
|
Some target systems require special options to be passed to
|
gcc to compile correctly for that system. Please examine the Makefile
|
gcc to compile correctly for that system. Please examine the Makefile
|
in the examples directory to see if this applies to your target.
|
in the examples directory to see if this applies to your target.
|
|
|
|
|
You can now run the resulting program using GDB in exactly the
|
You can now run the resulting program using GDB in exactly the
|
same the way you ran the test case before. The procedure will be the
|
same the way you ran the test case before. The procedure will be the
|
same, but this time run
|
same, but this time run
|
TARGET-gdb specifying
|
TARGET-gdb specifying
|
on the command line:
|
on the command line:
|
|
|
|
|
$ TARGET-gdb -nw a.out
|
$ TARGET-gdb -nw a.out
|
|
|
|
|
For targets other than the synthetic linux target, you should
|
For targets other than the synthetic linux target, you should
|
now run the usual GDB commands described earlier. Once this is done,
|
now run the usual GDB commands described earlier. Once this is done,
|
typing the command "continue" at the (gdb) prompt ("run" for
|
typing the command "continue" at the (gdb) prompt ("run" for
|
simulators) will allow the program to execute and print the string
|
simulators) will allow the program to execute and print the string
|
"Hello, eCos world!" on your screen.
|
"Hello, eCos world!" on your screen.
|
|
|
On the synthetic linux target, you may use the "run" command
|
On the synthetic linux target, you may use the "run" command
|
immediately - you do not need to connect to the target, nor use the
|
immediately - you do not need to connect to the target, nor use the
|
"load" command.
|
"load" command.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
A Sample Program with Two Threads
|
A Sample Program with Two Threads
|
|
|
Below is a program that uses some of eCos' system calls. It
|
Below is a program that uses some of eCos' system calls. It
|
creates two threads, each of which goes into an infinite loop in which
|
creates two threads, each of which goes into an infinite loop in which
|
it sleeps for a while (using cyg_thread_delay()). This code is found
|
it sleeps for a while (using cyg_thread_delay()). This code is found
|
in the file twothreads.c
|
in the file twothreads.c
|
in the examples directory.
|
in the examples directory.
|
|
|
|
|
eCos two-threaded program listing
|
eCos two-threaded program listing
|
|
|
|
|
#include <cyg/kernel/kapi.h>
|
#include <cyg/kernel/kapi.h>
|
#include <stdio.h>
|
#include <stdio.h>
|
#include <math.h>
|
#include <math.h>
|
#include <stdlib.h>
|
#include <stdlib.h>
|
|
|
/* now declare (and allocate space for) some kernel objects,
|
/* now declare (and allocate space for) some kernel objects,
|
like the two threads we will use */
|
like the two threads we will use */
|
cyg_thread thread_s[2]; /* space for two thread objects */
|
cyg_thread thread_s[2]; /* space for two thread objects */
|
|
|
char stack[2][4096]; /* space for two 4K stacks */
|
char stack[2][4096]; /* space for two 4K stacks */
|
|
|
/* now the handles for the threads */
|
/* now the handles for the threads */
|
cyg_handle_t simple_threadA, simple_threadB;
|
cyg_handle_t simple_threadA, simple_threadB;
|
|
|
/* and now variables for the procedure which is the thread */
|
/* and now variables for the procedure which is the thread */
|
cyg_thread_entry_t simple_program;
|
cyg_thread_entry_t simple_program;
|
|
|
/* and now a mutex to protect calls to the C library */
|
/* and now a mutex to protect calls to the C library */
|
cyg_mutex_t cliblock;
|
cyg_mutex_t cliblock;
|
|
|
/* we install our own startup routine which sets up threads */
|
/* we install our own startup routine which sets up threads */
|
void cyg_user_start(void)
|
void cyg_user_start(void)
|
{
|
{
|
printf("Entering twothreads' cyg_user_start() function\n");
|
printf("Entering twothreads' cyg_user_start() function\n");
|
|
|
cyg_mutex_init(&cliblock);
|
cyg_mutex_init(&cliblock);
|
|
|
cyg_thread_create(4, simple_program, (cyg_addrword_t) 0,
|
cyg_thread_create(4, simple_program, (cyg_addrword_t) 0,
|
"Thread A", (void *) stack[0], 4096,
|
"Thread A", (void *) stack[0], 4096,
|
&simple_threadA, &thread_s[0]);
|
&simple_threadA, &thread_s[0]);
|
cyg_thread_create(4, simple_program, (cyg_addrword_t) 1,
|
cyg_thread_create(4, simple_program, (cyg_addrword_t) 1,
|
"Thread B", (void *) stack[1], 4096,
|
"Thread B", (void *) stack[1], 4096,
|
&simple_threadB, &thread_s[1]);
|
&simple_threadB, &thread_s[1]);
|
|
|
cyg_thread_resume(simple_threadA);
|
cyg_thread_resume(simple_threadA);
|
cyg_thread_resume(simple_threadB);
|
cyg_thread_resume(simple_threadB);
|
}
|
}
|
|
|
/* this is a simple program which runs in a thread */
|
/* this is a simple program which runs in a thread */
|
void simple_program(cyg_addrword_t data)
|
void simple_program(cyg_addrword_t data)
|
{
|
{
|
int message = (int) data;
|
int message = (int) data;
|
int delay;
|
int delay;
|
|
|
printf("Beginning execution; thread data is %d\n", message);
|
printf("Beginning execution; thread data is %d\n", message);
|
|
|
cyg_thread_delay(200);
|
cyg_thread_delay(200);
|
|
|
for (;;) {
|
for (;;) {
|
delay = 200 + (rand() % 50);
|
delay = 200 + (rand() % 50);
|
|
|
/* note: printf() must be protected by a
|
/* note: printf() must be protected by a
|
call to cyg_mutex_lock() */
|
call to cyg_mutex_lock() */
|
cyg_mutex_lock(&cliblock); {
|
cyg_mutex_lock(&cliblock); {
|
printf("Thread %d: and now a delay of %d clock ticks\n",
|
printf("Thread %d: and now a delay of %d clock ticks\n",
|
message, delay);
|
message, delay);
|
}
|
}
|
cyg_mutex_unlock(&cliblock);
|
cyg_mutex_unlock(&cliblock);
|
cyg_thread_delay(delay);
|
cyg_thread_delay(delay);
|
}
|
}
|
}
|
}
|
|
|
|
|
|
|
When you run the program (by typing continue at
|
When you run the program (by typing continue at
|
the (gdb) prompt) the output should look like
|
the (gdb) prompt) the output should look like
|
this:
|
this:
|
|
|
|
|
Starting program: BASE_DIR/examples/twothreads.exe
|
Starting program: BASE_DIR/examples/twothreads.exe
|
Entering twothreads' cyg_user_start()
|
Entering twothreads' cyg_user_start()
|
function
|
function
|
Beginning execution; thread data is 0
|
Beginning execution; thread data is 0
|
Beginning execution; thread data is 1
|
Beginning execution; thread data is 1
|
Thread 0: and now a delay of 240 clock ticks
|
Thread 0: and now a delay of 240 clock ticks
|
Thread 1: and now a delay of 225 clock ticks
|
Thread 1: and now a delay of 225 clock ticks
|
Thread 1: and now a delay of 234 clock ticks
|
Thread 1: and now a delay of 234 clock ticks
|
Thread 0: and now a delay of 231 clock ticks
|
Thread 0: and now a delay of 231 clock ticks
|
Thread 1: and now a delay of 224 clock ticks
|
Thread 1: and now a delay of 224 clock ticks
|
Thread 0: and now a delay of 249 clock ticks
|
Thread 0: and now a delay of 249 clock ticks
|
Thread 1: and now a delay of 202 clock ticks
|
Thread 1: and now a delay of 202 clock ticks
|
Thread 0: and now a delay of 235 clock ticks
|
Thread 0: and now a delay of 235 clock ticks
|
|
|
|
|
|
|
When running in a simulator the
|
When running in a simulator the
|
delays might be quite long. On a hardware board (where the clock
|
delays might be quite long. On a hardware board (where the clock
|
speed is 100 ticks/second) the delays should average to
|
speed is 100 ticks/second) the delays should average to
|
about 2.25 seconds. In simulation, the delay will depend on the
|
about 2.25 seconds. In simulation, the delay will depend on the
|
speed of the host processor and will almost always be much slower than
|
speed of the host processor and will almost always be much slower than
|
the actual board. You might want to reduce the delay parameter when running
|
the actual board. You might want to reduce the delay parameter when running
|
in simulation.
|
in simulation.
|
|
|
|
|
|
|
|
|
shows how this
|
shows how this
|
multitasking program executes. Note that apart from the thread
|
multitasking program executes. Note that apart from the thread
|
creation system calls, this program also creates and uses a
|
creation system calls, this program also creates and uses a
|
mutex for synchronization
|
mutex for synchronization
|
between the printf() calls in the two
|
between the printf() calls in the two
|
threads. This is because the C library standard I/O (by default) is
|
threads. This is because the C library standard I/O (by default) is
|
configured not to be thread-safe, which means that if more than one
|
configured not to be thread-safe, which means that if more than one
|
thread is using standard I/O they might corrupt each other. This is
|
thread is using standard I/O they might corrupt each other. This is
|
fixed by a mutual exclusion (or mutex) lockout
|
fixed by a mutual exclusion (or mutex) lockout
|
mechanism: the threads do not call printf() until
|
mechanism: the threads do not call printf() until
|
cyg_mutex_lock() has returned, which only happens
|
cyg_mutex_lock() has returned, which only happens
|
when the other thread calls
|
when the other thread calls
|
cyg_mutex_unlock().
|
cyg_mutex_unlock().
|
|
|
You could avoid using the mutex by configuring the C library to
|
You could avoid using the mutex by configuring the C library to
|
be thread-safe (by selecting the component
|
be thread-safe (by selecting the component
|
CYGSEM_LIBC_STDIO_THREAD_SAFE_STREAMS).
|
CYGSEM_LIBC_STDIO_THREAD_SAFE_STREAMS).
|
|
|
|
|
ID="FIGURE-TWOTHREADS-WITH-SIMPLE-PRINTS"> Two
|
ID="FIGURE-TWOTHREADS-WITH-SIMPLE-PRINTS"> Two
|
threads with simple print statements after random delays
|
threads with simple print statements after random delays
|
![]()
|
![]()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
More Features — Clocks and Alarm
|
More Features — Clocks and Alarm
|
Handlers
|
Handlers
|
|
|
If a program wanted to execute a task at a given time, or
|
If a program wanted to execute a task at a given time, or
|
periodically, it could do it in an inefficient way by sitting in a
|
periodically, it could do it in an inefficient way by sitting in a
|
loop and checking the real-time clock to see if the proper amount of
|
loop and checking the real-time clock to see if the proper amount of
|
time has elapsed. But operating systems usually provide system calls
|
time has elapsed. But operating systems usually provide system calls
|
which allow the program to be informed at the desired time.
|
which allow the program to be informed at the desired time.
|
|
|
eCos provides a rich timekeeping formalism, involving
|
eCos provides a rich timekeeping formalism, involving
|
counters, clocks,
|
counters, clocks,
|
alarms, and timers. The
|
alarms, and timers. The
|
precise definition, relationship, and motivation of these features is
|
precise definition, relationship, and motivation of these features is
|
beyond the scope of this tutorial, but these examples illustrate how
|
beyond the scope of this tutorial, but these examples illustrate how
|
to set up basic periodic tasks.
|
to set up basic periodic tasks.
|
|
|
Alarms are events that happen at
|
Alarms are events that happen at
|
a given time, either once or periodically. A thread associates an
|
a given time, either once or periodically. A thread associates an
|
alarm handling function with the alarm, so that the function will
|
alarm handling function with the alarm, so that the function will
|
be invoked every time the alarm “goes off”.
|
be invoked every time the alarm “goes off”.
|
|
|
|
|
|
|
|
|
A Sample Program with Alarms
|
A Sample Program with Alarms
|
|
|
simple-alarm.c (in
|
simple-alarm.c (in
|
the examples directory) is a short program that creates a thread that
|
the examples directory) is a short program that creates a thread that
|
creates an alarm. The alarm is handled by the function
|
creates an alarm. The alarm is handled by the function
|
test_alarm_func(), which sets a global
|
test_alarm_func(), which sets a global
|
variable. When the main thread of execution sees that the variable has
|
variable. When the main thread of execution sees that the variable has
|
changed, it prints a message.
|
changed, it prints a message.
|
|
|
|
|
A sample program that creates an alarm
|
A sample program that creates an alarm
|
|
|
|
|
/* this is a very simple program meant to demonstrate
|
/* this is a very simple program meant to demonstrate
|
a basic use of time, alarms and alarm-handling functions in eCos */
|
a basic use of time, alarms and alarm-handling functions in eCos */
|
|
|
#include <cyg/kernel/kapi.h>
|
#include <cyg/kernel/kapi.h>
|
|
|
#include <stdio.h>
|
#include <stdio.h>
|
|
|
#define NTHREADS 1
|
#define NTHREADS 1
|
#define STACKSIZE 4096
|
#define STACKSIZE 4096
|
|
|
static cyg_handle_t thread[NTHREADS];
|
static cyg_handle_t thread[NTHREADS];
|
|
|
static cyg_thread thread_obj[NTHREADS];
|
static cyg_thread thread_obj[NTHREADS];
|
static char stack[NTHREADS][STACKSIZE];
|
static char stack[NTHREADS][STACKSIZE];
|
|
|
static void alarm_prog( cyg_addrword_t data );
|
static void alarm_prog( cyg_addrword_t data );
|
|
|
/* we install our own startup routine which sets up
|
/* we install our own startup routine which sets up
|
threads and starts the scheduler */
|
threads and starts the scheduler */
|
void cyg_user_start(void)
|
void cyg_user_start(void)
|
{
|
{
|
cyg_thread_create(4, alarm_prog, (cyg_addrword_t) 0,
|
cyg_thread_create(4, alarm_prog, (cyg_addrword_t) 0,
|
"alarm_thread", (void *) stack[0],
|
"alarm_thread", (void *) stack[0],
|
STACKSIZE, &thread[0], &thread_obj[0]);
|
STACKSIZE, &thread[0], &thread_obj[0]);
|
cyg_thread_resume(thread[0]);
|
cyg_thread_resume(thread[0]);
|
}
|
}
|
|
|
/* we need to declare the alarm handling function (which is
|
/* we need to declare the alarm handling function (which is
|
defined below), so that we can pass it to cyg_alarm_initialize() */
|
defined below), so that we can pass it to cyg_alarm_initialize() */
|
cyg_alarm_t test_alarm_func;
|
cyg_alarm_t test_alarm_func;
|
|
|
/* alarm_prog() is a thread which sets up an alarm which is then
|
/* alarm_prog() is a thread which sets up an alarm which is then
|
handled by test_alarm_func() */
|
handled by test_alarm_func() */
|
static void alarm_prog(cyg_addrword_t data)
|
static void alarm_prog(cyg_addrword_t data)
|
{
|
{
|
cyg_handle_t test_counterH, system_clockH, test_alarmH;
|
cyg_handle_t test_counterH, system_clockH, test_alarmH;
|
cyg_tick_count_t ticks;
|
cyg_tick_count_t ticks;
|
cyg_alarm test_alarm;
|
cyg_alarm test_alarm;
|
unsigned how_many_alarms = 0, prev_alarms = 0, tmp_how_many;
|
unsigned how_many_alarms = 0, prev_alarms = 0, tmp_how_many;
|
|
|
system_clockH = cyg_real_time_clock();
|
system_clockH = cyg_real_time_clock();
|
cyg_clock_to_counter(system_clockH, &test_counterH);
|
cyg_clock_to_counter(system_clockH, &test_counterH);
|
cyg_alarm_create(test_counterH, test_alarm_func,
|
cyg_alarm_create(test_counterH, test_alarm_func,
|
(cyg_addrword_t) &how_many_alarms,
|
(cyg_addrword_t) &how_many_alarms,
|
&test_alarmH, &test_alarm);
|
&test_alarmH, &test_alarm);
|
cyg_alarm_initialize(test_alarmH, cyg_current_time()+200, 200);
|
cyg_alarm_initialize(test_alarmH, cyg_current_time()+200, 200);
|
|
|
/* get in a loop in which we read the current time and
|
/* get in a loop in which we read the current time and
|
print it out, just to have something scrolling by */
|
print it out, just to have something scrolling by */
|
for (;;) {
|
for (;;) {
|
ticks = cyg_current_time();
|
ticks = cyg_current_time();
|
printf("Time is %llu\n", ticks);
|
printf("Time is %llu\n", ticks);
|
/* note that we must lock access to how_many_alarms, since the
|
/* note that we must lock access to how_many_alarms, since the
|
alarm handler might change it. this involves using the
|
alarm handler might change it. this involves using the
|
annoying temporary variable tmp_how_many so that I can keep the
|
annoying temporary variable tmp_how_many so that I can keep the
|
critical region short */
|
critical region short */
|
cyg_scheduler_lock();
|
cyg_scheduler_lock();
|
tmp_how_many = how_many_alarms;
|
tmp_how_many = how_many_alarms;
|
cyg_scheduler_unlock();
|
cyg_scheduler_unlock();
|
if (prev_alarms != tmp_how_many) {
|
if (prev_alarms != tmp_how_many) {
|
printf(" --- alarm calls so far: %u\n", tmp_how_many);
|
printf(" --- alarm calls so far: %u\n", tmp_how_many);
|
prev_alarms = tmp_how_many;
|
prev_alarms = tmp_how_many;
|
}
|
}
|
cyg_thread_delay(30);
|
cyg_thread_delay(30);
|
}
|
}
|
}
|
}
|
|
|
/* test_alarm_func() is invoked as an alarm handler, so
|
/* test_alarm_func() is invoked as an alarm handler, so
|
it should be quick and simple. in this case it increments
|
it should be quick and simple. in this case it increments
|
the data that is passed to it. */
|
the data that is passed to it. */
|
void test_alarm_func(cyg_handle_t alarmH, cyg_addrword_t data)
|
void test_alarm_func(cyg_handle_t alarmH, cyg_addrword_t data)
|
{
|
{
|
++*((unsigned *) data);
|
++*((unsigned *) data);
|
}
|
}
|
|
|
|
|
|
|
When you run this program (by typing continue at
|
When you run this program (by typing continue at
|
the (gdb) prompt) the output should look like
|
the (gdb) prompt) the output should look like
|
this:
|
this:
|
|
|
Starting program: BASE_DIR/examples/simple-alarm.exe
|
Starting program: BASE_DIR/examples/simple-alarm.exe
|
Time is 0
|
Time is 0
|
Time is 30
|
Time is 30
|
Time is 60
|
Time is 60
|
Time is 90
|
Time is 90
|
Time is 120
|
Time is 120
|
Time is 150
|
Time is 150
|
Time is 180
|
Time is 180
|
Time is 210
|
Time is 210
|
--- alarm calls so far: 1
|
--- alarm calls so far: 1
|
Time is 240
|
Time is 240
|
Time is 270
|
Time is 270
|
Time is 300
|
Time is 300
|
Time is 330
|
Time is 330
|
Time is 360
|
Time is 360
|
Time is 390
|
Time is 390
|
Time is 420
|
Time is 420
|
--- alarm calls so far: 2
|
--- alarm calls so far: 2
|
Time is 450
|
Time is 450
|
Time is 480
|
Time is 480
|
|
|
|
|
|
|
When running in a simulator the delays
|
When running in a simulator the delays
|
might be quite long. On a hardware board (where the clock speed is 100
|
might be quite long. On a hardware board (where the clock speed is 100
|
ticks/second) the delays should average to about 0.3 seconds (and 2
|
ticks/second) the delays should average to about 0.3 seconds (and 2
|
seconds between alarms). In simulation, the delay will depend on the
|
seconds between alarms). In simulation, the delay will depend on the
|
speed of the host processor and will almost always be much slower than
|
speed of the host processor and will almost always be much slower than
|
the actual board. You might want to reduce the delay parameter when
|
the actual board. You might want to reduce the delay parameter when
|
running in simulation.
|
running in simulation.
|
|
|
|
|
Here are a few things you might notice about this program:
|
Here are a few things you might notice about this program:
|
|
|
|
|
|
|
It used the cyg_real_time_clock() function;
|
It used the cyg_real_time_clock() function;
|
this always returns a handle to the default system real-time clock.
|
--> clock.
|
|
|
|
|
|
|
Clocks are based on Clocks are based on counters, so the function cyg_alarm_create()
|
--> counters, so the function cyg_alarm_create()
|
uses a counter handle. The program used the function
|
uses a counter handle. The program used the function
|
cyg_clock_to_counter() to strip the clock handle
|
cyg_clock_to_counter() to strip the clock handle
|
to the underlying counter handle.
|
to the underlying counter handle.
|
|
|
|
|
|
|
Once the alarm is created it is
|
Once the alarm is created it is
|
initialized with cyg_alarm_initialize(), which
|
initialized with cyg_alarm_initialize(), which
|
sets the time at which the alarm should go off, as well as the period
|
sets the time at which the alarm should go off, as well as the period
|
for repeating alarms. It is set to go off at the current time and
|
for repeating alarms. It is set to go off at the current time and
|
then to repeat every 200 ticks.
|
then to repeat every 200 ticks.
|
|
|
|
|
|
|
The alarm handler function
|
The alarm handler function
|
test_alarm_func() conforms to the guidelines for
|
test_alarm_func() conforms to the guidelines for
|
writing alarm handlers and other delayed service routines: it does not invoke any
|
--> delayed service routines: it does not invoke any
|
functions which might lock the scheduler. This is discussed in detail
|
functions which might lock the scheduler. This is discussed in detail
|
in the eCos Reference Manual, in the chapter
|
in the eCos Reference Manual, in the chapter
|
The eCos Kernel.
|
The eCos Kernel.
|
|
|
|
|
|
|
There is a critical region in this program:
|
There is a critical region in this program:
|
the variable how_many_alarms is accessed in the
|
the variable how_many_alarms is accessed in the
|
main thread of control and is also modified in the alarm handler. To
|
main thread of control and is also modified in the alarm handler. To
|
prevent a possible (though unlikely) race condition on this variable,
|
prevent a possible (though unlikely) race condition on this variable,
|
access to how_many_alarms in the principal thread
|
access to how_many_alarms in the principal thread
|
is protected by calls to cyg_scheduler_lock() and
|
is protected by calls to cyg_scheduler_lock() and
|
cyg_scheduler_unlock(). When the scheduler is
|
cyg_scheduler_unlock(). When the scheduler is
|
locked, the alarm handler will not be invoked, so the problem is
|
locked, the alarm handler will not be invoked, so the problem is
|
averted.
|
averted.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|