Chapter 26. Manual Configuration
Table of Contents
eCos developers will generally use the graphical Configuration Tool for configuring an eCos system and building the target library. However, some user prefer to use command line tools. These command line tools can also be used for batch operations on all platforms, for example as part of a nightly rebuild and testing procedure.
In the current release of the system the command line tools do not provide exactly the same functionality as the graphical tool. Most importantly, there is no facility to resolve configuration conflicts interactively.
The eCos configuration system, both graphical and command line tools, are under constant development and enhancement. Developers should note that the procedures described may change considerably in future releases.
26.1. Directory Tree Structure
When building eCos there are three main directory trees to consider: the source tree, the build tree, and the install tree.
The source tree, also known as the component repository, is read- only. It is possible to use a single component repository for any number of different configurations, and it is also possible to share a component repository between multiple users by putting it on a network drive.
The build tree contains everything that is specific to a particular configuration, including header and other files that contain configuration data, and the object files that result from compiling the system sources for this configuration.
The install tree is usually located in the
install
subdirectory of the build tree. Once an
eCos system has been built, the install tree
contains all the files needed for application development including the
header files and the target library. By making copies of the install
tree after a build it is possible to separate application development
and system configuration, which may be desirable for some organizations.
26.2. Creating the Build Tree
Generating a build tree is a non-trivial operation and should not be attempted manually. Instead, eCos is shipped with a tool called ecosconfig that should be used to create a build tree.
Usually ecosconfig will be run inside the build
tree itself. If you are creating a new build tree then typically you
will create a new empty directory using the mkdir
command, cd into that directory, and then invoke
ecosconfig to create a configuration. Alternatively
you can also use the --builddir
option to specify the
build directory if the build directory is to be stored in a location
other than the current directory. By default, the configuration is
stored in a file ecos.ecc
in the current directory.
The configuration may be modified by editing this file directly.
ecosconfig itself deals with a number of coarse-
grained configuration options such as the target platform and the
packages that should be used.
The ecosconfig tool is also used subsequently to generate a build tree for a configuration. Once a build tree exists, it is possible to run ecosconfig again inside the same build tree. This will be necessary if your wish to change some of the configuration options.
ecosconfig does not generate the top-level directory of the build tree; you must do this yourself.
$ mkdir ecos-work $ cd ecos-work
The next step is to run ecosconfig:
$ ecosconfig <qualifiers> <command>
26.2.1. ecosconfig qualifiers
The available command line qualifiers for ecosconfig are as follows. Multiple qualifiers may be used on the command line:
-
--help
Provides basic usage guidelines for the available commands and qualifiers.
-
--config=<file>
Specifies an eCos configuration save file for use by the tool. By default, the file
ecos.ecc
in the current directory is used. Developers may prefer to use a common location for all their eCos configurations rather than keep the configuration information in the base of the build tree.-
--prefix=<dir>
Specifies an alternative location for the install tree. By default, the install tree resides inside the
install
directory in the build tree. Developers may prefer to locate the build tree in a temporary file hierarchy but keep the install tree in a more permanent location.-
--srcdir=<dir>
Specifies the location of the component repository. By default, the tool uses the location specified in the
ECOS_REPOSITORY
environment variable. Developers may prefer to use of this qualifier if they are working with more than one repository.-
--builddir=<dir>
Specifies an alternative location for the build directory. By default, the build directory will be created inside the current directory. Developers may prefer to locate the build tree in a temporary file hierarchy but keep the install tree in a more permanent location.
-
--no-resolve
Disables the implicit resolution of conflicts while manipulating the configuration data. developers may prefer to resolve conflicts by editing the eCos configuration save file manually.
-
--ignore-errors
,-i
By default, ecosconfig will exit with an error code if the current configuration contains any conflicts, and it is not possible to generate or update a build tree for such configurations. This qualifier causes ecosconfig to ignore such problems, and hence it is possible to generate a build tree even if there are still conflicts. Of course, there are no guarantees that the resulting system will actually do anything.
-
--compat
,-c
This option invokes the compatability mode of ecosconfig with the GUI configtool. It sets both the build and install directories of ecosconfig to the directories, relative to the configuration file, that would be created and used by the GUI configtool respectively. This option therefore cannot be used in conjuction with either the
--prefix=<dir>
or--builddir=<dir>
options. This option is useful to application developers that regularly switch between using the CLI and GUI configuration tools.-
--long
,-l
Display long listing of packages, templates, targets and attributes.
-
--verbose
,-v
Display more information.
-
--quiet
,-q
Display less information.
The --config
, --prefix
and
--srcdir
qualifiers can also be written with two arguments,
for example:
ecosconfig --srcdir <dir>
...
This simplifies filename completion with some shells.
26.2.2. ecosconfig commands
The available commands for ecosconfig are as follows:
- list [<packages> | <templates> | <targets>]
Lists the available packages, targets and templates as installed in the eCos repository. The additional options
<packages>
,<templates>
and<targets>
restrict output to packages, templates and targets respectively and include the--long
option support to provide additional information. Aliases and package versions are also reported.- new <target> [<template> [<version>]]
Creates a new eCos configuration for the specified target hardware and saves it. A software template may also be specified. By default, the template named ’default‚ is used. If the template version is not specified, the latest version is used.
- target <target>
Changes the target hardware selection for the eCos configuration. This has the effect of unloading packages supporting the target selected previously and loading the packages which support the new hardware. This command will be used typically when switching between a simulator and real hardware.
Note When switching targets between minor CPU variants, users are advised that inferred changes within common hardware packages are not reset or re-inferred unless a conflict arises as a result of the switch. For example, while a template may contain the SPI package, this package may be disabled in a configuration through inference as a result of the initial hardware lacking an SPI device. However, when switching to a processor variant with more cells (device support), such as one that includes an SPI device, the SPI package could remain disabled when the configuration is switched to the more superior variant unless it is marked as required within the CDL (i.e. it would conflict). Users are therefore advised that switching targets within a configuration may have unanticipated results and are recommended to use the process described in Section 15.2, “Switching Targets, Repositories and Versions”.
- template <template> [<version>]
Changes the template selection for the eCos configuration. This has the effect of unloading packages specified by the template selected previously and loading the packages specified by the new template. By default, the latest version of the specified template is used.
- add <packages>
Adds the specified packages to the eCos configuration. This command will be used typically when the template on which a configuration is based does not contain all the packages which are required.For example, add-on packages provided by third parties will not be known to the standard templates, so they will have to be added explicitly.
- remove <packages>
Removes the specified packages from the eCos configuration. This command will be used typically when the template on which a configuration is based contains packages which are not required.
- packages [loaded | active]
Provides package information regarding the eCos configuration rather than the eCos repository (as provided by the list command). The optional argument
loaded
(the default) will list what packages have been loaded into the eCos configuration whileactive
will list active packages. The-- long
option may also be included to provide additional information.- present <package> [<package> ...]
Tests for the presense of the packages and returns a status code of 0 if all the packages are present in the eCos configuration, or an error if not. This is useful for automated scripting of the creation of eCos configurations from the command line.
- version <version> <packages>
Selects the specified version of a number of packages in the eCos configuration. By default, the most recent version of each package is used. This command will be used typically when an older version of a package is required.
- check
Presents the following information concerning the current configuration:
the selected target hardware
the selected template
additional packages
removed packages
the selected version of packages where this is not the most recent version
conflicts in the current configuration
- resolve
Resolves conflicts identified in the current eCos configuration by invoking an inference capability. Resolved conflicts are reported, but not all conflicts may be resolvable. This command will be used typically following manual editing of the configuration.
-
export
<file>
Exports a minimal eCos configuration save file with the specified name. This file contains only those options which do not have their default value. Such files are used typically to transfer option values from one configuration to another.
-
import
<file>
Imports a minimal eCos configuration save file with the specified name. The values of those options specified in the file are applied to the current configuration.
- tree
Generates a build tree based on the current eCos configuration. This command will be used typically just before building eCos.Normally a build tree can only be generated if if the configuration has no unresolved conflicts, but
--ignore-errors
can be used to override this.- get_comment
User comments within eCos configurations are not preserved when modified with the configtool or ecosconfig. However, from eCosPro version 4.0 and above, the eCos Configuration file (normal prefix <
.ecc
>) the eCos Configuration file can contain user comments. The are located at the top of the Configuration file and can be fetched with this command. For example, both tools use User comments to store additional matedata information such as the name of the eCosPro profile used to generate the configuration. If no profile information is provided to either the configtool or ecosconfig, both tools will use this comment to set a default profile for the configuration of the profile is valid.- add_comment <comment>
Append the comment
<comment>
to the user comments within the eCos configuration file.- set_comment <comment>
Replaces the user comments within the eCos configuration file with
<comment>
. This will erase any profile indicators stored within the configuration file when the eCos configuration was created.
26.3. Conflicts and constraints
Configuration options are not completely independent. For example
the C library's strtod()
and
atof()
functions rely on the math library package
to provide certain functionality. If the math library package is removed
then the C library can no longer provide these functions. Each package
describes constraints like these in CDL "requires"
properties. If a constraint is not satisfied, then the configuration
contains a conflict. For any given conflict there can be several
resolution options. For example, it would be possible to add the math
library package back to the configuration, or to disable the
strtod()
and atof()
functions.
The eCos configuration tools will
report any conflicts in the current configuration. If there are any such
conflicts then the configuration is usually unsafe and it makes no sense
to build and run eCos in such circumstances.
In fact, any attempt at building eCos is
likely to fail. In exceptional cases it is possible to override this by
using e.g. the --ignore-errors
qualifier with
ecosconfig.
Many constraints are fairly simple in nature, and the
configuration tools contain an inference engine which can resolve the
associated conflicts automatically. For example, if the math library
package is removed then the inference engine can resolve the resulting
conflict by disabling the configuration option for
strtod()
and atof()
. All such
changes will be reported. Sometimes the inference engine cannot resolve
a conflict, for example it is not allowed to override a change that has
been made explicitly by the user. Sometimes it will find a solution
which does not match the application's requirements.
A typical session involving conflicts would look something like this:
$ ecosconfig new pid
This creates a new configuration with the default template. For most targets this will not result in any conflicts, because the default settings for the various options meet the requirements of the default template.
For some targets there may be conflicts and the inference engine would come into play.
$ ecosconfig remove libm U CYGSEM_LIBC_STDIO_SCANF_FLOATING_POINT, new inferred value 0 U CYGFUN_LIBC_strtod, new inferred value 0 U CYGSEM_LIBC_STDIO_PRINTF_FLOATING_POINT, new inferred value 0
ecosconfig reports that this change caused three conflicts, all in the C library. The inference engine was able to resolve all the conflicts and update the relevant configuration options accordingly.
To suppress the inference engine --no-resolve
can
be used:
$ ecosconfig new pid $ ecosconfig --no-resolve remove libm C CYGSEM_LIBC_STDIO_SCANF_FLOATING_POINT, "requires" constraint not satisfied: CYGPKG_LIBM C CYGSEM_LIBC_STDIO_PRINTF_FLOATING_POINT, "requires" constraint not satisfied: CYGPKG_LIBM C CYGFUN_LIBC_strtod, "requires" constraint not satisfied: CYGPKG_LIBM
Three unresolved conflicts are reported.
The check command can be used to get the
current state of the configuration, and the --verbose
qualifier will provide additional information:
$ ecosconfig --srcdir /home/bartv/ecc/ecc --verbose check Target: pid Template: default Removed: CYGPKG_LIBM 3 conflict(s): C CYGFUN_LIBC_strtod, "requires" constraint not satisfied: CYGPKG_LIBM Possible solution: CYGFUN_LIBC_strtod -> 0 CYGSEM_LIBC_STDIO_SCANF_FLOATING_POINT -> 0 C CYGSEM_LIBC_STDIO_PRINTF_FLOATING_POINT, "requires" constraint not satisfied: CYGPKG_LIBM Possible solution: CYGSEM_LIBC_STDIO_PRINTF_FLOATING_POINT -> 0 C CYGSEM_LIBC_STDIO_SCANF_FLOATING_POINT, "requires" constraint not satisfied: CYGPKG_LIBM Possible solution: CYGSEM_LIBC_STDIO_SCANF_FLOATING_POINT -> 0
If the proposed solutions are acceptable, the resolve command can be used to apply them:
$ ecosconfig resolve U CYGSEM_LIBC_STDIO_SCANF_FLOATING_POINT, new inferred value 0 U CYGFUN_LIBC_strtod, new inferred value 0 U CYGSEM_LIBC_STDIO_PRINTF_FLOATING_POINT, new inferred value 0
The current configuration is again conflict-free and it is
possible to generate a build tree. The --quiet
qualifier can be used to suppress the change messages, if desired.
When changing individual configuration options by editing the ecos.ecc file (as described below), the resulting system should be checked and any problems should be resolved. For example, if CYGFUN_LIBC_strtod is explicitly enabled in the savefile:
$ edit ecos.ecc $ ecosconfig check Target: pid Template: default Removed: CYGPKG_LIBM 1 conflict(s): C CYGFUN_LIBC_strtod, "requires" constraint not satisfied: CYGPKG_LIBM $ ecosconfig resolve C CYGFUN_LIBC_strtod, "requires" constraint not satisfied: CYGPKG_LIBM
In this case the inference engine cannot resolve the conflict automatically because that would involve changing a user setting. Any attempt to generate a build tree will fail:
$ ecosconfig --srcdir /home/bartv/ecc/ecc tree C CYGFUN_LIBC_strtod, "requires" constraint not satisfied: CYGPKG_LIBM Unable to generate build tree, this configuration still contains conflicts. Either resolve the conflicts or use --ignore-errors
It is still possible to generate a build tree:
$ ecosconfig --srcdir /home/bartv/ecc/ecc --ignore-errors tree C CYGFUN_LIBC_strtod, "requires" constraint not satisfied: CYGPKG_LIBM $ make
In this case eCos will fail to build.
In other cases of unresolved conflicts eCos
may build, but may not run. In general all conflicts should be resolved
by editing the ecos.ecc
file, by letting the
inference engine make appropriate changes, or by other means, before any
attempt is made to build or run eCos.
26.4. Building the System
Once a build tree has been generated with ecosconfig, building eCos is straightforward:
$ make
The build tree contains the subdirectories, makefiles, and everything else that is needed to generate the default configuration for the selected architecture and platform. The only requirement is that the tools needed for that architecture, for example powerpc-eabi-g++, are available using the standard search path. If this is not the case then the make will fail with an error message. If you have a multiprocessor system then it may be more efficient to use:
$ make -j n
where n
is equal to the number of
processors on your system.
Once the make process has completed, the install tree will contain the header files and the target library that are needed for application development.
It is also possible to build the system‚s test cases for the current configuration:
$ make tests
The resulting test executables will end up in a
tests
subdirectory of the install tree.
If disk space is scarce then it is possible to make the copy of the install tree for application development purposes, and then use:
$ make clean
The build tree will now use up a minimum of disk space — the bulk of what is left consists of configuration header files that you may have edited and hence should not be deleted automatically. However, it is possible to rebuild the system at any time without re-invoking ecosconfig, just by running make again.
Under exceptional circumstances it may be necessary to run
make clean for other reasons, such as when a new
release of the toolchain is installed. The toolchain includes a number
of header files which are closely tied to the compiler, for example
limits.h
, and these header files are not and should
not be duplicated by eCos. The makefiles
perform header file dependency analysis, so that when a header file is
changed all affected sources will be rebuilt during the next
make. This is very useful when the configuration
header files are changed, but it also means that a build tree containing
information about the locations of header files must be rebuilt. If a
new version of the toolchain is installed and the old version is removed
then this location information is no longer accurate, and
make will complain that certain dependencies cannot
be satisfied. Under such circumstances it is necessary to do a
make clean first.
26.5. Packages
eCos is a component architecture. The system comes as a number of packages which can be enabled or disabled as required, and new packages can be added as they become available. Unfortunately, the packages are not completely independent: for example the µITRON compatibility package relies almost entirely on functionality provided by the kernel package, and it would not make sense to try to build µITRON if the kernel was disabled. The C library has fewer dependencies: some parts of the C library rely on kernel functionality, but it is possible to disable these parts and thus build a system that has the C library but no kernel. The ecosconfig tool has the capability of checking that all the dependencies are satisfied, but it may still be possible to produce configurations that will not build or (conceivably) that will build but not run. Developers should be aware of this and take appropriate care.
By default, ecosconfig will include all packages that are appropriate for the specified hardware in the configuration. The common HAL package and the eCos infrastructure must be present in every configuration. In addition, it is always necessary to have one architectural HAL package and one platform HAL package. Other packages are optional, and can be added or removed from a configuration as required.
The application may not require all of the packages; for example, it might not need the µITRON compatibility package, or the floating point support provided by the math library. There is a slight overhead when eCos is built because the packages will get compiled, and there is also a small disk space penalty. However, any unused facilities will get stripped out at link- time, so having redundant packages will not affect the final executable.
26.6. Coarse-grained Configuration
Coarse-grained configuration of an eCos system means making configuration changes using the ecosconfig tool. These changes include:
switching to different target hardware
switching to a different template
adding or removing a package
changing the version of a package
Whenever ecosconfig generates or updates an eCos configuration, it generates a configuration save file.
Suppose that the configuration was first created using the following command line:
$ ecosconfig new stdeval1
To change the target hardware to the Cogent CMA28x PowerPC board, the following command would be needed:
$ ecosconfig target cma28x
To switch to the PowerPC simulator instead:
$ ecosconfig target psim
As the hardware changes, hardware-related packages such as the HAL packages and device drivers will be added to and removed from the configuration as appropriate.
Note | |
---|---|
See the note on unintended consequences in Section 15.2, “Switching Targets, Repositories and Versions”. |
To remove any package from the current configuration, use the remove command:
$ ecosconfig remove uitron
You can disable multiple packages using multiple arguments, for example:
$ ecosconfig remove uitron libm
If this turns out to have been a mistake then you can re-enable one or more packages with the add command:
$ ecosconfig add libm
Changing the desired version for a package is also straightforward:
$ ecosconfig version v4_0_1 kernel
It is necessary to regenerate the build tree and header files following any changes to the configuration before rebuilding eCos:
$ ecosconfig tree
26.7. Fine-grained Configuration
ecosconfig only provides coarse-grained control over the configuration: the hardware, the template and the packages that should be built. Unlike the Configuration Tool, ecosconfig does not provide any facilities for manipulating finer-grained configuration options such as how many priority levels the scheduler should support. There are hundreds of these options, and manipulating them by means of command line arguments would not be sensible.
In the current system fine-grained configuration options may be manipulated by manual editing of the configuration file. When a file has been edited in this way, the ecosconfig tool should be used to check the configuration for any conflicts which may have been introduced:
$ ecosconfig check
The check command will list all conflicts and will also rewrite the configuration file, propagating any changes which affect other options. The user may choose to resolve the conflicts either by re-editing the configuration file manually or by invoking the inference engine using the resolve command:
$ ecosconfig resolve
The resolve command will list all conflicts which can be resolved and save the resulting changes to the configuration.
It is necessary to regenerate the build tree and header files following any changes to the configuration before rebuilding eCos:
$ ecosconfig tree
All the configuration options and their descriptions are listed in the eCos Reference Manual.
26.8. Editing an eCos Savefile
The eCos configuration information is
held in a single savefile, typically ecos.ecc
,
which can be generated by either the GUI configuration tool or by the
command line ecosconfig tool. The file normally
exists at the top level of the build tree. It is a text file, allowing
the various configurations options to be edited inside a suitable text
editor or by other programs or scripts, as well as in the GUI config
tool.
An eCos savefile is actually a script
in the Tcl programming language, so any
modifications to the file need to preserve Tcl syntax. For most
configuration options, any modifications will be trivial and there is no
need to worry about Tcl syntax. For example, changing a 1 to a 0 to
disable an option. For more complicated options, for exampleCYGDAT_UITRON_TASK_EXTERNS
, which involves some lines of C
code, more care has to be taken. If an edited savefile is no longer a
valid Tcl script then the configuration tools will be unable to read
back the data for further processing, for example to generate a build
tree. An outline of Tcl syntax is given below. One point worth noting
here is that a line that begins with a “#” is usually a
comment, and the bulk of an eCos savefile
actually consists of such comments, to make it easier to edit.
26.8.1. Header
An eCos savefile begins with a header, which typically looks something like this:
# eCos saved configuration # ---- commands -------------------------------------------------------- # This section contains information about the savefile format. # It should not be edited. Any modifications made to this section # may make it impossible for the configuration tools to read # the savefile. cdl_savefile_version 1; cdl_savefile_command cdl_savefile_version {}; cdl_savefile_command cdl_savefile_command {}; cdl_savefile_command cdl_configuration { description hardware template package }; cdl_savefile_command cdl_package { value_source user_value wizard_value inferred_value }; cdl_savefile_command cdl_component { value_source user_value wizard_value inferred_value }; cdl_savefile_command cdl_option { value_source user_value wizard_value inferred_value }; cdl_savefile_command cdl_interface { value_source user_value wizard_value inferred_value };
This section of the savefile is intended for use by the configuration system, and should not be edited. If this section is edited then the various configuration tools may no longer be able to read in the modified savefile.
26.8.2. Toplevel Section
The header is followed by a section that defines the configuration as a whole. A typical example would be:
# ---- toplevel -------------------------------------------------------- # This section defines the toplevel configuration object. The only # values that can be changed are the name of the configuration and # the description field. It is not possible to modify the target, # the template or the set of packages simply by editing the lines # below because these changes have wide-ranging effects. Instead # the appropriate tools should be used to make such modifications. cdl_configuration eCos { description ““ ; # These fields should not be modified. hardware pid ; template uitron ; package -hardware CYGPKG_HAL_ARM current ; package -hardware CYGPKG_HAL_ARM_PID current ; package -hardware CYGPKG_IO_SERIAL current ; package -template CYGPKG_HAL current ; package -template CYGPKG_IO current ; package -template CYGPKG_INFRA current ; package -template CYGPKG_KERNEL current ; package -template CYGPKG_UITRON current ; package -template CYGPKG_LIBC current ; package -template CYGPKG_LIBM current ; package -template CYGPKG_DEVICES_WALLCLOCK current ; package -template CYGPKG_ERROR current ; };
This section allows the configuration tools to reload the various packages that make up the configuration. Most of the information should not be edited. If it is necessary to add a new package or to remove an existing one then the appropriate tools should be used for this, for example:
$ ecosconfig remove CYGPKG_LIBM
There are two fields which can be edited. Configurations have a name; in this case eCos. They can also have a description, which is some arbitrary text. The configuration tools do not make use of these fields, they exist so that users can store additional information about a configuration.
26.8.3. Conflicts Section
The toplevel section is followed by details of all the conflicts (if any) in the configuration, for example:
# ---- conflicts ------------------------------------------------------- # There are 2 conflicts. # # option CYGNUM_LIBC_TIME_DST_DEFAULT_OFFSET # Property LegalValues # Illegal current value 100000 # Legal values are: -90000 to 90000 # # option CYGSEM_LIBC_TIME_CLOCK_WORKING # Property Requires # Requires constraint not satisfied: CYGFUN_KERNEL_THREADS_TIMER
When editing a configuration you may end up with something that is
invalid. Any problems in the configuration will be reported in the
conflicts section. In this case there are two conflicts. The option
CYGNUM_LIBC_TIME_DST_DEFAULT_OFFSET
has been given an
illegal value: typically this would be fixed by searching for the
definition of that option later on in the savefile and modifying the
value. The second conflict is more interesting, an unsatisfied
requires constraint. Configuration options are not
independent: disabling some functionality in, say, the kernel, can have
an impact elsewhere; in this case the C library. The various
dependencies between the options are specified by the component
developers and checked by the configuration system. In this case there
are two obvious ways in which the conflict could be resolved: re-
enabling CYGFUN_KERNEL_THREADS_TIMER
, or disabling
CYGSEM_LIBC_TIME_CLOCK_WORKING
. Both of these options
will be listed later on in the file.
Some care has to be taken when modifying configuration options, to
avoid introducing new conflict. For instance it is possible that there
might be other options in the system which have a dependency on
CYGSEM_LIBC_TIME_CLOCK_WORKING
, so disabling that
option may not be the best way to resolve the conflict. Details of all
such dependencies are provided in the appropriate places in the
savefile.
It is not absolutely required that a configuration be conflict- free before generating a build tree and building eCos. It is up to the developers of each component to decide what would happen if an attempt is made to build eCos while there are still conflicts. In serious cases there is likely to be a compile-time failure, or possibly a link-time failure. In less serious cases the system may build happily and the application can be linked with the resulting library, but the component may not quite function as intended - although it may still be good enough for the specific needs of the application. It is also possible that everything builds and links, but once in a while the system will unaccountably crash. Using a configuration that still has conflicts is done entirely at the user‚s risk.
26.8.4. Data Section
The bulk of the savefile lists the various packages, components, and options, including their values and the various dependencies. A number of global options come first, especially those related to the build process such as compiler flags. These are followed by the various packages, and the components and options within those packages, in order.
Packages, components and options are organized in a hierarchy. If a particular component is disabled then all options and sub-components below it will be inactive: any changes made to these will have no effect. The savefile contains information about the hierarchy in the form of comments, for example:
cdl_package CYGPKG_KERNEL ... # > cdl_component CYGPKG_KERNEL_EXCEPTIONS ... # > cdl_option CYGSEM_KERNEL_EXCEPTIONS_DECODE ... cdl_option CYGSEM_KERNEL_EXCEPTIONS_GLOBAL ... # < cdl_component CYGPKG_KERNEL_SCHED ... # > cdl_option CYGSEM_KERNEL_SCHED_MLQUEUE ... cdl_option CYGSEM_KERNEL_SCHED_BITMAP ... # < # <
This corresponds to the following hierarchy:
CYGPKG_KERNEL CYGPKG_KERNEL_EXCEPTIONS CYGSEM_KERNEL_EXCEPTIONS_DECODE CYGSEM_KERNEL_EXCEPTIONS_GLOBAL CYGPKG_KERNEL_SCHED CYGSEM_KERNEL_SCHED_MLQUEUE CYGSEM_KERNEL_SCHED_BITMAP
Providing the hierarchy information in this way allows programs or scripts to analyze the savefile and readily determine the hierarchy. It could also be used by a sufficiently powerful editor to support structured editing of eCos savefiles. The information is not used by the configuration tools themselves since they obtain the hierarchy from the original CDL scripts.
Each configurable entity is preceded by a comment, of the following form:
# Kernel schedulers # doc: ref/ecos-ref/ecos-kernel-overview.html#THE-SCHEDULER # The eCos kernel provides a choice of schedulers. In addition # there are a number of configuration options to control the # detailed behaviour of these schedulers. cdl_component CYGPKG_KERNEL_SCHED { ... };
This provides a short textual alias Kernel
schedulers
for the component. If online documentation is
available for the configurable entity then this will come next. Finally
there is a short description of the entity as a whole. All this
information is provided by the component developers.
Each configurable entity takes the form:
<type> <name> { <data> };
Configurable entities may not be active. This can be either because the parent is disabled or inactive, or because there are one or more active_if properties. Modifying the value of an inactive entity has no effect on the configuration, so this information is provided first:
cdl_option CYGSEM_KERNEL_EXCEPTIONS_DECODE { # This option is not active # The parent CYGPKG_KERNEL_EXCEPTIONS is disabled ... }; ... cdl_option CYGIMP_IDLE_THREAD_YIELD { # This option is not active # ActiveIf constraint: (CYGNUM_KERNEL_SCHED_PRIORITIES == 1) # CYGNUM_KERNEL_SCHED_PRIORITIES == 32 # --> 0 ... };
For CYGIMP_IDLE_THREAD_YIELD
the
savefile lists the expression that must be satisfied if the option
is to be active, followed by the current value of all entities that
are referenced in the expression, and finally the result of evaluating
that expression.
Not all options are directly modifiable in the savefile. First, the value of packages (which is the version of that package loaded into the configuration) cannot be modified here.
cdl_package CYGPKG_KERNEL { # Packages cannot be added or removed, nor can their version be changed, # simply by editing their value. Instead the appropriate configuration # should be used to perform these actions. ... };
The version of a package can be changed using e.g.:
$ ecosconfig version 1.3 CYGPKG_KERNEL
Even though a package‚s value cannot be modified here, it is still important for the savefile to contain the details. In particular packages may impose constraints on other configurable entities and may be referenced by other configurable entities. Also it would be difficult to understand or extract the configuration‚s hierarchy if the packages were not listed in the appropriate places in the savefile.
Some components (or, conceivably, options) do not have any associated data. Typically they serve only to introduce another level in the hierarchy, which can be useful in the context of the GUI configuration tool.
cdl_component CYGPKG_HAL_COMMON_INTERRUPTS { # There is no associated value. };
Other components or options have a calculated value. These are not user-modifiable, but typically the value will depend on other options which can be modified. Such calculated options can be useful when controlling what gets built or what ends up in the generated configuration header files. A calculated value may also effect other parts of the configuration, for instance, via a requires constraint.
cdl_option BUFSIZ { # Calculated value: CYGSEM_LIBC_STDIO_WANT_BUFFERED_IO ? CYGNUM_LIBC_STDIO_BUFSIZE : 0 # CYGSEM_LIBC_STDIO_WANT_BUFFERED_IO == 1 # CYGNUM_LIBC_STDIO_BUFSIZE == 256 # Current_value: 256 };
A special type of calculated value is the interface. The value of an interface is the number of active and enabled options which implement that interface. Again the value of an interface cannot be modified directly; only by modifying the options which implement the interface. However, an interface can be referenced by other parts of the configuration.
cdl_interface CYGINT_KERNEL_SCHEDULER { # Implemented by CYGSEM_KERNEL_SCHED_MLQUEUE, active, enabled # Implemented by CYGSEM_KERNEL_SCHED_BITMAP, active, disabled # This value cannot be modified here. # Current_value: 1 # Requires: 1 == CYGINT_KERNEL_SCHEDULER # CYGINT_KERNEL_SCHEDULER == 1 # --> 1 # The following properties are affected by this value # interface CYGINT_KERNEL_SCHEDULER # Requires: 1 == CYGINT_KERNEL_SCHEDULER };
If the configurable entity is modifiable then there will be lines like the following:
cdl_option CYGSEM_KERNEL_SCHED_MLQUEUE { ... # Flavor: bool # No user value, uncomment the following line to provide one. # user_value 1 # value_source default # Default value: 1 ... };
Configurable entities can have one of four different flavors: none, bool, data and booldata. Flavor none indicates that there is no data associated with the entity, typically it just acts as a placeholder in the overall hierarchy. Flavor bool is the most common, it is a simple yes-or-no choice. Flavor data is for more complicated configuration choices, for instance the size of an array or the name of a device. Flavor booldata is a combination of bool and data: the option can be enabled or disabled, and there is some additional data associated with the option as well.
In the above example the user has not modified this particular
option, as indicated by the comment and by the commented-out user_value
line.
To disable this option the file should be edited to:
cdl_option CYGSEM_KERNEL_SCHED_MLQUEUE { ... # Flavor: bool # No user value, uncomment the following line to provide one. user_value 0 # value_source default # Default value: 1 ... }
The comment preceding the user_value
0
line can be removed if desired, otherwise it
will be removed automatically the next time the file is read and
updated by the configuration tools.
Much the same process should be used for options with the data flavor, for example:
cdl_option CYGNUM_LIBC_TIME_DST_DEFAULT_OFFSET { # Flavor: data # No user value, uncomment the following line to provide one. # user_value 3600 # value_source default # Default value: 3600 # Legal values: -90000 to 90000 };
can be changed to:
cdl_option CYGNUM_LIBC_TIME_DST_DEFAULT_OFFSET { # Flavor: data user_value 7200 # value_source default # Default value: 3600 # Legal values: -90000 to 90000 };
Note that the original text provides the default value in
the user_value
comment,
on the assumption that the desired new value is likely to be similar
to the default value. The value_source
comment
does not need to be updated, it will be fixed up if the savefile
is fed back into the configuration system and regenerated.
For options with the booldata flavor, the user_value
line
needs take two arguments. The first argument is for the boolean
part, the second for the data part. For example:
cdl_component CYGNUM_LIBM_COMPATIBILITY { # Flavor: booldata # No user value, uncomment the following line to provide one. # user_value 1 POSIX # value_source default # Default value: 1 POSIX # Legal values: “POSIX” “IEEE” “XOPEN” “SVID” ... };
could be changed to:
cdl_component CYGNUM_LIBM_COMPATIBILITY { # Flavor: booldata user_value 1 IEEE # value_source default # Default value: 1 POSIX # Legal values: “POSIX” “IEEE” “XOPEN” “SVID” ... };
or alternatively, if the whole component should be disabled, to:
cdl_component CYGNUM_LIBM_COMPATIBILITY { # Flavor: booldata user_value 0 POSIX # value_source default # Default value: 1 POSIX # Legal values: “POSIX” “IEEE” “XOPEN” “SVID” ... };
Some options take values that span multiple lines. An example would be:
cdl_option CYGDAT_UITRON_MEMPOOLVAR_INITIALIZERS { # Flavor: data # No user value, uncomment the following line to provide one. # user_value \ # “CYG_UIT_MEMPOOLVAR( vpool1, 2000 ), \\ # CYG_UIT_MEMPOOLVAR( vpool2, 2000 ), \\ # CYG_UIT_MEMPOOLVAR( vpool3, 2000 ),” # value_source default # Default value: \ # “CYG_UIT_MEMPOOLVAR( vpool1, 2000 ), \\ # CYG_UIT_MEMPOOLVAR( vpool2, 2000 ), \\ # CYG_UIT_MEMPOOLVAR( vpool3, 2000 ),” };
Setting a user value for this option involves uncommenting and modifying all relevant lines, for example:
cdl_option CYGDAT_UITRON_MEMPOOLVAR_INITIALIZERS { # Flavor: data user_value \ “CYG_UIT_MEMPOOLVAR( vpool1, 4000 ), \\ CYG_UIT_MEMPOOLVAR( vpool2, 4000 ),” # value_source default # Default value: \ # “CYG_UIT_MEMPOOLVAR( vpool1, 2000 ), \\ # CYG_UIT_MEMPOOLVAR( vpool2, 2000 ), \\ # CYG_UIT_MEMPOOLVAR( vpool3, 2000 ),” };
In such cases appropriate care has to be taken to preserve Tcl syntax, as discussed below.
The configuration system has the ability to keep track of
several different values for any given option. All options
start off with a default value, in other words their value
source is set to default
. If a
configuration involves conflicts and the configuration
system‚s inference engine is allowed to resolve these
automatically then it may provide an
inferred
value instead, for
example:
cdl_option CYGMFN_KERNEL_SYNCH_CONDVAR_TIMED_WAIT { # Flavor: bool # No user value, uncomment the following line to provide one. # user_value 1 # The inferred value should not be edited directly. inferred_value 0 # value_source inferred # Default value: 1 ... };
Inferred values are calculated by the configuration system and should not be edited by the user. If the inferred value is not correct then a user value should be substituted instead:
cdl_option CYGMFN_KERNEL_SYNCH_CONDVAR_TIMED_WAIT { # Flavor: bool user_value 1 # The inferred value should not be edited directly. inferred_value 0 # value_source inferred # Default value: 1 ... };
The inference engine will not override a user value with an inferred one. Making a change like this may well re-introduce a conflict, since the inferred value was only calculated to resolve a conflict. Another run of the inference engine may find a different and more acceptable way of resolving the conflict, but this is not guaranteed and it may be up to the user to examine the various dependencies and work out an acceptable solution.
Inferred values are listed in the savefile because the exact inferred value may depend on the order in which changes were made and conflicts were resolved. If the inferred values were absent then it is possible that reloading a savefile would not exactly restore the configuration. Default values on the other hand are entirely deterministic so there is no actual need for the values to be listed in the savefile. However, the default value can be very useful information so it is provided in a comment.
Occasionally the user will want to do some experimentation, and temporarily switch an option from a user value back to a default or inferred one to see what the effect would be. This could be achieved by simply commenting out the user value. For instance, if the current savefile contains:
cdl_option CYGMFN_KERNEL_SYNCH_CONDVAR_TIMED_WAIT { # Flavor: bool user_value 1 # The inferred value should not be edited directly. inferred_value 0 # value_source user # Default value: 1 ... };
then the inferred value could be restored by commenting out
or removing the user_value
line:
cdl_option CYGMFN_KERNEL_SYNCH_CONDVAR_TIMED_WAIT { # Flavor: bool # user_value 1 # The inferred value should not be edited directly. inferred_value 0 # value_source user # Default value: 1 ... };
This is fine for simple values. However if the value is complicated
then there is a problem: commenting out the user_value
line or lines means that the
user value becomes invisible to the configuration system, so if the
savefile is loaded and then regenerated the information will be lost.
An alternative approach is to keep the user_value
but explicitly set the value_source
line,
for example:
cdl_option CYGMFN_KERNEL_SYNCH_CONDVAR_TIMED_WAIT { # Flavor: bool user_value 1 # The inferred value should not be edited directly. inferred_value 0 value_source inferred # Default value: 1 ... };
In this case the configuration system will use the inferred value for
the purposes of dependency analysis etc., even though a user value is
present. To restore the user value the value_source
line can be commented out
again. If there is no explicit value_source
then the configuration system
will just use the highest priority one: the user value if it exists;
otherwise the inferred value if it
exists; otherwise the default value which always exists.
The default value for an option can be a simple constant, or it can be an expression involving other options. In the latter case the expression will be listed, together with the values for all options referenced in the expression and the current result of evaluating that expression. This is for informational purposes only, the default value is always recalculated deterministically when loading in a savefile.
cdl_option CYGBLD_GLOBAL_COMMAND_PREFIX { # Flavor: data # No user value, uncomment the following line to provide one. # user_value arm-elf # value_source default # Default value: CYGHWR_THUMB ? “thumb-elf” : “arm-elf” # CYGHWR_THUMB == 0 # --> arm-elf };
For options with the data or booldata flavor, there are likely
to be constraints on the possible values. If the value is supposed
to be a number in a given range and a user value of “hello
world
” is provided instead then there
are likely to be compile-time failures. Component developers can
specify constraints on the legal values, and these will be listed
in the savefile.
cdl_option X_TLOSS { # Flavor: data # No user value, uncomment the following line to provide one. # user_value 1.41484755040569E+16 # value_source default # Default value: 1.41484755040569E+16 # Legal values: 1 to 1e308 };
cdl_component CYGNUM_LIBM_COMPATIBILITY { # Flavor: booldata # No user value, uncomment the following line to provide one. # user_value 1 POSIX # value_source default # Default value: 1 POSIX # Legal values: “POSIX” “IEEE” “XOPEN” “SVID” ... };
In some cases the legal values list may be an expression involving other options. If so then the current values of the referenced options will be listed, together with the result of evaluating the list expression, just as for default value expressions.
If an illegal value is provided then this will result in a conflict, listed in the conflicts section of the savefile. For more complicated options a simple legal values list is not sufficient to allow the current value to be validated, and the configuration system will be unable to flag conflicts. This issue will be addressed in future releases of the configuration system.
Following the value-related fields for a given option, any requires constraints belonging to this option will be listed. These constraints are only effective if the option is active and, for bool and booldata flavors, enabled. If some aspect of eCos functionality is inactive or disabled then it cannot impose any constraints on the rest of the system. As usual, the full expression will be listed followed by the current values of all options that are referenced and the result of evaluating the expression:
cdl_option CYGSEM_LIBC_TIME_TIME_WORKING { ... # Requires: CYGPKG_DEVICES_WALLCLOCK # CYGPKG_DEVICES_WALLCLOCK == current # --> 1 };
When modifying the value of an option it is useful to know not only what constraints the option imposes on the rest of the system but also what other options in the system depend in some way on this one. The savefile provides this information:
cdl_option CYGFUN_KERNEL_THREADS_TIMER { ... # The following properties are affected by this value # option CYGMFN_KERNEL_SYNCH_CONDVAR_TIMED_WAIT # Requires: CYGFUN_KERNEL_THREADS_TIMER # option CYGIMP_UITRON_STRICT_CONFORMANCE # Requires: CYGFUN_KERNEL_THREADS_TIMER # option CYGSEM_LIBC_TIME_CLOCK_WORKING # Requires: CYGFUN_KERNEL_THREADS_TIMER };
26.8.5. Tcl Syntax
eCos savefiles are implemented as Tcl scripts, and are read
in by running the data through a standard Tcl interpreter that has
been extended with a small number of additional commands such as cdl_option
and cdl_configuration
.
In many cases this is an implementation detail that can be safely
ignored while editing a savefile: simply replacing a 1
with
a 0
to disable some functionality
is not going to affect whether or not the savefile is still a valid
Tcl script and can be processed by a Tcl interpreter. However, there
are more complicated cases where an understanding of Tcl syntax
is at least desirable, for example:
cdl_option CYGDAT_UITRON_MEMPOOLVAR_EXTERNS { # Flavor: data user_value \ “static char vpool1\[ 2000 \], \\ vpool2\[ 2000 \], \\ vpool3\[ 2000 \];” # value_source default # Default value: \ # “static char vpool1\[ 2000 \], \\ # vpool2\[ 2000 \], \\ # vpool3\[ 2000 \];” };
The backslash at the end of the user_value
line
is processed by the Tcl interpreter as a line continuation character.
The quote marks around the user data are also interpreted by the
Tcl interpreter and serve to turn the entire data field into a single
argument. The backslashes preceding the opening and closing square
brackets prevent the Tcl interpreter from treating these characters
specially, otherwise there would be an attempt at command
substitution as described below. The double backslashes
at the end of each line of the data will be turned into a single
backslash by the Tcl interpreter, rather than escaping the newline
character, so that the actual data seen by the configuration system
is:
static char vpool1[ 2000 ], \ vpool2[ 2000 ], \ vpool3[ 2000 ];
This is of course the data that should end up in the µITRON
configuration header file. The opening and closing braces surrounding
the entire body of the option data are also significant and cause
this body to be passed as a single argument to the cdl_option command.
The closing semicolon is optional in this example, but provides
a small amount of additional robustness if the savefile is edited
such that it is no longer a valid Tcl script. If the data contained
any $
characters then
these would have to be treated specially as well, via a backslash escape.
In spite of what all the above might seem to suggest, Tcl is actually a very simple yet powerful scripting language: the syntax is defined by just eleven rules. On occasion this simplicity means that Tcl‚s behaviour is subtly different from other languages, which can confuse newcomers.
When the Tcl interpreter is passed some data such as puts Hello
, it splits this data into a
command and its arguments. The command will be terminated by a
newline or by a semicolon, unless one of the quoting mechanisms is
used. The command and each of its arguments are separated by white
space. So in the following example:
puts Hello set x 42
will result in two separate commands being executed. The first
command is puts
and is passed a
single argument, Hello
. The second
command is set
and is passed two
arguments, x
and 42
.
The intervening newline character serves to terminate the first
command, and a semi-colon separator could be used instead:
puts Hello;set x 42
Any white space surrounding the semicolon is just ignored because it does not serve to separate arguments.
Now consider the following:
set x Hello world
This is not valid Tcl. It is an attempt to invoke the set
command
with three arguments: x
, Hello
,
and world
. The set
only
takes two arguments, a variable name and a value, so it is necessary
to combine the data into a single argument by quoting:
set x “Hello world”
When the Tcl interpreter encounters the first quote character
it treats all subsequent data up to but not including the closing
quote as part of the current argument. The quote marks are removed
by the interpreter, so the second argument passed to the set
command
is just Hello world
without the
quote characters. This can be significant in the context of eCos savefiles.
For instance, consider the following configuration option:
cdl_option CYGDAT_LIBC_STDIO_DEFAULT_CONSOLE { # Flavor: data # No user value, uncomment the following line to provide one. # user_value “\”/dev/ttydiag\”” # value_source default # Default value: “\”/dev/ttydiag\”” };
The desired value of the configuration option should be a valid C string, complete with quote characters. If the savefile was edited to:
cdl_option CYGDAT_LIBC_STDIO_DEFAULT_CONSOLE { # Flavor: data user_value “/dev/ttydiag” # value_source default # Default value: “\”/dev/ttydiag\”” };
then the Tcl interpreter would remove the quote marks when
the savefile is read back in, so the option‚s value would
not have any quote marks and would not be a valid C string. The
configuration system is not yet able to perform the required validation
so the following #define
would
be generated in the configuration header file:
#define CYGDAT_LIBC_STDIO_DEFAULT_CONSOLE /dev/ttydiag
This is likely to cause a compile-time failure when building eCos.
A quoted argument continues until the closing quote character
is encountered, which means that it can span multiple lines. This
can also be encountered in eCos savefiles, for instance, in the CYGDAT_UITRON_MEMPOOLVAR_EXTERNS
example
mentioned earlier. Newline or semicolon characters do not terminate
the current command in such cases.
The Tcl interpreter supports much the same forms of backslash
substitution as other common programming languages. Some backslash
sequences such as \n
will
be replaced by the appropriate character. The sequence \\
will
be replaced by a single backslash. A backslash at the very end of
a line will cause that backslash, the newline character, and any
white space at the start of the next line to be replaced by a single
space. Hence the following two Tcl commands are equivalent:
puts “Hello\nworld\n” puts \ “Hello world “
In addition to quote and backslash characters, the Tcl interpreter
treats square brackets, the $
character,
and braces specially. Square brackets are used for command substitution,
for example:
puts “The answer is [expr 6 * 9]”
When the Tcl interpreter encounters the square brackets it will treat
the contents as another command that should be executed first, and the
result of executing that is used when continuing to process the script.
In this case the Tcl interpreter will execute the command expr 6 * 9
, yielding a result of 54, and then
the Tcl interpreter will execute
puts “The answer is 54”
.
It should be noted that the interpreter contains only one level of
substitution: if the result of performing command substitution performs
further special characters such as square brackets then these will not
be treated specially.
Command line substitution is very unlikely to prove useful in the context of an eCos savefile, but it is part of the Tcl language and hence cannot be easily suppressed while reading in a savefile. As a result care has to be taken when savefile data involves square brackets. Consider the following:
cdl_option CYGDAT_UITRON_MEMPOOLFIXED_EXTERNS { ... user_value \ “static char fpool1[ 2000 ], fpool2[ 2000 ];” ... };
The Tcl interpreter will interpret the square brackets as
an attempt at command substitution and hence it will attempt to
execute the command 2000
with no
arguments. No such command is defined by the Tcl language or by
the savefile-related extensions provided by the configuration system,
so this will result in an error when an attempt is made to read
back the savefile. Instead it is necessary to backslash-escape the
square brackets and thus suppress command substitution:
cdl_option CYGDAT_UITRON_MEMPOOLFIXED_EXTERNS { ... user_value \ “static char fpool1\[ 2000 \], fpool2\[ 2000 \];” ... };
Similarly the $
character
is used in Tcl scripts to perform variable substitution:
set x [expr 6 * 9] puts “The answer is $x”
Variable substitution, like command substitution, is very
unlikely to prove useful in the context of an eCos savefile. Should
it be necessary to have a $
character
in configuration data then again a backslash escape needs to be
used.
cdl_option FOODAT_MONITOR_PROMPT { ... user_value “\$ “ ... };
Braces are used to collect a sequence of characters into a
single argument, just like quotes. The difference is that variable,
command and backslash substitution do not occur inside braces (with
the sole exception of backslash substitution at the end of a line).
So, for example, the CYGDAT_UITRON_MEMPOOL_EXTERNFIXED_EXTERNS
value
could be written as:
cdl_option CYGDAT_UITRON_MEMPOOLFIXED_EXTERNS { ... user_value \ {static char fpool1[ 2000 ], fpool2[ 2000 ];} ... };
The configuration system does not use this when generating savefiles because for simple edits of a savefile by inexperienced users the use of brace characters is likely to be a little bit more confusing than the use of quotes.
At this stage it is worth noting that the basic format of each configuration option in the savefile makes use of braces:
cdl_option <name> { ... };
The configuration system extends the Tcl language with a small
number of additional commands such as cdl_option
.
These commands take two arguments, a name and a body, where the
body consists of all the text between the braces. First a check
is made that the specified option is actually present in the configuration.
Then the body is executed in a recursive invocation of the Tcl interpreter,
this time with additional commands such as user_value
and value_source
.
If, after editing, the braces are not correctly matched up then
the savefile will no longer be a valid Tcl script and errors will
be reported when the savefile is loaded again.
Comments in Tcl scripts are introduced by a hash character #
.
However, a hash character only introduces a comment if it occurs
where a command is expected. Consider the following:
# This is a comment puts “Hello” # world
The first line is a valid comment, since the hash character
occurs right at the start where a command name is expected. The
second line does not contain a comment. Instead it is an attempt
to invoke the puts
command with
three arguments: Hello
, #
and world
.
These are not valid arguments for the puts
command
so an error will be raised.
If the second line was rewritten as:
puts “Hello”; # world
then this is a valid Tcl script. The semicolon identifies the end of the current command, so the hash character occurs at a point where the next command would start and hence it is interpreted as the start of a comment.
This handling of comments can lead to subtle behaviour. Consider the following:
cdl_option WHATEVER { # This is a comment } user_value 42 ... }
Consider the way the Tcl interpreter processes this. The command
name and the first argument do not pose any special difficulties.
The opening brace is interpreted as the start of the next argument,
which continues until a closing brace is encountered. In this case
the closing brace occurs on the second line, so the second argument
passed to cdl_option
is \n # This is a comment
. This second argument
is processed in a recursive invocation of the Tcl interpreter and
does not contain any commands, just a comment. Toplevel savefile
processing then resumes, and the next command that is encountered
is user_value
. Since the
relevant savefile code is not currently processing a configuration
option this is an error. Later on the Tcl interpreter would encounter
a closing brace by itself, which is also an error. Fortunately this
sequence of events is very unlikely to occur when editing generated
savefiles.
This should be sufficient information about Tcl to allow for safe editing of eCos savefiles. Further information is available from a wide variety of sources, for example the book Tcl and the Tk Toolkit by John K Ousterhout.
26.9. Editing the Sources
For many users, controlling the packages and manipulating the available configuration options will be sufficient to create an embedded operating system that meets the application's requirements. However, since eCos is shipped entirely in source form, it is possible to go further when necessary: you can edit the eCos sources themselves. This requires some understanding of the way the eCos build system works.
The most obvious place to edit the source code is directly in the
component repository. For example, you could
edit the file
kernel/
to change the way kernel mutexes work, or possibly just to
add some extra diagnostics or assertions. Once the file has been edited,
it is possible to invoke make at the top level of
the build tree and the target library will be rebuilt as required. A
small optimization is possible: the build tree is largely a mirror of
the component repository, so it too will contain a subdirectory
<version>
/src/sync/mutex.cxxkernel/
; if
make is invoked in this directory then it will only check for changes to
the kernel sources, which is a bit more efficient than checking for
changes throughout the component repository.
<version>
Editing a file in the component repository is fine if this
tree is used for only one eCos configuration. If the repository
is used for several different configurations, however, and especially
if it is shared by multiple users, then making what may be experimental
changes to the master sources would be a bad idea. The build system provides
an alternative. It is possible to make a copy of the file in the
build tree, in other words copy mutex.cxx
from
the kernel/
directory
in the component repository to <version>
/src/synckernel/
in
the build tree, and edit the file in the build tree. When make is
invoked it will pick up local copies of any of the sources in preference
to the master versions in the component repository. Once you have
finished modifying the eCos sources you can install the final version
back in the component repository. If the changes were temporary
in nature and only served to aid the debugging process, then you
can discard the modified version of the sources.
<version>
/src/sync
The situation is slightly more complicated for the header
files that a package may export, such as the C library‚s stdio.h
header
file, which can be found in the directory language/c/libc/
.
If such a header file is changed, either directly in the component
repository or after copying it to the build tree, then make must
be invoked at the top level of the build tree. In cases like this
it is not safe to rebuild just the C library because other packages
may depend on the contents of <version>
/includestdio.h
.
26.10. Modifying the Memory Layout
Each eCos platform package is supplied with linker script
fragments which describe the location of memory regions on the evaluation
board and the location of memory sections within these regions.
The correct linker script fragment is selected and included in the
eCos linker script
target.ld
when
eCos is built.
It is not necessary to modify the default memory layouts in order to start development with eCos. However, it will be necessary to edit a linker script fragment when the memory map of the evaluation board is changed. For example, if additional memory is added, the linker must be notified that the new memory is available for use. As a minimum, this would involve modifying the length of the corresponding memory region. Where the available memory is non-contiguous, it may be necessary to declare a new memory region and reassign certain linker output sections to the new region.
Linker script fragments and memory layout header files should
be edited within the eCos install tree. They are
located at include/pkgconf/mlt_*.*
.
Where multiple start-up types are in use, it will be necessary to
edit multiple linker script fragments and header files. The information
provided in the header file and the corresponding linker script
fragment must always match. A typical linker script fragment is
shown below:
Example 26.1. eCos linker script fragment
MEMORY { rom : ORIGIN = 0x40000000, LENGTH = 0x80000 ram : ORIGIN = 0x48000000, LENGTH = 0x200000 } SECTIONS { SECTIONS_BEGIN SECTION_rom_vectors (rom, 0x40000000, LMA_EQ_VMA) SECTION_text (rom, ALIGN (0x1), LMA_EQ_VMA) SECTION_fini (rom, ALIGN (0x1), LMA_EQ_VMA) SECTION_rodata (rom, ALIGN (0x1), LMA_EQ_VMA) SECTION_rodata1 (rom, ALIGN (0x1), LMA_EQ_VMA) SECTION_fixup (rom, ALIGN (0x1), LMA_EQ_VMA) SECTION_gcc_except_table (rom, ALIGN (0x1), LMA_EQ_VMA) SECTION_data (ram, 0x48000000, FOLLOWING (.gcc_except_table)) SECTION_bss (ram, ALIGN (0x4), LMA_EQ_VMA) SECTIONS_END }
The file consists of two blocks, the MEMORY
block
contains lines describing the address (ORIGIN
)
and the size (LENGTH
) of each memory
region. The MEMORY
block is followed
by the SECTIONS
block which contains
lines describing each of the linker output sections. Each section
is represented by a macro call. The arguments of these macros are
ordered as follows:
The memory region in which the section will finally reside.
The final address (
VMA
) of the section. This is expressed using one of the following forms:- n
at the absolute address specified by the unsigned integer n
- ALIGN (n)
following the final location of the previous section with alignment to the next n-byte boundary
The initial address (
LMA
) of the section. This is expressed using one of the following forms:- LMA_EQ_VMA
the
LMA
equals theVMA
(no relocation)- AT (n)
at the absolute address specified by the unsigned integer n
- FOLLOWING (.name)
following the initial location of section name
In order to maintain compatibility with linker script fragments and header files exported by the eCos Configuration Tool, the use of other expressions within these files is not recommended.
Note that the names of the linker output sections will vary between target architectures. A description of these sections can be found in the specific GCC documentation for your architecture.
2024-12-10 | Open Publication License |