<!-- Copyright (C) 2002 Red Hat, Inc. -->
|
<!-- Copyright (C) 2002 Red Hat, Inc. -->
|
<!-- This material may be distributed only subject to the terms -->
|
<!-- This material may be distributed only subject to the terms -->
|
<!-- and conditions set forth in the Open Publication License, v1.0 -->
|
<!-- and conditions set forth in the Open Publication License, v1.0 -->
|
<!-- or later (the latest version is presently available at -->
|
<!-- or later (the latest version is presently available at -->
|
<!-- http://www.opencontent.org/openpub/). -->
|
<!-- http://www.opencontent.org/openpub/). -->
|
<!-- Distribution of the work or derivative of the work in any -->
|
<!-- Distribution of the work or derivative of the work in any -->
|
<!-- standard (paper) book form is prohibited unless prior -->
|
<!-- standard (paper) book form is prohibited unless prior -->
|
<!-- permission is obtained from the copyright holder. -->
|
<!-- permission is obtained from the copyright holder. -->
|
<HTML
|
<HTML
|
><HEAD
|
><HEAD
|
><TITLE
|
><TITLE
|
>Writing New Devices - host</TITLE
|
>Writing New Devices - host</TITLE
|
><meta name="MSSmartTagsPreventParsing" content="TRUE">
|
><meta name="MSSmartTagsPreventParsing" content="TRUE">
|
<META
|
<META
|
NAME="GENERATOR"
|
NAME="GENERATOR"
|
CONTENT="Modular DocBook HTML Stylesheet Version 1.76b+
|
CONTENT="Modular DocBook HTML Stylesheet Version 1.76b+
|
"><LINK
|
"><LINK
|
REL="HOME"
|
REL="HOME"
|
TITLE="eCos Synthetic Target"
|
TITLE="eCos Synthetic Target"
|
HREF="hal-synth-arch.html"><LINK
|
HREF="hal-synth-arch.html"><LINK
|
REL="PREVIOUS"
|
REL="PREVIOUS"
|
TITLE="Writing New Devices - target"
|
TITLE="Writing New Devices - target"
|
HREF="synth-new-target.html"><LINK
|
HREF="synth-new-target.html"><LINK
|
REL="NEXT"
|
REL="NEXT"
|
TITLE="Porting"
|
TITLE="Porting"
|
HREF="synth-porting.html"></HEAD
|
HREF="synth-porting.html"></HEAD
|
><BODY
|
><BODY
|
CLASS="REFENTRY"
|
CLASS="REFENTRY"
|
BGCOLOR="#FFFFFF"
|
BGCOLOR="#FFFFFF"
|
TEXT="#000000"
|
TEXT="#000000"
|
LINK="#0000FF"
|
LINK="#0000FF"
|
VLINK="#840084"
|
VLINK="#840084"
|
ALINK="#0000FF"
|
ALINK="#0000FF"
|
><DIV
|
><DIV
|
CLASS="NAVHEADER"
|
CLASS="NAVHEADER"
|
><TABLE
|
><TABLE
|
SUMMARY="Header navigation table"
|
SUMMARY="Header navigation table"
|
WIDTH="100%"
|
WIDTH="100%"
|
BORDER="0"
|
BORDER="0"
|
CELLPADDING="0"
|
CELLPADDING="0"
|
CELLSPACING="0"
|
CELLSPACING="0"
|
><TR
|
><TR
|
><TH
|
><TH
|
COLSPAN="3"
|
COLSPAN="3"
|
ALIGN="center"
|
ALIGN="center"
|
>eCos Synthetic Target</TH
|
>eCos Synthetic Target</TH
|
></TR
|
></TR
|
><TR
|
><TR
|
><TD
|
><TD
|
WIDTH="10%"
|
WIDTH="10%"
|
ALIGN="left"
|
ALIGN="left"
|
VALIGN="bottom"
|
VALIGN="bottom"
|
><A
|
><A
|
HREF="synth-new-target.html"
|
HREF="synth-new-target.html"
|
ACCESSKEY="P"
|
ACCESSKEY="P"
|
>Prev</A
|
>Prev</A
|
></TD
|
></TD
|
><TD
|
><TD
|
WIDTH="80%"
|
WIDTH="80%"
|
ALIGN="center"
|
ALIGN="center"
|
VALIGN="bottom"
|
VALIGN="bottom"
|
></TD
|
></TD
|
><TD
|
><TD
|
WIDTH="10%"
|
WIDTH="10%"
|
ALIGN="right"
|
ALIGN="right"
|
VALIGN="bottom"
|
VALIGN="bottom"
|
><A
|
><A
|
HREF="synth-porting.html"
|
HREF="synth-porting.html"
|
ACCESSKEY="N"
|
ACCESSKEY="N"
|
>Next</A
|
>Next</A
|
></TD
|
></TD
|
></TR
|
></TR
|
></TABLE
|
></TABLE
|
><HR
|
><HR
|
ALIGN="LEFT"
|
ALIGN="LEFT"
|
WIDTH="100%"></DIV
|
WIDTH="100%"></DIV
|
><H1
|
><H1
|
><A
|
><A
|
NAME="SYNTH-NEW-HOST">Writing New Devices - host</H1
|
NAME="SYNTH-NEW-HOST">Writing New Devices - host</H1
|
><DIV
|
><DIV
|
CLASS="REFNAMEDIV"
|
CLASS="REFNAMEDIV"
|
><A
|
><A
|
NAME="AEN726"
|
NAME="AEN726"
|
></A
|
></A
|
><H2
|
><H2
|
>Name</H2
|
>Name</H2
|
>Writing New Devices -- extending the synthetic target, host-side</DIV
|
>Writing New Devices -- extending the synthetic target, host-side</DIV
|
><DIV
|
><DIV
|
CLASS="REFSECT1"
|
CLASS="REFSECT1"
|
><A
|
><A
|
NAME="SYNTH-NEW-HOST-DESCRIPTION"
|
NAME="SYNTH-NEW-HOST-DESCRIPTION"
|
></A
|
></A
|
><H2
|
><H2
|
>Description</H2
|
>Description</H2
|
><P
|
><P
|
>On the host-side adding a new device means writing a Tcl/Tk script
|
>On the host-side adding a new device means writing a Tcl/Tk script
|
that will handle instantiation and subsequent requests from the
|
that will handle instantiation and subsequent requests from the
|
target-side. These scripts all run in the same full interpreter,
|
target-side. These scripts all run in the same full interpreter,
|
extended with various commands provided by the main I/O auxiliary
|
extended with various commands provided by the main I/O auxiliary
|
code, and running in an overall GUI framework. Some knowledge of
|
code, and running in an overall GUI framework. Some knowledge of
|
programming with Tcl/Tk is required to implement host-side device
|
programming with Tcl/Tk is required to implement host-side device
|
support.
|
support.
|
</P
|
</P
|
><P
|
><P
|
>Some devices can be implemented entirely using a Tcl/Tk script. For
|
>Some devices can be implemented entirely using a Tcl/Tk script. For
|
example, if the final system will have some buttons then those can be
|
example, if the final system will have some buttons then those can be
|
emulated in the synthetic target using a few Tk widgets. A simple
|
emulated in the synthetic target using a few Tk widgets. A simple
|
emulation could just have the right number of buttons in a row. A more
|
emulation could just have the right number of buttons in a row. A more
|
advanced emulation could organize the buttons with the right layout,
|
advanced emulation could organize the buttons with the right layout,
|
perhaps even matching the colour scheme, the shapes, and the relative
|
perhaps even matching the colour scheme, the shapes, and the relative
|
sizes. With other devices it may be necessary for the Tcl script to
|
sizes. With other devices it may be necessary for the Tcl script to
|
interact with an external program, because the required functionality
|
interact with an external program, because the required functionality
|
cannot easily be accessed from a Tcl script. For example interacting
|
cannot easily be accessed from a Tcl script. For example interacting
|
with a raw ethernet device involves some <TT
|
with a raw ethernet device involves some <TT
|
CLASS="FUNCTION"
|
CLASS="FUNCTION"
|
>ioctl</TT
|
>ioctl</TT
|
>
|
>
|
calls, which is easier to do in a C program. Therefore the
|
calls, which is easier to do in a C program. Therefore the
|
<TT
|
<TT
|
CLASS="FILENAME"
|
CLASS="FILENAME"
|
>ethernet.tcl</TT
|
>ethernet.tcl</TT
|
> script which implements the
|
> script which implements the
|
host-side ethernet support spawns a separate program
|
host-side ethernet support spawns a separate program
|
<TT
|
<TT
|
CLASS="FILENAME"
|
CLASS="FILENAME"
|
>rawether</TT
|
>rawether</TT
|
>, written in C, that performs the
|
>, written in C, that performs the
|
low-level I/O. Raw ethernet access usually also requires root
|
low-level I/O. Raw ethernet access usually also requires root
|
privileges, and running a small program <TT
|
privileges, and running a small program <TT
|
CLASS="FILENAME"
|
CLASS="FILENAME"
|
>rawether</TT
|
>rawether</TT
|
>
|
>
|
with such privileges is somewhat less of a security risk than the
|
with such privileges is somewhat less of a security risk than the
|
whole eCos application, the I/O auxiliary, and various dynamically
|
whole eCos application, the I/O auxiliary, and various dynamically
|
loaded Tcl scripts.
|
loaded Tcl scripts.
|
</P
|
</P
|
><P
|
><P
|
>Because all scripts run in a single interpreter, some care has
|
>Because all scripts run in a single interpreter, some care has
|
to be taken to avoid accidental sharing of global variables. The best
|
to be taken to avoid accidental sharing of global variables. The best
|
way to avoid problems is to have each script create its own Tcl
|
way to avoid problems is to have each script create its own Tcl
|
namespace, so for example the <TT
|
namespace, so for example the <TT
|
CLASS="FILENAME"
|
CLASS="FILENAME"
|
>ethernet.tcl</TT
|
>ethernet.tcl</TT
|
> script
|
> script
|
creates a namespace <TT
|
creates a namespace <TT
|
CLASS="VARNAME"
|
CLASS="VARNAME"
|
>ethernet::</TT
|
>ethernet::</TT
|
> and all variables
|
> and all variables
|
and procedures reside in this namespace. Similarly the I/O auxiliary
|
and procedures reside in this namespace. Similarly the I/O auxiliary
|
itself makes use of a <TT
|
itself makes use of a <TT
|
CLASS="VARNAME"
|
CLASS="VARNAME"
|
>synth::</TT
|
>synth::</TT
|
> namespace.
|
> namespace.
|
</P
|
</P
|
></DIV
|
></DIV
|
><DIV
|
><DIV
|
CLASS="REFSECT1"
|
CLASS="REFSECT1"
|
><A
|
><A
|
NAME="SYNTH-NEW-HOST-BUILD"
|
NAME="SYNTH-NEW-HOST-BUILD"
|
></A
|
></A
|
><H2
|
><H2
|
>Building and Installation</H2
|
>Building and Installation</H2
|
><P
|
><P
|
>When an eCos device driver or application code instantiates a device,
|
>When an eCos device driver or application code instantiates a device,
|
the I/O auxiliary will attempt to load a matching Tcl script. The
|
the I/O auxiliary will attempt to load a matching Tcl script. The
|
third argument to <TT
|
third argument to <TT
|
CLASS="FUNCTION"
|
CLASS="FUNCTION"
|
>synth_auxiliary_instantiate</TT
|
>synth_auxiliary_instantiate</TT
|
>
|
>
|
specifies the type of device, for example <TT
|
specifies the type of device, for example <TT
|
CLASS="LITERAL"
|
CLASS="LITERAL"
|
>ethernet</TT
|
>ethernet</TT
|
>,
|
>,
|
and the I/O auxiliary will append a <TT
|
and the I/O auxiliary will append a <TT
|
CLASS="FILENAME"
|
CLASS="FILENAME"
|
>.tcl</TT
|
>.tcl</TT
|
> suffix
|
> suffix
|
and look for a script <TT
|
and look for a script <TT
|
CLASS="FILENAME"
|
CLASS="FILENAME"
|
>ethernet.tcl</TT
|
>ethernet.tcl</TT
|
>.
|
>.
|
</P
|
</P
|
><P
|
><P
|
>If the device being instantiated is application-specific rather than
|
>If the device being instantiated is application-specific rather than
|
part of an eCos package, the I/O auxiliary will look first in the
|
part of an eCos package, the I/O auxiliary will look first in the
|
current directory, then in <TT
|
current directory, then in <TT
|
CLASS="FILENAME"
|
CLASS="FILENAME"
|
>~/.ecos/synth</TT
|
>~/.ecos/synth</TT
|
>. If it is part of an eCos
|
>. If it is part of an eCos
|
package then the auxiliary will expect to find the Tcl script and any
|
package then the auxiliary will expect to find the Tcl script and any
|
support files below <TT
|
support files below <TT
|
CLASS="FILENAME"
|
CLASS="FILENAME"
|
>libexec/ecos</TT
|
>libexec/ecos</TT
|
> in the install tree - note
|
> in the install tree - note
|
that the same install tree must be used for the I/O auxiliary itself
|
that the same install tree must be used for the I/O auxiliary itself
|
and for any device driver support. The directory hierarchy below
|
and for any device driver support. The directory hierarchy below
|
<TT
|
<TT
|
CLASS="FILENAME"
|
CLASS="FILENAME"
|
>libexec/ecos</TT
|
>libexec/ecos</TT
|
> matches the
|
> matches the
|
structure of the eCos repository, allowing multiple versions of a
|
structure of the eCos repository, allowing multiple versions of a
|
package to be installed to allow for incompatible protocol changes.
|
package to be installed to allow for incompatible protocol changes.
|
</P
|
</P
|
><P
|
><P
|
>The preferred way to build host-side software is to use
|
>The preferred way to build host-side software is to use
|
<B
|
<B
|
CLASS="COMMAND"
|
CLASS="COMMAND"
|
>autoconf</B
|
>autoconf</B
|
> and <B
|
> and <B
|
CLASS="COMMAND"
|
CLASS="COMMAND"
|
>automake</B
|
>automake</B
|
>. Usually
|
>. Usually
|
this involves little more than copying the
|
this involves little more than copying the
|
<TT
|
<TT
|
CLASS="FILENAME"
|
CLASS="FILENAME"
|
>acinclude.m4</TT
|
>acinclude.m4</TT
|
>, <TT
|
>, <TT
|
CLASS="FILENAME"
|
CLASS="FILENAME"
|
>configure.in</TT
|
>configure.in</TT
|
>
|
>
|
and <TT
|
and <TT
|
CLASS="FILENAME"
|
CLASS="FILENAME"
|
>Makefile.am</TT
|
>Makefile.am</TT
|
> files from an existing package,
|
> files from an existing package,
|
for example the synthetic target ethernet driver, and then making
|
for example the synthetic target ethernet driver, and then making
|
minor edits. In <TT
|
minor edits. In <TT
|
CLASS="FILENAME"
|
CLASS="FILENAME"
|
>acinclude.m4</TT
|
>acinclude.m4</TT
|
> it may be necessary
|
> it may be necessary
|
to adjust the path to the root of the repository.
|
to adjust the path to the root of the repository.
|
<TT
|
<TT
|
CLASS="FILENAME"
|
CLASS="FILENAME"
|
>configure.in</TT
|
>configure.in</TT
|
> may require a similar change, and
|
> may require a similar change, and
|
the <TT
|
the <TT
|
CLASS="FUNCTION"
|
CLASS="FUNCTION"
|
>AC_INIT</TT
|
>AC_INIT</TT
|
> macro invocation will have to be
|
> macro invocation will have to be
|
changed to match one of the files in the new package. A critical macro
|
changed to match one of the files in the new package. A critical macro
|
in this file is <TT
|
in this file is <TT
|
CLASS="FILENAME"
|
CLASS="FILENAME"
|
>ECOS_PACKAGE_DIRS</TT
|
>ECOS_PACKAGE_DIRS</TT
|
> which will set
|
> which will set
|
up the correct install directory. <TT
|
up the correct install directory. <TT
|
CLASS="FILENAME"
|
CLASS="FILENAME"
|
>Makefile.am</TT
|
>Makefile.am</TT
|
> may
|
> may
|
require some more changes, for example to specify the data files that
|
require some more changes, for example to specify the data files that
|
should be installed (including the Tcl script). These files should
|
should be installed (including the Tcl script). These files should
|
then be processed using <B
|
then be processed using <B
|
CLASS="COMMAND"
|
CLASS="COMMAND"
|
>aclocal</B
|
>aclocal</B
|
>,
|
>,
|
<B
|
<B
|
CLASS="COMMAND"
|
CLASS="COMMAND"
|
>autoconf</B
|
>autoconf</B
|
> and <B
|
> and <B
|
CLASS="COMMAND"
|
CLASS="COMMAND"
|
>automake</B
|
>automake</B
|
> in that
|
> in that
|
order. Actually building the software then just involves
|
order. Actually building the software then just involves
|
<B
|
<B
|
CLASS="COMMAND"
|
CLASS="COMMAND"
|
>configure</B
|
>configure</B
|
>, <B
|
>, <B
|
CLASS="COMMAND"
|
CLASS="COMMAND"
|
>make</B
|
>make</B
|
> and
|
> and
|
<B
|
<B
|
CLASS="COMMAND"
|
CLASS="COMMAND"
|
>make install</B
|
>make install</B
|
>, as per the instructions in the
|
>, as per the instructions in the
|
toplevel <TT
|
toplevel <TT
|
CLASS="FILENAME"
|
CLASS="FILENAME"
|
>README.host</TT
|
>README.host</TT
|
> file.
|
> file.
|
</P
|
</P
|
><P
|
><P
|
>To assist developers, if the environment variable
|
>To assist developers, if the environment variable
|
<TT
|
<TT
|
CLASS="ENVAR"
|
CLASS="ENVAR"
|
>ECOSYNTH_DEVEL</TT
|
>ECOSYNTH_DEVEL</TT
|
> is set then a slightly different
|
> is set then a slightly different
|
algorithm is used for locating device Tcl scripts. Instead of looking
|
algorithm is used for locating device Tcl scripts. Instead of looking
|
only in the install tree the I/O auxiliary will also look in the
|
only in the install tree the I/O auxiliary will also look in the
|
source tree, and if the script there is more recent than the installed
|
source tree, and if the script there is more recent than the installed
|
version it will be used in preference. This allows developers to
|
version it will be used in preference. This allows developers to
|
modify the master copy without having to run <B
|
modify the master copy without having to run <B
|
CLASS="COMMAND"
|
CLASS="COMMAND"
|
>make
|
>make
|
install</B
|
install</B
|
> all the time.
|
> all the time.
|
</P
|
</P
|
><P
|
><P
|
>If a script needs to know where it has been installed it can examine
|
>If a script needs to know where it has been installed it can examine
|
the Tcl variable <TT
|
the Tcl variable <TT
|
CLASS="VARNAME"
|
CLASS="VARNAME"
|
>synth::device_install_dir</TT
|
>synth::device_install_dir</TT
|
> . This
|
> . This
|
variable gets updated whenever a script is loaded, so if the
|
variable gets updated whenever a script is loaded, so if the
|
value may be needed later it should be saved away in a device-specific
|
value may be needed later it should be saved away in a device-specific
|
variable.
|
variable.
|
</P
|
</P
|
></DIV
|
></DIV
|
><DIV
|
><DIV
|
CLASS="REFSECT1"
|
CLASS="REFSECT1"
|
><A
|
><A
|
NAME="SYNTH-NEW-HOST-INSTANTIATION"
|
NAME="SYNTH-NEW-HOST-INSTANTIATION"
|
></A
|
></A
|
><H2
|
><H2
|
>Instantiation</H2
|
>Instantiation</H2
|
><P
|
><P
|
>The I/O auxiliary will <B
|
>The I/O auxiliary will <B
|
CLASS="COMMAND"
|
CLASS="COMMAND"
|
>source</B
|
>source</B
|
> the device-specific
|
> the device-specific
|
Tcl script when the eCos application first attempts to instantiate a
|
Tcl script when the eCos application first attempts to instantiate a
|
device of that type. The script should return a procedure that will be
|
device of that type. The script should return a procedure that will be
|
invoked to instantiate a device.
|
invoked to instantiate a device.
|
</P
|
</P
|
><TABLE
|
><TABLE
|
BORDER="5"
|
BORDER="5"
|
BGCOLOR="#E0E0F0"
|
BGCOLOR="#E0E0F0"
|
WIDTH="70%"
|
WIDTH="70%"
|
><TR
|
><TR
|
><TD
|
><TD
|
><PRE
|
><PRE
|
CLASS="PROGRAMLISTING"
|
CLASS="PROGRAMLISTING"
|
>namespace eval ethernet {
|
>namespace eval ethernet {
|
…
|
…
|
proc instantiate { id instance data } {
|
proc instantiate { id instance data } {
|
…
|
…
|
return ethernet::handle_request
|
return ethernet::handle_request
|
}
|
}
|
}
|
}
|
return ethernet::instantiate</PRE
|
return ethernet::instantiate</PRE
|
></TD
|
></TD
|
></TR
|
></TR
|
></TABLE
|
></TABLE
|
><P
|
><P
|
>The <TT
|
>The <TT
|
CLASS="VARNAME"
|
CLASS="VARNAME"
|
>id</TT
|
>id</TT
|
> argument is a unique identifier for this
|
> argument is a unique identifier for this
|
device instance. It will also be supplied on subsequent calls to the
|
device instance. It will also be supplied on subsequent calls to the
|
request handler, and will match the return value of
|
request handler, and will match the return value of
|
<TT
|
<TT
|
CLASS="FUNCTION"
|
CLASS="FUNCTION"
|
>synth_auxiliary_instantiate</TT
|
>synth_auxiliary_instantiate</TT
|
> on the target side. A
|
> on the target side. A
|
common use for this value is as an array index to support multiple
|
common use for this value is as an array index to support multiple
|
instances of this types of device. The <TT
|
instances of this types of device. The <TT
|
CLASS="VARNAME"
|
CLASS="VARNAME"
|
>instance</TT
|
>instance</TT
|
> and
|
> and
|
<TT
|
<TT
|
CLASS="VARNAME"
|
CLASS="VARNAME"
|
>data</TT
|
>data</TT
|
> arguments match the corresponding arguments to
|
> arguments match the corresponding arguments to
|
<TT
|
<TT
|
CLASS="FUNCTION"
|
CLASS="FUNCTION"
|
>synth_auxiliary_instantiate</TT
|
>synth_auxiliary_instantiate</TT
|
> on the target side, so
|
> on the target side, so
|
a typical value for <TT
|
a typical value for <TT
|
CLASS="VARNAME"
|
CLASS="VARNAME"
|
>instance</TT
|
>instance</TT
|
> would be
|
> would be
|
<TT
|
<TT
|
CLASS="LITERAL"
|
CLASS="LITERAL"
|
>eth0</TT
|
>eth0</TT
|
>, and <TT
|
>, and <TT
|
CLASS="VARNAME"
|
CLASS="VARNAME"
|
>data</TT
|
>data</TT
|
> is used to pass
|
> is used to pass
|
arbitrary initialization parameters from target to host.
|
arbitrary initialization parameters from target to host.
|
</P
|
</P
|
><P
|
><P
|
>The actual work done by the instantiation procedure is obviously
|
>The actual work done by the instantiation procedure is obviously
|
device-specific. It may involve allocating an <A
|
device-specific. It may involve allocating an <A
|
HREF="synth-new-host.html#SYNTH-NEW-HOST-INTERRUPTS"
|
HREF="synth-new-host.html#SYNTH-NEW-HOST-INTERRUPTS"
|
>interrupt vector</A
|
>interrupt vector</A
|
>, adding a
|
>, adding a
|
device-specific subwindow to the display, opening a real Linux device,
|
device-specific subwindow to the display, opening a real Linux device,
|
establishing a socket connection to some server, spawning a separate
|
establishing a socket connection to some server, spawning a separate
|
process to handle the actual I/O, or a combination of some or all of
|
process to handle the actual I/O, or a combination of some or all of
|
the above.
|
the above.
|
</P
|
</P
|
><P
|
><P
|
>If the device is successfully instantiated then the return value
|
>If the device is successfully instantiated then the return value
|
should be a handler for subsequent I/O requests. Otherwise the return
|
should be a handler for subsequent I/O requests. Otherwise the return
|
value should be an empty string, and on the target-side the
|
value should be an empty string, and on the target-side the
|
<TT
|
<TT
|
CLASS="FUNCTION"
|
CLASS="FUNCTION"
|
>synth_auxiliary_instantiate</TT
|
>synth_auxiliary_instantiate</TT
|
> call will return
|
> call will return
|
<TT
|
<TT
|
CLASS="LITERAL"
|
CLASS="LITERAL"
|
>-1</TT
|
>-1</TT
|
>. The script is responsible for providing
|
>. The script is responsible for providing
|
<A
|
<A
|
HREF="synth-new-host.html#SYNTH-NEW-HOST-OUTPUT"
|
HREF="synth-new-host.html#SYNTH-NEW-HOST-OUTPUT"
|
>diagnostics</A
|
>diagnostics</A
|
> explaining
|
> explaining
|
why the device could not be instantiated.
|
why the device could not be instantiated.
|
</P
|
</P
|
></DIV
|
></DIV
|
><DIV
|
><DIV
|
CLASS="REFSECT1"
|
CLASS="REFSECT1"
|
><A
|
><A
|
NAME="SYNTH-NEW-HOST-REQUESTS"
|
NAME="SYNTH-NEW-HOST-REQUESTS"
|
></A
|
></A
|
><H2
|
><H2
|
>Handling Requests</H2
|
>Handling Requests</H2
|
><P
|
><P
|
>When the target-side calls
|
>When the target-side calls
|
<TT
|
<TT
|
CLASS="FUNCTION"
|
CLASS="FUNCTION"
|
>synth_auxiliary_xchgmsg</TT
|
>synth_auxiliary_xchgmsg</TT
|
>, the I/O auxiliary will
|
>, the I/O auxiliary will
|
end up calling the request handler for the appropriate device instance
|
end up calling the request handler for the appropriate device instance
|
returned during instantiation:
|
returned during instantiation:
|
</P
|
</P
|
><TABLE
|
><TABLE
|
BORDER="5"
|
BORDER="5"
|
BGCOLOR="#E0E0F0"
|
BGCOLOR="#E0E0F0"
|
WIDTH="70%"
|
WIDTH="70%"
|
><TR
|
><TR
|
><TD
|
><TD
|
><PRE
|
><PRE
|
CLASS="PROGRAMLISTING"
|
CLASS="PROGRAMLISTING"
|
>namespace eval ethernet {
|
>namespace eval ethernet {
|
…
|
…
|
proc handle_request { id request arg1 arg2 txdata txlen max_rxlen } {
|
proc handle_request { id request arg1 arg2 txdata txlen max_rxlen } {
|
…
|
…
|
if { <some condition> } {
|
if { <some condition> } {
|
synth::send_reply <error code> 0 ""
|
synth::send_reply <error code> 0 ""
|
return
|
return
|
}
|
}
|
…
|
…
|
synth::send_reply <reply code> $packet_len $packet
|
synth::send_reply <reply code> $packet_len $packet
|
}
|
}
|
…
|
…
|
}</PRE
|
}</PRE
|
></TD
|
></TD
|
></TR
|
></TR
|
></TABLE
|
></TABLE
|
><P
|
><P
|
>The <TT
|
>The <TT
|
CLASS="VARNAME"
|
CLASS="VARNAME"
|
>id</TT
|
>id</TT
|
> argument is the same device id that was
|
> argument is the same device id that was
|
passed to the instantiate function, and is typically used as an array
|
passed to the instantiate function, and is typically used as an array
|
index to access per-device data. The <TT
|
index to access per-device data. The <TT
|
CLASS="VARNAME"
|
CLASS="VARNAME"
|
>request</TT
|
>request</TT
|
>,
|
>,
|
<TT
|
<TT
|
CLASS="VARNAME"
|
CLASS="VARNAME"
|
>arg1</TT
|
>arg1</TT
|
>, <TT
|
>, <TT
|
CLASS="VARNAME"
|
CLASS="VARNAME"
|
>arg2</TT
|
>arg2</TT
|
>, and
|
>, and
|
<TT
|
<TT
|
CLASS="VARNAME"
|
CLASS="VARNAME"
|
>max_rxlen</TT
|
>max_rxlen</TT
|
> are the same values that were passed to
|
> are the same values that were passed to
|
<TT
|
<TT
|
CLASS="FUNCTION"
|
CLASS="FUNCTION"
|
>synth_auxiliary_xchgmsg</TT
|
>synth_auxiliary_xchgmsg</TT
|
> on the target-side,
|
> on the target-side,
|
although since this is a Tcl script obviously the numbers have been
|
although since this is a Tcl script obviously the numbers have been
|
converted to strings. The <TT
|
converted to strings. The <TT
|
CLASS="VARNAME"
|
CLASS="VARNAME"
|
>txdata</TT
|
>txdata</TT
|
> buffer is raw data
|
> buffer is raw data
|
as transmitted by the target, or an empty string if the I/O operation
|
as transmitted by the target, or an empty string if the I/O operation
|
does not involve any additional data. The Tcl procedures
|
does not involve any additional data. The Tcl procedures
|
<B
|
<B
|
CLASS="COMMAND"
|
CLASS="COMMAND"
|
>binary scan</B
|
>binary scan</B
|
>, <B
|
>, <B
|
CLASS="COMMAND"
|
CLASS="COMMAND"
|
>string index</B
|
>string index</B
|
> and
|
> and
|
<B
|
<B
|
CLASS="COMMAND"
|
CLASS="COMMAND"
|
>string range</B
|
>string range</B
|
> may be found especially useful when
|
> may be found especially useful when
|
manipulating this buffer. <TT
|
manipulating this buffer. <TT
|
CLASS="VARNAME"
|
CLASS="VARNAME"
|
>txlen</TT
|
>txlen</TT
|
> is provided for
|
> is provided for
|
convenience, although <B
|
convenience, although <B
|
CLASS="COMMAND"
|
CLASS="COMMAND"
|
>string length $txdata</B
|
>string length $txdata</B
|
> would
|
> would
|
give the same information.
|
give the same information.
|
</P
|
</P
|
><P
|
><P
|
>The code for actually processing the request is of course device
|
>The code for actually processing the request is of course device
|
specific. If the target does not expect a reply then the request
|
specific. If the target does not expect a reply then the request
|
handler should just return when finished. If a reply is expected then
|
handler should just return when finished. If a reply is expected then
|
there should be a call to <B
|
there should be a call to <B
|
CLASS="COMMAND"
|
CLASS="COMMAND"
|
>synth::send_reply</B
|
>synth::send_reply</B
|
>. The
|
>. The
|
first argument is the reply code, and will be turned into a 32-bit
|
first argument is the reply code, and will be turned into a 32-bit
|
integer on the target side. The second argument specifies the length
|
integer on the target side. The second argument specifies the length
|
of the reply data, and the third argument is the reply data itself.
|
of the reply data, and the third argument is the reply data itself.
|
For some devices the Tcl procedure <B
|
For some devices the Tcl procedure <B
|
CLASS="COMMAND"
|
CLASS="COMMAND"
|
>binary format</B
|
>binary format</B
|
>
|
>
|
may prove useful. If the reply involves just a code and no additional
|
may prove useful. If the reply involves just a code and no additional
|
data, the second and third arguments should be <TT
|
data, the second and third arguments should be <TT
|
CLASS="LITERAL"
|
CLASS="LITERAL"
|
>0</TT
|
>0</TT
|
>
|
>
|
and an empty string respectively.
|
and an empty string respectively.
|
</P
|
</P
|
><P
|
><P
|
>Attempts to send a reply when none is expected, fail to send a reply
|
>Attempts to send a reply when none is expected, fail to send a reply
|
when one is expected, or send a reply that is larger than the
|
when one is expected, or send a reply that is larger than the
|
target-side expects, will all be detected by the I/O auxiliary and
|
target-side expects, will all be detected by the I/O auxiliary and
|
result in run-time error messages.
|
result in run-time error messages.
|
</P
|
</P
|
><P
|
><P
|
>It is not possible for the host-side code to send unsolicited messages
|
>It is not possible for the host-side code to send unsolicited messages
|
to the target. If host-side code needs attention from the target, for
|
to the target. If host-side code needs attention from the target, for
|
example because some I/O operation has completed, then an interrupt
|
example because some I/O operation has completed, then an interrupt
|
should be raised.
|
should be raised.
|
</P
|
</P
|
></DIV
|
></DIV
|
><DIV
|
><DIV
|
CLASS="REFSECT1"
|
CLASS="REFSECT1"
|
><A
|
><A
|
NAME="SYNTH-NEW-HOST-INTERRUPTS"
|
NAME="SYNTH-NEW-HOST-INTERRUPTS"
|
></A
|
></A
|
><H2
|
><H2
|
>Interrupts</H2
|
>Interrupts</H2
|
><P
|
><P
|
>The I/O auxiliary provides a number of procedures for interrupt
|
>The I/O auxiliary provides a number of procedures for interrupt
|
handling.
|
handling.
|
</P
|
</P
|
><TABLE
|
><TABLE
|
BORDER="5"
|
BORDER="5"
|
BGCOLOR="#E0E0F0"
|
BGCOLOR="#E0E0F0"
|
WIDTH="70%"
|
WIDTH="70%"
|
><TR
|
><TR
|
><TD
|
><TD
|
><PRE
|
><PRE
|
CLASS="PROGRAMLISTING"
|
CLASS="PROGRAMLISTING"
|
>synth::interrupt_allocate <name>
|
>synth::interrupt_allocate <name>
|
synth::interrupt_get_max
|
synth::interrupt_get_max
|
synth::interrupt_get_devicename <vector>
|
synth::interrupt_get_devicename <vector>
|
synth::interrupt_raise <vector></PRE
|
synth::interrupt_raise <vector></PRE
|
></TD
|
></TD
|
></TR
|
></TR
|
></TABLE
|
></TABLE
|
><P
|
><P
|
><B
|
><B
|
CLASS="COMMAND"
|
CLASS="COMMAND"
|
>synth::interrupt_allocate</B
|
>synth::interrupt_allocate</B
|
> is normally called during
|
> is normally called during
|
device instantiation, and returns the next free interrupt vector. This
|
device instantiation, and returns the next free interrupt vector. This
|
can be passed on to the target-side device driver in response to a
|
can be passed on to the target-side device driver in response to a
|
suitable request, and it can then install an interrupt handler on that
|
suitable request, and it can then install an interrupt handler on that
|
vector. Interrupt vector <TT
|
vector. Interrupt vector <TT
|
CLASS="LITERAL"
|
CLASS="LITERAL"
|
>0</TT
|
>0</TT
|
> is used within the
|
> is used within the
|
target-side code for the real-time clock, so the allocated vectors
|
target-side code for the real-time clock, so the allocated vectors
|
will start at <TT
|
will start at <TT
|
CLASS="LITERAL"
|
CLASS="LITERAL"
|
>1</TT
|
>1</TT
|
>. The argument identifies the
|
>. The argument identifies the
|
device, for example <TT
|
device, for example <TT
|
CLASS="LITERAL"
|
CLASS="LITERAL"
|
>eth0</TT
|
>eth0</TT
|
>. This is not actually used
|
>. This is not actually used
|
internally, but can be accessed by user-initialization scripts that
|
internally, but can be accessed by user-initialization scripts that
|
provide some sort of interrupt monitoring facility (typically via the
|
provide some sort of interrupt monitoring facility (typically via the
|
<TT
|
<TT
|
CLASS="LITERAL"
|
CLASS="LITERAL"
|
>interrupt</TT
|
>interrupt</TT
|
> <A
|
> <A
|
HREF="synth-new-host.html#SYNTH-NEW-HOST-HOOKS"
|
HREF="synth-new-host.html#SYNTH-NEW-HOST-HOOKS"
|
>hook</A
|
>hook</A
|
>). It is possible for a
|
>). It is possible for a
|
single device to allocate multiple interrupt vectors, but the
|
single device to allocate multiple interrupt vectors, but the
|
synthetic target supports a maximum of 32 such vectors.
|
synthetic target supports a maximum of 32 such vectors.
|
</P
|
</P
|
><P
|
><P
|
><B
|
><B
|
CLASS="COMMAND"
|
CLASS="COMMAND"
|
>synth::interrupt_get_max</B
|
>synth::interrupt_get_max</B
|
> returns the highest
|
> returns the highest
|
interrupt vector that has been allocated, or <TT
|
interrupt vector that has been allocated, or <TT
|
CLASS="LITERAL"
|
CLASS="LITERAL"
|
>0</TT
|
>0</TT
|
> if
|
> if
|
there have been no calls to
|
there have been no calls to
|
<B
|
<B
|
CLASS="COMMAND"
|
CLASS="COMMAND"
|
>synth::interrupt_allocate</B
|
>synth::interrupt_allocate</B
|
>.
|
>.
|
<B
|
<B
|
CLASS="COMMAND"
|
CLASS="COMMAND"
|
>synth::interrupt_get_devicename</B
|
>synth::interrupt_get_devicename</B
|
> returns the string
|
> returns the string
|
that was passed to <B
|
that was passed to <B
|
CLASS="COMMAND"
|
CLASS="COMMAND"
|
>synth::interrupt_allocate</B
|
>synth::interrupt_allocate</B
|
> when
|
> when
|
the vector was allocated.
|
the vector was allocated.
|
</P
|
</P
|
><P
|
><P
|
><B
|
><B
|
CLASS="COMMAND"
|
CLASS="COMMAND"
|
>synth::interrupt_raise</B
|
>synth::interrupt_raise</B
|
> can be called any time after
|
> can be called any time after
|
initialization. The argument should be the vector returned by
|
initialization. The argument should be the vector returned by
|
<B
|
<B
|
CLASS="COMMAND"
|
CLASS="COMMAND"
|
>synth::interrupt_allocate</B
|
>synth::interrupt_allocate</B
|
> for this device. It will
|
> for this device. It will
|
activate the normal eCos interrupt handling mechanism so, subject to
|
activate the normal eCos interrupt handling mechanism so, subject to
|
interrupts being enabled and this particular interrupt not being
|
interrupts being enabled and this particular interrupt not being
|
masked out, the appropriate ISR will run.
|
masked out, the appropriate ISR will run.
|
</P
|
</P
|
><DIV
|
><DIV
|
CLASS="NOTE"
|
CLASS="NOTE"
|
><BLOCKQUOTE
|
><BLOCKQUOTE
|
CLASS="NOTE"
|
CLASS="NOTE"
|
><P
|
><P
|
><B
|
><B
|
>Note: </B
|
>Note: </B
|
>At this time it is not possible for a device to allocate a specific
|
>At this time it is not possible for a device to allocate a specific
|
interrupt vector. The order in which interrupt vectors are assigned to
|
interrupt vector. The order in which interrupt vectors are assigned to
|
devices effectively depends on the order in which the eCos devices get
|
devices effectively depends on the order in which the eCos devices get
|
initialized, and that may change if the eCos application is rebuilt. A
|
initialized, and that may change if the eCos application is rebuilt. A
|
future extension may allow devices to allocate specific vectors, thus
|
future extension may allow devices to allocate specific vectors, thus
|
making things more deterministic. However that will introduce new
|
making things more deterministic. However that will introduce new
|
problems, in particular the code will have to start worrying about
|
problems, in particular the code will have to start worrying about
|
requests for vectors that have already been allocated.
|
requests for vectors that have already been allocated.
|
</P
|
</P
|
></BLOCKQUOTE
|
></BLOCKQUOTE
|
></DIV
|
></DIV
|
></DIV
|
></DIV
|
><DIV
|
><DIV
|
CLASS="REFSECT1"
|
CLASS="REFSECT1"
|
><A
|
><A
|
NAME="SYNTH-NEW-HOST-ARGS"
|
NAME="SYNTH-NEW-HOST-ARGS"
|
></A
|
></A
|
><H2
|
><H2
|
>Flags and Command Line Arguments</H2
|
>Flags and Command Line Arguments</H2
|
><P
|
><P
|
>The generic I/O auxiliary code will process the standard command line
|
>The generic I/O auxiliary code will process the standard command line
|
arguments, and will set various flag variables accordingly. Some of
|
arguments, and will set various flag variables accordingly. Some of
|
these should be checked by device-specific scripts.
|
these should be checked by device-specific scripts.
|
</P
|
</P
|
><P
|
><P
|
></P
|
></P
|
><DIV
|
><DIV
|
CLASS="VARIABLELIST"
|
CLASS="VARIABLELIST"
|
><DL
|
><DL
|
><DT
|
><DT
|
><TT
|
><TT
|
CLASS="VARNAME"
|
CLASS="VARNAME"
|
>synth::flag_gui</TT
|
>synth::flag_gui</TT
|
></DT
|
></DT
|
><DD
|
><DD
|
><P
|
><P
|
>This is set when the I/O auxiliary is operating in graphical mode
|
>This is set when the I/O auxiliary is operating in graphical mode
|
rather than text mode. Some functionality such as filters and the GUI
|
rather than text mode. Some functionality such as filters and the GUI
|
layout are only available in graphical mode.
|
layout are only available in graphical mode.
|
</P
|
</P
|
><TABLE
|
><TABLE
|
BORDER="5"
|
BORDER="5"
|
BGCOLOR="#E0E0F0"
|
BGCOLOR="#E0E0F0"
|
WIDTH="70%"
|
WIDTH="70%"
|
><TR
|
><TR
|
><TD
|
><TD
|
><PRE
|
><PRE
|
CLASS="PROGRAMLISTING"
|
CLASS="PROGRAMLISTING"
|
> if { $synth::flag_gui } {
|
> if { $synth::flag_gui } {
|
…
|
…
|
}</PRE
|
}</PRE
|
></TD
|
></TD
|
></TR
|
></TR
|
></TABLE
|
></TABLE
|
></DD
|
></DD
|
><DT
|
><DT
|
><TT
|
><TT
|
CLASS="VARNAME"
|
CLASS="VARNAME"
|
>synth::flag_verbose</TT
|
>synth::flag_verbose</TT
|
></DT
|
></DT
|
><DD
|
><DD
|
><P
|
><P
|
>The user has requested additional information during startup. Each
|
>The user has requested additional information during startup. Each
|
device driver can decide how much additional information, if any,
|
device driver can decide how much additional information, if any,
|
should be produced.
|
should be produced.
|
</P
|
</P
|
></DD
|
></DD
|
><DT
|
><DT
|
><TT
|
><TT
|
CLASS="VARNAME"
|
CLASS="VARNAME"
|
>synth::flag_keep_going</TT
|
>synth::flag_keep_going</TT
|
></DT
|
></DT
|
><DD
|
><DD
|
><P
|
><P
|
>The user has specified <TT
|
>The user has specified <TT
|
CLASS="OPTION"
|
CLASS="OPTION"
|
>-k</TT
|
>-k</TT
|
> or
|
> or
|
<TT
|
<TT
|
CLASS="OPTION"
|
CLASS="OPTION"
|
>--keep-going</TT
|
>--keep-going</TT
|
>, so even if an error occurs the I/O
|
>, so even if an error occurs the I/O
|
auxiliary and the various device driver scripts should continue running
|
auxiliary and the various device driver scripts should continue running
|
if at all possible. Diagnostics should still be generated.
|
if at all possible. Diagnostics should still be generated.
|
</P
|
</P
|
></DD
|
></DD
|
></DL
|
></DL
|
></DIV
|
></DIV
|
><P
|
><P
|
>Some scripts may want to support additional command line arguments.
|
>Some scripts may want to support additional command line arguments.
|
This facility should be used with care since there is no way to
|
This facility should be used with care since there is no way to
|
prevent two different scripts from trying to use the same argument.
|
prevent two different scripts from trying to use the same argument.
|
The following Tcl procedures are available:
|
The following Tcl procedures are available:
|
</P
|
</P
|
><TABLE
|
><TABLE
|
BORDER="5"
|
BORDER="5"
|
BGCOLOR="#E0E0F0"
|
BGCOLOR="#E0E0F0"
|
WIDTH="70%"
|
WIDTH="70%"
|
><TR
|
><TR
|
><TD
|
><TD
|
><PRE
|
><PRE
|
CLASS="PROGRAMLISTING"
|
CLASS="PROGRAMLISTING"
|
>synth::argv_defined <name>
|
>synth::argv_defined <name>
|
synth::argv_get_value <name></PRE
|
synth::argv_get_value <name></PRE
|
></TD
|
></TD
|
></TR
|
></TR
|
></TABLE
|
></TABLE
|
><P
|
><P
|
><B
|
><B
|
CLASS="COMMAND"
|
CLASS="COMMAND"
|
>synth::argv_defined</B
|
>synth::argv_defined</B
|
> returns a boolean to indicate
|
> returns a boolean to indicate
|
whether or not a particular argument is present. If the argument is
|
whether or not a particular argument is present. If the argument is
|
the name part of a name/value pair, an <TT
|
the name part of a name/value pair, an <TT
|
CLASS="LITERAL"
|
CLASS="LITERAL"
|
>=</TT
|
>=</TT
|
> character
|
> character
|
should be appended. Typical uses might be:
|
should be appended. Typical uses might be:
|
</P
|
</P
|
><TABLE
|
><TABLE
|
BORDER="5"
|
BORDER="5"
|
BGCOLOR="#E0E0F0"
|
BGCOLOR="#E0E0F0"
|
WIDTH="70%"
|
WIDTH="70%"
|
><TR
|
><TR
|
><TD
|
><TD
|
><PRE
|
><PRE
|
CLASS="PROGRAMLISTING"
|
CLASS="PROGRAMLISTING"
|
> if { [synth::argv_defined "-o13"] } {
|
> if { [synth::argv_defined "-o13"] } {
|
…
|
…
|
}
|
}
|
|
|
if { [synth::argv_defined "-mark="] } {
|
if { [synth::argv_defined "-mark="] } {
|
…
|
…
|
}</PRE
|
}</PRE
|
></TD
|
></TD
|
></TR
|
></TR
|
></TABLE
|
></TABLE
|
><P
|
><P
|
>The first call checks for a flag <TT
|
>The first call checks for a flag <TT
|
CLASS="LITERAL"
|
CLASS="LITERAL"
|
>-o13</TT
|
>-o13</TT
|
> or
|
> or
|
<TT
|
<TT
|
CLASS="LITERAL"
|
CLASS="LITERAL"
|
>--o13</TT
|
>--o13</TT
|
> - the code treats options with single and
|
> - the code treats options with single and
|
double hyphens interchangeably. The second call checks for an argument
|
double hyphens interchangeably. The second call checks for an argument
|
of the form <TT
|
of the form <TT
|
CLASS="LITERAL"
|
CLASS="LITERAL"
|
>-mark=<value></TT
|
>-mark=<value></TT
|
> or a pair of
|
> or a pair of
|
arguments <TT
|
arguments <TT
|
CLASS="LITERAL"
|
CLASS="LITERAL"
|
>-mark <value></TT
|
>-mark <value></TT
|
>. The value part of a
|
>. The value part of a
|
name/value pair can be obtained using
|
name/value pair can be obtained using
|
<B
|
<B
|
CLASS="COMMAND"
|
CLASS="COMMAND"
|
>synth::argv_get_value</B
|
>synth::argv_get_value</B
|
>;
|
>;
|
</P
|
</P
|
><TABLE
|
><TABLE
|
BORDER="5"
|
BORDER="5"
|
BGCOLOR="#E0E0F0"
|
BGCOLOR="#E0E0F0"
|
WIDTH="70%"
|
WIDTH="70%"
|
><TR
|
><TR
|
><TD
|
><TD
|
><PRE
|
><PRE
|
CLASS="PROGRAMLISTING"
|
CLASS="PROGRAMLISTING"
|
> variable speed 1
|
> variable speed 1
|
if { [synth::argv_defined "-mark="] } {
|
if { [synth::argv_defined "-mark="] } {
|
set mark [synth::argv_get_value "-mark="]
|
set mark [synth::argv_get_value "-mark="]
|
if { ![string is integer $mark] || ($mark < 1) || ($mark > 9) } {
|
if { ![string is integer $mark] || ($mark < 1) || ($mark > 9) } {
|
<issue diagnostic>
|
<issue diagnostic>
|
} else {
|
} else {
|
set speed $mark
|
set speed $mark
|
}
|
}
|
}</PRE
|
}</PRE
|
></TD
|
></TD
|
></TR
|
></TR
|
></TABLE
|
></TABLE
|
><P
|
><P
|
><B
|
><B
|
CLASS="COMMAND"
|
CLASS="COMMAND"
|
>synth::argv_get_value</B
|
>synth::argv_get_value</B
|
> should only be used after a
|
> should only be used after a
|
successful call to <B
|
successful call to <B
|
CLASS="COMMAND"
|
CLASS="COMMAND"
|
>synth::argv_defined</B
|
>synth::argv_defined</B
|
>.
|
>.
|
At present there is no support for some advanced forms of command line
|
At present there is no support for some advanced forms of command line
|
argument processing. For example it is not possible to repeat a
|
argument processing. For example it is not possible to repeat a
|
certain option such as <TT
|
certain option such as <TT
|
CLASS="OPTION"
|
CLASS="OPTION"
|
>-v</TT
|
>-v</TT
|
> or
|
> or
|
<TT
|
<TT
|
CLASS="OPTION"
|
CLASS="OPTION"
|
>--verbose</TT
|
>--verbose</TT
|
>, with each occurrence increasing the level
|
>, with each occurrence increasing the level
|
of verbosity.
|
of verbosity.
|
</P
|
</P
|
><P
|
><P
|
>If a script is going to have its own set of command-line arguments
|
>If a script is going to have its own set of command-line arguments
|
then it should give appropriate details if the user specifies
|
then it should give appropriate details if the user specifies
|
<TT
|
<TT
|
CLASS="OPTION"
|
CLASS="OPTION"
|
>--help</TT
|
>--help</TT
|
>. This involves a hook function:
|
>. This involves a hook function:
|
</P
|
</P
|
><TABLE
|
><TABLE
|
BORDER="5"
|
BORDER="5"
|
BGCOLOR="#E0E0F0"
|
BGCOLOR="#E0E0F0"
|
WIDTH="70%"
|
WIDTH="70%"
|
><TR
|
><TR
|
><TD
|
><TD
|
><PRE
|
><PRE
|
CLASS="PROGRAMLISTING"
|
CLASS="PROGRAMLISTING"
|
>namespace eval my_device {
|
>namespace eval my_device {
|
proc help_hook { } {
|
proc help_hook { } {
|
puts " -o13 : activate the omega 13 device"
|
puts " -o13 : activate the omega 13 device"
|
puts " -mark <speed> : set speed. Valid values are 1 to 9."
|
puts " -mark <speed> : set speed. Valid values are 1 to 9."
|
}
|
}
|
|
|
synth::hook_add "help" my_device::help_hook
|
synth::hook_add "help" my_device::help_hook
|
}</PRE
|
}</PRE
|
></TD
|
></TD
|
></TR
|
></TR
|
></TABLE
|
></TABLE
|
></DIV
|
></DIV
|
><DIV
|
><DIV
|
CLASS="REFSECT1"
|
CLASS="REFSECT1"
|
><A
|
><A
|
NAME="SYNTH-NEW-HOST-TDF"
|
NAME="SYNTH-NEW-HOST-TDF"
|
></A
|
></A
|
><H2
|
><H2
|
>The Target Definition File</H2
|
>The Target Definition File</H2
|
><P
|
><P
|
>Most device scripts will want to check entries in the target
|
>Most device scripts will want to check entries in the target
|
definition file for run-time configuration information. The Tcl
|
definition file for run-time configuration information. The Tcl
|
procedures for this are as follows:
|
procedures for this are as follows:
|
</P
|
</P
|
><TABLE
|
><TABLE
|
BORDER="5"
|
BORDER="5"
|
BGCOLOR="#E0E0F0"
|
BGCOLOR="#E0E0F0"
|
WIDTH="70%"
|
WIDTH="70%"
|
><TR
|
><TR
|
><TD
|
><TD
|
><PRE
|
><PRE
|
CLASS="PROGRAMLISTING"
|
CLASS="PROGRAMLISTING"
|
>synth::tdf_has_device <name>
|
>synth::tdf_has_device <name>
|
synth::tdf_get_devices
|
synth::tdf_get_devices
|
synth::tdf_has_option <devname> <option>
|
synth::tdf_has_option <devname> <option>
|
synth::tdf_get_option <devname> <option>
|
synth::tdf_get_option <devname> <option>
|
synth::tdf_get_options <devname> <option>
|
synth::tdf_get_options <devname> <option>
|
synth::tdf_get_all_options <devname></PRE
|
synth::tdf_get_all_options <devname></PRE
|
></TD
|
></TD
|
></TR
|
></TR
|
></TABLE
|
></TABLE
|
><P
|
><P
|
><B
|
><B
|
CLASS="COMMAND"
|
CLASS="COMMAND"
|
>synth::tdf_has_device</B
|
>synth::tdf_has_device</B
|
> can be used to check whether
|
> can be used to check whether
|
or not the target definition file had an entry
|
or not the target definition file had an entry
|
<TT
|
<TT
|
CLASS="LITERAL"
|
CLASS="LITERAL"
|
>synth_device <name></TT
|
>synth_device <name></TT
|
>. Usually the name
|
>. Usually the name
|
will match the type of device, so the
|
will match the type of device, so the
|
<TT
|
<TT
|
CLASS="FILENAME"
|
CLASS="FILENAME"
|
>console.tcl</TT
|
>console.tcl</TT
|
> script will look for a target
|
> script will look for a target
|
definition file entry <TT
|
definition file entry <TT
|
CLASS="LITERAL"
|
CLASS="LITERAL"
|
>console</TT
|
>console</TT
|
>.
|
>.
|
<B
|
<B
|
CLASS="COMMAND"
|
CLASS="COMMAND"
|
>synth::tdf_get_devices</B
|
>synth::tdf_get_devices</B
|
> returns a list of all
|
> returns a list of all
|
device entries in the target definition file.
|
device entries in the target definition file.
|
</P
|
</P
|
><P
|
><P
|
>Once it is known that the target definition file has an entry for a
|
>Once it is known that the target definition file has an entry for a
|
certain device, it is possible to check for options within the entry.
|
certain device, it is possible to check for options within the entry.
|
<B
|
<B
|
CLASS="COMMAND"
|
CLASS="COMMAND"
|
>synth::tdf_has_option</B
|
>synth::tdf_has_option</B
|
> just checks for the presence,
|
> just checks for the presence,
|
returning a boolean:
|
returning a boolean:
|
</P
|
</P
|
><TABLE
|
><TABLE
|
BORDER="5"
|
BORDER="5"
|
BGCOLOR="#E0E0F0"
|
BGCOLOR="#E0E0F0"
|
WIDTH="70%"
|
WIDTH="70%"
|
><TR
|
><TR
|
><TD
|
><TD
|
><PRE
|
><PRE
|
CLASS="PROGRAMLISTING"
|
CLASS="PROGRAMLISTING"
|
> if { [synth::tdf_has_option "console" "appearance"] } {
|
> if { [synth::tdf_has_option "console" "appearance"] } {
|
…
|
…
|
}</PRE
|
}</PRE
|
></TD
|
></TD
|
></TR
|
></TR
|
></TABLE
|
></TABLE
|
><P
|
><P
|
><B
|
><B
|
CLASS="COMMAND"
|
CLASS="COMMAND"
|
>synth::tdf_get_option</B
|
>synth::tdf_get_option</B
|
> returns a list of all the
|
> returns a list of all the
|
arguments for a given option. For example, if the target definition
|
arguments for a given option. For example, if the target definition
|
file contains an entry:
|
file contains an entry:
|
</P
|
</P
|
><TABLE
|
><TABLE
|
BORDER="5"
|
BORDER="5"
|
BGCOLOR="#E0E0F0"
|
BGCOLOR="#E0E0F0"
|
WIDTH="70%"
|
WIDTH="70%"
|
><TR
|
><TR
|
><TD
|
><TD
|
><PRE
|
><PRE
|
CLASS="PROGRAMLISTING"
|
CLASS="PROGRAMLISTING"
|
>synth_device console {
|
>synth_device console {
|
appearance -foreground white -background black
|
appearance -foreground white -background black
|
filter trace {^TRACE:.*} -foreground HotPink1 -hide 1
|
filter trace {^TRACE:.*} -foreground HotPink1 -hide 1
|
filter xyzzy {.*xyzzy.*} -foreground PapayaWhip
|
filter xyzzy {.*xyzzy.*} -foreground PapayaWhip
|
}</PRE
|
}</PRE
|
></TD
|
></TD
|
></TR
|
></TR
|
></TABLE
|
></TABLE
|
><P
|
><P
|
>A call
|
>A call
|
<B
|
<B
|
CLASS="COMMAND"
|
CLASS="COMMAND"
|
>synth::tdf_get_option console appearance</B
|
>synth::tdf_get_option console appearance</B
|
>
|
>
|
will return the list <TT
|
will return the list <TT
|
CLASS="LITERAL"
|
CLASS="LITERAL"
|
>{-foreground white -background
|
>{-foreground white -background
|
black}</TT
|
black}</TT
|
>. This list can be manipulated using standard Tcl routines
|
>. This list can be manipulated using standard Tcl routines
|
such as <B
|
such as <B
|
CLASS="COMMAND"
|
CLASS="COMMAND"
|
>llength</B
|
>llength</B
|
> and <B
|
> and <B
|
CLASS="COMMAND"
|
CLASS="COMMAND"
|
>lindex</B
|
>lindex</B
|
>. Some
|
>. Some
|
options can occur multiple times in one entry, for example
|
options can occur multiple times in one entry, for example
|
<TT
|
<TT
|
CLASS="OPTION"
|
CLASS="OPTION"
|
>filter</TT
|
>filter</TT
|
> in the <TT
|
> in the <TT
|
CLASS="LITERAL"
|
CLASS="LITERAL"
|
>console</TT
|
>console</TT
|
> entry.
|
> entry.
|
<B
|
<B
|
CLASS="COMMAND"
|
CLASS="COMMAND"
|
>synth::tdf_get_options</B
|
>synth::tdf_get_options</B
|
> returns a list of lists,
|
> returns a list of lists,
|
with one entry for each option occurrence.
|
with one entry for each option occurrence.
|
<B
|
<B
|
CLASS="COMMAND"
|
CLASS="COMMAND"
|
>synth::tdf_get_all_options</B
|
>synth::tdf_get_all_options</B
|
> returns a list of lists
|
> returns a list of lists
|
of all options. This time each entry will include the option name as
|
of all options. This time each entry will include the option name as
|
well.
|
well.
|
</P
|
</P
|
><P
|
><P
|
>The I/O auxiliary will not issue warnings about entries in the target
|
>The I/O auxiliary will not issue warnings about entries in the target
|
definition file for devices which were not loaded, unless the
|
definition file for devices which were not loaded, unless the
|
<TT
|
<TT
|
CLASS="OPTION"
|
CLASS="OPTION"
|
>-v</TT
|
>-v</TT
|
> or <TT
|
> or <TT
|
CLASS="OPTION"
|
CLASS="OPTION"
|
>--verbose</TT
|
>--verbose</TT
|
> command line
|
> command line
|
argument was used. This makes it easier to use a single target
|
argument was used. This makes it easier to use a single target
|
definition file for different applications. However the auxiliary will
|
definition file for different applications. However the auxiliary will
|
issue warnings about options within an entry that were ignored,
|
issue warnings about options within an entry that were ignored,
|
because often these indicate a typing mistake of some sort. Hence a
|
because often these indicate a typing mistake of some sort. Hence a
|
script should always call <B
|
script should always call <B
|
CLASS="COMMAND"
|
CLASS="COMMAND"
|
>synth::tdf_has_option</B
|
>synth::tdf_has_option</B
|
>,
|
>,
|
<B
|
<B
|
CLASS="COMMAND"
|
CLASS="COMMAND"
|
>synth:;tdf_get_option</B
|
>synth:;tdf_get_option</B
|
> or
|
> or
|
<B
|
<B
|
CLASS="COMMAND"
|
CLASS="COMMAND"
|
>synth::tdf_get_options</B
|
>synth::tdf_get_options</B
|
> for all valid options, even
|
> for all valid options, even
|
if some of the options preclude the use of others.
|
if some of the options preclude the use of others.
|
</P
|
</P
|
></DIV
|
></DIV
|
><DIV
|
><DIV
|
CLASS="REFSECT1"
|
CLASS="REFSECT1"
|
><A
|
><A
|
NAME="SYNTH-NEW-HOST-HOOKS"
|
NAME="SYNTH-NEW-HOST-HOOKS"
|
></A
|
></A
|
><H2
|
><H2
|
>Hooks</H2
|
>Hooks</H2
|
><P
|
><P
|
>Some scripts may want to take action when particular events occur, for
|
>Some scripts may want to take action when particular events occur, for
|
example when the eCos application has exited and there is no need for
|
example when the eCos application has exited and there is no need for
|
further I/O. This is supported using hooks:
|
further I/O. This is supported using hooks:
|
</P
|
</P
|
><TABLE
|
><TABLE
|
BORDER="5"
|
BORDER="5"
|
BGCOLOR="#E0E0F0"
|
BGCOLOR="#E0E0F0"
|
WIDTH="70%"
|
WIDTH="70%"
|
><TR
|
><TR
|
><TD
|
><TD
|
><PRE
|
><PRE
|
CLASS="PROGRAMLISTING"
|
CLASS="PROGRAMLISTING"
|
>namespace eval my_device {
|
>namespace eval my_device {
|
…
|
…
|
proc handle_ecos_exit { arg_list } {
|
proc handle_ecos_exit { arg_list } {
|
…
|
…
|
}
|
}
|
synth::hook_add "ecos_exit" my_device::handle_ecos_exit
|
synth::hook_add "ecos_exit" my_device::handle_ecos_exit
|
}</PRE
|
}</PRE
|
></TD
|
></TD
|
></TR
|
></TR
|
></TABLE
|
></TABLE
|
><P
|
><P
|
>It is possible for device scripts to add their own hooks and call all
|
>It is possible for device scripts to add their own hooks and call all
|
functions registered for those hooks. A typical use for this is by
|
functions registered for those hooks. A typical use for this is by
|
user initialization scripts that want to monitor some types of I/O.
|
user initialization scripts that want to monitor some types of I/O.
|
The available Tcl procedures for manipulating hooks are:
|
The available Tcl procedures for manipulating hooks are:
|
</P
|
</P
|
><TABLE
|
><TABLE
|
BORDER="5"
|
BORDER="5"
|
BGCOLOR="#E0E0F0"
|
BGCOLOR="#E0E0F0"
|
WIDTH="70%"
|
WIDTH="70%"
|
><TR
|
><TR
|
><TD
|
><TD
|
><PRE
|
><PRE
|
CLASS="PROGRAMLISTING"
|
CLASS="PROGRAMLISTING"
|
>synth::hook_define <name>
|
>synth::hook_define <name>
|
synth::hook_defined <name>
|
synth::hook_defined <name>
|
synth::hook_add <name> <function>
|
synth::hook_add <name> <function>
|
synth::hook_call <name> <args></PRE
|
synth::hook_call <name> <args></PRE
|
></TD
|
></TD
|
></TR
|
></TR
|
></TABLE
|
></TABLE
|
><P
|
><P
|
><B
|
><B
|
CLASS="COMMAND"
|
CLASS="COMMAND"
|
>synth::hook_define</B
|
>synth::hook_define</B
|
> creates a new hook with the
|
> creates a new hook with the
|
specified name. This hook must not already exist.
|
specified name. This hook must not already exist.
|
<B
|
<B
|
CLASS="COMMAND"
|
CLASS="COMMAND"
|
>synth::hook_defined</B
|
>synth::hook_defined</B
|
> can be used to check for the
|
> can be used to check for the
|
existence of a hook. <B
|
existence of a hook. <B
|
CLASS="COMMAND"
|
CLASS="COMMAND"
|
>synth::hook_add</B
|
>synth::hook_add</B
|
> allows other
|
> allows other
|
scripts to register a callback function for this hook, and
|
scripts to register a callback function for this hook, and
|
<B
|
<B
|
CLASS="COMMAND"
|
CLASS="COMMAND"
|
>synth::hook_call</B
|
>synth::hook_call</B
|
> allows the owner script to invoke
|
> allows the owner script to invoke
|
all such callback functions. A hook must already be defined before a
|
all such callback functions. A hook must already be defined before a
|
callback can be attached. Therefore typically device scripts will only
|
callback can be attached. Therefore typically device scripts will only
|
use standard hooks and their own hooks, not hooks created by some
|
use standard hooks and their own hooks, not hooks created by some
|
other device, because the order of device initialization is not
|
other device, because the order of device initialization is not
|
sufficiently defined. User scripts run from
|
sufficiently defined. User scripts run from
|
<TT
|
<TT
|
CLASS="FILENAME"
|
CLASS="FILENAME"
|
>mainrc.tcl</TT
|
>mainrc.tcl</TT
|
> can use any hooks that have been
|
> can use any hooks that have been
|
defined.
|
defined.
|
</P
|
</P
|
><P
|
><P
|
><B
|
><B
|
CLASS="COMMAND"
|
CLASS="COMMAND"
|
>synth::hook_call</B
|
>synth::hook_call</B
|
> takes an arbitrary list of
|
> takes an arbitrary list of
|
arguments, for example:
|
arguments, for example:
|
</P
|
</P
|
><TABLE
|
><TABLE
|
BORDER="5"
|
BORDER="5"
|
BGCOLOR="#E0E0F0"
|
BGCOLOR="#E0E0F0"
|
WIDTH="70%"
|
WIDTH="70%"
|
><TR
|
><TR
|
><TD
|
><TD
|
><PRE
|
><PRE
|
CLASS="PROGRAMLISTING"
|
CLASS="PROGRAMLISTING"
|
> synth::hook_call "ethernet_rx" "eth0" $packet</PRE
|
> synth::hook_call "ethernet_rx" "eth0" $packet</PRE
|
></TD
|
></TD
|
></TR
|
></TR
|
></TABLE
|
></TABLE
|
><P
|
><P
|
>The callback function will always be invoked with a single argument,
|
>The callback function will always be invoked with a single argument,
|
a list of the arguments that were passed to
|
a list of the arguments that were passed to
|
<B
|
<B
|
CLASS="COMMAND"
|
CLASS="COMMAND"
|
>synth::hook_call</B
|
>synth::hook_call</B
|
>:
|
>:
|
</P
|
</P
|
><TABLE
|
><TABLE
|
BORDER="5"
|
BORDER="5"
|
BGCOLOR="#E0E0F0"
|
BGCOLOR="#E0E0F0"
|
WIDTH="70%"
|
WIDTH="70%"
|
><TR
|
><TR
|
><TD
|
><TD
|
><PRE
|
><PRE
|
CLASS="PROGRAMLISTING"
|
CLASS="PROGRAMLISTING"
|
> proc rx_callback { arg_list } {
|
> proc rx_callback { arg_list } {
|
set device [lindex $arg_list 0]
|
set device [lindex $arg_list 0]
|
set packet [lindex $arg_list 1]
|
set packet [lindex $arg_list 1]
|
}</PRE
|
}</PRE
|
></TD
|
></TD
|
></TR
|
></TR
|
></TABLE
|
></TABLE
|
><P
|
><P
|
>Although it might seem more appropriate to use Tcl's
|
>Although it might seem more appropriate to use Tcl's
|
<B
|
<B
|
CLASS="COMMAND"
|
CLASS="COMMAND"
|
>eval</B
|
>eval</B
|
> procedure and have the callback functions
|
> procedure and have the callback functions
|
invoked with the right number of arguments rather than a single list,
|
invoked with the right number of arguments rather than a single list,
|
that would cause serious problems if any of the data contained special
|
that would cause serious problems if any of the data contained special
|
characters such as <TT
|
characters such as <TT
|
CLASS="LITERAL"
|
CLASS="LITERAL"
|
>[</TT
|
>[</TT
|
> or <TT
|
> or <TT
|
CLASS="LITERAL"
|
CLASS="LITERAL"
|
>$</TT
|
>$</TT
|
>. The
|
>. The
|
current implementation of hooks avoids such problems, at the cost of
|
current implementation of hooks avoids such problems, at the cost of
|
minor inconvenience when writing callbacks.
|
minor inconvenience when writing callbacks.
|
</P
|
</P
|
><P
|
><P
|
>A number of hooks are defined as standard. Some devices will add
|
>A number of hooks are defined as standard. Some devices will add
|
additional hooks, and the device-specific documentation should be
|
additional hooks, and the device-specific documentation should be
|
consulted for those. User scripts can add their own hooks if desired.
|
consulted for those. User scripts can add their own hooks if desired.
|
</P
|
</P
|
><P
|
><P
|
></P
|
></P
|
><DIV
|
><DIV
|
CLASS="VARIABLELIST"
|
CLASS="VARIABLELIST"
|
><DL
|
><DL
|
><DT
|
><DT
|
><TT
|
><TT
|
CLASS="LITERAL"
|
CLASS="LITERAL"
|
>exit</TT
|
>exit</TT
|
></DT
|
></DT
|
><DD
|
><DD
|
><P
|
><P
|
>This hook is called just before the I/O auxiliary exits. Hence it
|
>This hook is called just before the I/O auxiliary exits. Hence it
|
provides much the same functionality as <TT
|
provides much the same functionality as <TT
|
CLASS="FUNCTION"
|
CLASS="FUNCTION"
|
>atexit</TT
|
>atexit</TT
|
> in
|
> in
|
C programs. The argument list passed to the callback function will be
|
C programs. The argument list passed to the callback function will be
|
empty.
|
empty.
|
</P
|
</P
|
></DD
|
></DD
|
><DT
|
><DT
|
><TT
|
><TT
|
CLASS="LITERAL"
|
CLASS="LITERAL"
|
>ecos_exit</TT
|
>ecos_exit</TT
|
></DT
|
></DT
|
><DD
|
><DD
|
><P
|
><P
|
>This hook is called when the eCos application has exited. It is used
|
>This hook is called when the eCos application has exited. It is used
|
mainly to shut down I/O operations: if the application is no longer
|
mainly to shut down I/O operations: if the application is no longer
|
running then there is no point in raising interrupts or storing
|
running then there is no point in raising interrupts or storing
|
incoming packets. The callback argument list will be empty.
|
incoming packets. The callback argument list will be empty.
|
</P
|
</P
|
></DD
|
></DD
|
><DT
|
><DT
|
><TT
|
><TT
|
CLASS="LITERAL"
|
CLASS="LITERAL"
|
>ecos_initialized</TT
|
>ecos_initialized</TT
|
></DT
|
></DT
|
><DD
|
><DD
|
><P
|
><P
|
>The synthetic target HAL will send a request to the I/O auxiliary once
|
>The synthetic target HAL will send a request to the I/O auxiliary once
|
the static constructors have been run. All devices should now have been
|
the static constructors have been run. All devices should now have been
|
instantiated. A script could now check how many instances there are of
|
instantiated. A script could now check how many instances there are of
|
a given type of device, for example ethernet devices, and create a
|
a given type of device, for example ethernet devices, and create a
|
little monitor window showing traffic on all the devices. The
|
little monitor window showing traffic on all the devices. The
|
<TT
|
<TT
|
CLASS="LITERAL"
|
CLASS="LITERAL"
|
>ecos_initialized</TT
|
>ecos_initialized</TT
|
> callbacks will be run just before
|
> callbacks will be run just before
|
the user's <TT
|
the user's <TT
|
CLASS="FILENAME"
|
CLASS="FILENAME"
|
>mainrc.tcl</TT
|
>mainrc.tcl</TT
|
> script. The callback
|
> script. The callback
|
argument list will be empty.
|
argument list will be empty.
|
</P
|
</P
|
></DD
|
></DD
|
><DT
|
><DT
|
><TT
|
><TT
|
CLASS="LITERAL"
|
CLASS="LITERAL"
|
>help</TT
|
>help</TT
|
></DT
|
></DT
|
><DD
|
><DD
|
><P
|
><P
|
>This hook is also invoked once static constructors have been run, but
|
>This hook is also invoked once static constructors have been run, but
|
only if the user specified <TT
|
only if the user specified <TT
|
CLASS="OPTION"
|
CLASS="OPTION"
|
>-h</TT
|
>-h</TT
|
> or
|
> or
|
<TT
|
<TT
|
CLASS="OPTION"
|
CLASS="OPTION"
|
>--help</TT
|
>--help</TT
|
>. Any scripts that add their own command line
|
>. Any scripts that add their own command line
|
arguments should add a callback to this hook which outputs details of
|
arguments should add a callback to this hook which outputs details of
|
the additional arguments. The callback argument list will be empty.
|
the additional arguments. The callback argument list will be empty.
|
</P
|
</P
|
></DD
|
></DD
|
><DT
|
><DT
|
><TT
|
><TT
|
CLASS="LITERAL"
|
CLASS="LITERAL"
|
>interrupt</TT
|
>interrupt</TT
|
></DT
|
></DT
|
><DD
|
><DD
|
><P
|
><P
|
>Whenever a device calls <B
|
>Whenever a device calls <B
|
CLASS="COMMAND"
|
CLASS="COMMAND"
|
>synth::interrupt_raise</B
|
>synth::interrupt_raise</B
|
> the
|
> the
|
<TT
|
<TT
|
CLASS="LITERAL"
|
CLASS="LITERAL"
|
>interrupt</TT
|
>interrupt</TT
|
> hook will be called with a single
|
> hook will be called with a single
|
argument, the interrupt vector. The main use for this is to allow
|
argument, the interrupt vector. The main use for this is to allow
|
user scripts to monitor interrupt traffic.
|
user scripts to monitor interrupt traffic.
|
</P
|
</P
|
></DD
|
></DD
|
></DL
|
></DL
|
></DIV
|
></DIV
|
></DIV
|
></DIV
|
><DIV
|
><DIV
|
CLASS="REFSECT1"
|
CLASS="REFSECT1"
|
><A
|
><A
|
NAME="SYNTH-NEW-HOST-OUTPUT"
|
NAME="SYNTH-NEW-HOST-OUTPUT"
|
></A
|
></A
|
><H2
|
><H2
|
>Output and Filters</H2
|
>Output and Filters</H2
|
><P
|
><P
|
>Scripts can use conventional facilities for sending text output to the
|
>Scripts can use conventional facilities for sending text output to the
|
user, for example calling <B
|
user, for example calling <B
|
CLASS="COMMAND"
|
CLASS="COMMAND"
|
>puts</B
|
>puts</B
|
> or directly
|
> or directly
|
manipulating the central text widget
|
manipulating the central text widget
|
<TT
|
<TT
|
CLASS="VARNAME"
|
CLASS="VARNAME"
|
>.main.centre.text</TT
|
>.main.centre.text</TT
|
>. However in nearly all cases it
|
>. However in nearly all cases it
|
is better to use output facilities provided by the I/O auxiliary
|
is better to use output facilities provided by the I/O auxiliary
|
itself:
|
itself:
|
</P
|
</P
|
><TABLE
|
><TABLE
|
BORDER="5"
|
BORDER="5"
|
BGCOLOR="#E0E0F0"
|
BGCOLOR="#E0E0F0"
|
WIDTH="70%"
|
WIDTH="70%"
|
><TR
|
><TR
|
><TD
|
><TD
|
><PRE
|
><PRE
|
CLASS="PROGRAMLISTING"
|
CLASS="PROGRAMLISTING"
|
>synth::report <msg>
|
>synth::report <msg>
|
synth::report_warning <msg>
|
synth::report_warning <msg>
|
synth::report_error <msg>
|
synth::report_error <msg>
|
synth::internal_error <msg>
|
synth::internal_error <msg>
|
synth::output <msg> <filter></PRE
|
synth::output <msg> <filter></PRE
|
></TD
|
></TD
|
></TR
|
></TR
|
></TABLE
|
></TABLE
|
><P
|
><P
|
><B
|
><B
|
CLASS="COMMAND"
|
CLASS="COMMAND"
|
>synth::report</B
|
>synth::report</B
|
> is intended for messages related to
|
> is intended for messages related to
|
the operation of the I/O auxiliary itself, especially additional
|
the operation of the I/O auxiliary itself, especially additional
|
output resulting from <TT
|
output resulting from <TT
|
CLASS="OPTION"
|
CLASS="OPTION"
|
>-v</TT
|
>-v</TT
|
> or
|
> or
|
<TT
|
<TT
|
CLASS="OPTION"
|
CLASS="OPTION"
|
>--verbose</TT
|
>--verbose</TT
|
>. If running in text mode the output will go
|
>. If running in text mode the output will go
|
to standard output. If running in graphical mode the output will go to
|
to standard output. If running in graphical mode the output will go to
|
the central text window. In both modes, use of <TT
|
the central text window. In both modes, use of <TT
|
CLASS="OPTION"
|
CLASS="OPTION"
|
>-l</TT
|
>-l</TT
|
> or
|
> or
|
<TT
|
<TT
|
CLASS="OPTION"
|
CLASS="OPTION"
|
>--logfile</TT
|
>--logfile</TT
|
> will modify the behaviour.
|
> will modify the behaviour.
|
</P
|
</P
|
><P
|
><P
|
><B
|
><B
|
CLASS="COMMAND"
|
CLASS="COMMAND"
|
>synth::report_warning</B
|
>synth::report_warning</B
|
>,
|
>,
|
<B
|
<B
|
CLASS="COMMAND"
|
CLASS="COMMAND"
|
>synth::report_error</B
|
>synth::report_error</B
|
> and
|
> and
|
<B
|
<B
|
CLASS="COMMAND"
|
CLASS="COMMAND"
|
>synth::internal_error</B
|
>synth::internal_error</B
|
> have the obvious meaning,
|
> have the obvious meaning,
|
including prepending strings such as <TT
|
including prepending strings such as <TT
|
CLASS="LITERAL"
|
CLASS="LITERAL"
|
>Warning:</TT
|
>Warning:</TT
|
> and
|
> and
|
<TT
|
<TT
|
CLASS="LITERAL"
|
CLASS="LITERAL"
|
>Error:</TT
|
>Error:</TT
|
>. When the eCos application informs the I/O
|
>. When the eCos application informs the I/O
|
auxiliary that all static constructors have run, if at that point
|
auxiliary that all static constructors have run, if at that point
|
there have been any calls to <B
|
there have been any calls to <B
|
CLASS="COMMAND"
|
CLASS="COMMAND"
|
>synth::error</B
|
>synth::error</B
|
> then the
|
> then the
|
I/O auxiliary will exit. This can be suppressed with command line
|
I/O auxiliary will exit. This can be suppressed with command line
|
arguments <TT
|
arguments <TT
|
CLASS="OPTION"
|
CLASS="OPTION"
|
>-k</TT
|
>-k</TT
|
> or <TT
|
> or <TT
|
CLASS="OPTION"
|
CLASS="OPTION"
|
>--keep-going</TT
|
>--keep-going</TT
|
>.
|
>.
|
<B
|
<B
|
CLASS="COMMAND"
|
CLASS="COMMAND"
|
>synth::internal_error</B
|
>synth::internal_error</B
|
> will output some information
|
> will output some information
|
about the current state of the I/O auxiliary and then exit
|
about the current state of the I/O auxiliary and then exit
|
immediately. Of course it should never be necessary to call this
|
immediately. Of course it should never be necessary to call this
|
function.
|
function.
|
</P
|
</P
|
><P
|
><P
|
><B
|
><B
|
CLASS="COMMAND"
|
CLASS="COMMAND"
|
>synth::output</B
|
>synth::output</B
|
> is the main routine for outputting
|
> is the main routine for outputting
|
text. The second argument identifies a filter. If running in text mode
|
text. The second argument identifies a filter. If running in text mode
|
the filter is ignored, but if running in graphical mode the filter can
|
the filter is ignored, but if running in graphical mode the filter can
|
be used to control the appearance of this output. A typical use would
|
be used to control the appearance of this output. A typical use would
|
be:
|
be:
|
</P
|
</P
|
><TABLE
|
><TABLE
|
BORDER="5"
|
BORDER="5"
|
BGCOLOR="#E0E0F0"
|
BGCOLOR="#E0E0F0"
|
WIDTH="70%"
|
WIDTH="70%"
|
><TR
|
><TR
|
><TD
|
><TD
|
><PRE
|
><PRE
|
CLASS="PROGRAMLISTING"
|
CLASS="PROGRAMLISTING"
|
> synth::output $line "console"</PRE
|
> synth::output $line "console"</PRE
|
></TD
|
></TD
|
></TR
|
></TR
|
></TABLE
|
></TABLE
|
><P
|
><P
|
>This outputs a single line of text using the
|
>This outputs a single line of text using the
|
<TT
|
<TT
|
CLASS="LITERAL"
|
CLASS="LITERAL"
|
>console</TT
|
>console</TT
|
> filter. If running in graphical mode the
|
> filter. If running in graphical mode the
|
default appearance of this text can be modified with the
|
default appearance of this text can be modified with the
|
<TT
|
<TT
|
CLASS="OPTION"
|
CLASS="OPTION"
|
>appearance</TT
|
>appearance</TT
|
> option in the
|
> option in the
|
<B
|
<B
|
CLASS="COMMAND"
|
CLASS="COMMAND"
|
>synth_device console</B
|
>synth_device console</B
|
> entry of the target
|
> entry of the target
|
definition file. The <SPAN
|
definition file. The <SPAN
|
CLASS="GUIMENUITEM"
|
CLASS="GUIMENUITEM"
|
>System filters</SPAN
|
>System filters</SPAN
|
> menu
|
> menu
|
option can be used to change the appearance at run-time.
|
option can be used to change the appearance at run-time.
|
</P
|
</P
|
><P
|
><P
|
>Filters should be created before they are used. The procedures
|
>Filters should be created before they are used. The procedures
|
available for this are:
|
available for this are:
|
</P
|
</P
|
><TABLE
|
><TABLE
|
BORDER="5"
|
BORDER="5"
|
BGCOLOR="#E0E0F0"
|
BGCOLOR="#E0E0F0"
|
WIDTH="70%"
|
WIDTH="70%"
|
><TR
|
><TR
|
><TD
|
><TD
|
><PRE
|
><PRE
|
CLASS="PROGRAMLISTING"
|
CLASS="PROGRAMLISTING"
|
>synth::filter_exists <name>
|
>synth::filter_exists <name>
|
synth::filter_get_list
|
synth::filter_get_list
|
synth::filter_add <name> [options]
|
synth::filter_add <name> [options]
|
synth::filter_parse_options <options> <parsed_options> <message>
|
synth::filter_parse_options <options> <parsed_options> <message>
|
synth::filter_add_parsed <name> <parsed_options></PRE
|
synth::filter_add_parsed <name> <parsed_options></PRE
|
></TD
|
></TD
|
></TR
|
></TR
|
></TABLE
|
></TABLE
|
><P
|
><P
|
><B
|
><B
|
CLASS="COMMAND"
|
CLASS="COMMAND"
|
>synth::filter_exists</B
|
>synth::filter_exists</B
|
> can be used to check whether
|
> can be used to check whether
|
or not a particular filter already exists: creating two filters with
|
or not a particular filter already exists: creating two filters with
|
the same name is not allowed.
|
the same name is not allowed.
|
<B
|
<B
|
CLASS="COMMAND"
|
CLASS="COMMAND"
|
>synth::filter_get_list</B
|
>synth::filter_get_list</B
|
> returns a list of the
|
> returns a list of the
|
current known filters. <B
|
current known filters. <B
|
CLASS="COMMAND"
|
CLASS="COMMAND"
|
>synth::filter_add</B
|
>synth::filter_add</B
|
> can be
|
> can be
|
used to create a new filter. The first argument names the new filter,
|
used to create a new filter. The first argument names the new filter,
|
and the remaining arguments control the initial appearance. A typical
|
and the remaining arguments control the initial appearance. A typical
|
use might be:
|
use might be:
|
</P
|
</P
|
><TABLE
|
><TABLE
|
BORDER="5"
|
BORDER="5"
|
BGCOLOR="#E0E0F0"
|
BGCOLOR="#E0E0F0"
|
WIDTH="70%"
|
WIDTH="70%"
|
><TR
|
><TR
|
><TD
|
><TD
|
><PRE
|
><PRE
|
CLASS="PROGRAMLISTING"
|
CLASS="PROGRAMLISTING"
|
> synth::filter_add "my_device_tx" -foreground yellow -hide 1</PRE
|
> synth::filter_add "my_device_tx" -foreground yellow -hide 1</PRE
|
></TD
|
></TD
|
></TR
|
></TR
|
></TABLE
|
></TABLE
|
><P
|
><P
|
>It is assumed that the supplied arguments are valid, which typically
|
>It is assumed that the supplied arguments are valid, which typically
|
means that they are hard-wired in the script. If instead the data
|
means that they are hard-wired in the script. If instead the data
|
comes out of a configuration file and hence may be invalid, the
|
comes out of a configuration file and hence may be invalid, the
|
I/O auxiliary provides a parsing utility. Typical usage would be:
|
I/O auxiliary provides a parsing utility. Typical usage would be:
|
</P
|
</P
|
><TABLE
|
><TABLE
|
BORDER="5"
|
BORDER="5"
|
BGCOLOR="#E0E0F0"
|
BGCOLOR="#E0E0F0"
|
WIDTH="70%"
|
WIDTH="70%"
|
><TR
|
><TR
|
><TD
|
><TD
|
><PRE
|
><PRE
|
CLASS="PROGRAMLISTING"
|
CLASS="PROGRAMLISTING"
|
> array set parsed_options [list]
|
> array set parsed_options [list]
|
set message ""
|
set message ""
|
if { ![synth::filter_parse_options $console_appearance parsed_options message] } {
|
if { ![synth::filter_parse_options $console_appearance parsed_options message] } {
|
synth::report_error \
|
synth::report_error \
|
"Invalid entry in target definition file $synth::target_definition\
|
"Invalid entry in target definition file $synth::target_definition\
|
\n synth_device \"console\", entry \"appearance\"\n$message"
|
\n synth_device \"console\", entry \"appearance\"\n$message"
|
} else {
|
} else {
|
synth::filter_add_parsed "console" parsed_options
|
synth::filter_add_parsed "console" parsed_options
|
}</PRE
|
}</PRE
|
></TD
|
></TD
|
></TR
|
></TR
|
></TABLE
|
></TABLE
|
><P
|
><P
|
>On success <TT
|
>On success <TT
|
CLASS="VARNAME"
|
CLASS="VARNAME"
|
>parsed_options</TT
|
>parsed_options</TT
|
> will be updated with an
|
> will be updated with an
|
internal representation of the desired appearance, which can then be
|
internal representation of the desired appearance, which can then be
|
used in a call to <B
|
used in a call to <B
|
CLASS="COMMAND"
|
CLASS="COMMAND"
|
>synth::filter_add_parsed</B
|
>synth::filter_add_parsed</B
|
>. On
|
>. On
|
failure <TT
|
failure <TT
|
CLASS="VARNAME"
|
CLASS="VARNAME"
|
>message</TT
|
>message</TT
|
> will be updated with details of the
|
> will be updated with details of the
|
parsing error that occurred.
|
parsing error that occurred.
|
</P
|
</P
|
></DIV
|
></DIV
|
><DIV
|
><DIV
|
CLASS="REFSECT1"
|
CLASS="REFSECT1"
|
><A
|
><A
|
NAME="SYNTH-NEW-HOST-GUI"
|
NAME="SYNTH-NEW-HOST-GUI"
|
></A
|
></A
|
><H2
|
><H2
|
>The Graphical Interface</H2
|
>The Graphical Interface</H2
|
><P
|
><P
|
>When the I/O auxiliary is running in graphical mode, many scripts will
|
>When the I/O auxiliary is running in graphical mode, many scripts will
|
want to update the user interface in some way. This may be as simple
|
want to update the user interface in some way. This may be as simple
|
as adding another entry to the help menu for the device, or adding a
|
as adding another entry to the help menu for the device, or adding a
|
new button to the toolbar. It may also involve adding new subwindows,
|
new button to the toolbar. It may also involve adding new subwindows,
|
or even creating entire new toplevel windows. These may be simple
|
or even creating entire new toplevel windows. These may be simple
|
monitor windows, displaying additional information about what is going
|
monitor windows, displaying additional information about what is going
|
on in the system in a graphical format. Alternatively they may emulate
|
on in the system in a graphical format. Alternatively they may emulate
|
actual I/O operations, for example button widgets could be used to
|
actual I/O operations, for example button widgets could be used to
|
emulate real physical buttons.
|
emulate real physical buttons.
|
</P
|
</P
|
><P
|
><P
|
>The I/O auxiliary does not provide many procedures related to the
|
>The I/O auxiliary does not provide many procedures related to the
|
graphical interface. Instead it is expected that scripts will just
|
graphical interface. Instead it is expected that scripts will just
|
update the widget hierarchy directly.
|
update the widget hierarchy directly.
|
</P
|
</P
|
><DIV
|
><DIV
|
CLASS="INFORMALFIGURE"
|
CLASS="INFORMALFIGURE"
|
><A
|
><A
|
NAME="AEN1018"><P
|
NAME="AEN1018"><P
|
></P
|
></P
|
><DIV
|
><DIV
|
CLASS="MEDIAOBJECT"
|
CLASS="MEDIAOBJECT"
|
><P
|
><P
|
><IMG
|
><IMG
|
SRC="layout.gif"
|
SRC="layout.gif"
|
ALIGN="CENTER"></P
|
ALIGN="CENTER"></P
|
></DIV
|
></DIV
|
><P
|
><P
|
></P
|
></P
|
></DIV
|
></DIV
|
><P
|
><P
|
>So adding a new item to the <SPAN
|
>So adding a new item to the <SPAN
|
CLASS="GUIMENU"
|
CLASS="GUIMENU"
|
>Help</SPAN
|
>Help</SPAN
|
> menu involves a
|
> menu involves a
|
<B
|
<B
|
CLASS="COMMAND"
|
CLASS="COMMAND"
|
>.menubar.help add</B
|
>.menubar.help add</B
|
> operation with suitable
|
> operation with suitable
|
arguments. Adding a new button to the toolbar involves creating a
|
arguments. Adding a new button to the toolbar involves creating a
|
child window in <TT
|
child window in <TT
|
CLASS="VARNAME"
|
CLASS="VARNAME"
|
>.toolbar</TT
|
>.toolbar</TT
|
> and packing it
|
> and packing it
|
appropriately. Scripts can create their own subwindows and then pack
|
appropriately. Scripts can create their own subwindows and then pack
|
it into one of <TT
|
it into one of <TT
|
CLASS="VARNAME"
|
CLASS="VARNAME"
|
>.main.nw</TT
|
>.main.nw</TT
|
>,
|
>,
|
<TT
|
<TT
|
CLASS="VARNAME"
|
CLASS="VARNAME"
|
>.main.n</TT
|
>.main.n</TT
|
>, <TT
|
>, <TT
|
CLASS="VARNAME"
|
CLASS="VARNAME"
|
>.main.ne</TT
|
>.main.ne</TT
|
>,
|
>,
|
<TT
|
<TT
|
CLASS="VARNAME"
|
CLASS="VARNAME"
|
>.main.w</TT
|
>.main.w</TT
|
>, <TT
|
>, <TT
|
CLASS="VARNAME"
|
CLASS="VARNAME"
|
>.main.e</TT
|
>.main.e</TT
|
>,
|
>,
|
<TT
|
<TT
|
CLASS="VARNAME"
|
CLASS="VARNAME"
|
>.main.sw</TT
|
>.main.sw</TT
|
>, <TT
|
>, <TT
|
CLASS="VARNAME"
|
CLASS="VARNAME"
|
>.main.s</TT
|
>.main.s</TT
|
> or
|
> or
|
<TT
|
<TT
|
CLASS="VARNAME"
|
CLASS="VARNAME"
|
>.main.se</TT
|
>.main.se</TT
|
>. Normally the user should be allowed to
|
>. Normally the user should be allowed to
|
<A
|
<A
|
HREF="synth-gui.html#SYNTH-GUI-LAYOUT"
|
HREF="synth-gui.html#SYNTH-GUI-LAYOUT"
|
>control</A
|
>control</A
|
> this via the target
|
> this via the target
|
definition file. The central window <TT
|
definition file. The central window <TT
|
CLASS="VARNAME"
|
CLASS="VARNAME"
|
>.main.centre</TT
|
>.main.centre</TT
|
>
|
>
|
should normally be left alone by other scripts since it gets used for
|
should normally be left alone by other scripts since it gets used for
|
text output.
|
text output.
|
</P
|
</P
|
><P
|
><P
|
>The following graphics-related utilities may be found useful:
|
>The following graphics-related utilities may be found useful:
|
</P
|
</P
|
><TABLE
|
><TABLE
|
BORDER="5"
|
BORDER="5"
|
BGCOLOR="#E0E0F0"
|
BGCOLOR="#E0E0F0"
|
WIDTH="70%"
|
WIDTH="70%"
|
><TR
|
><TR
|
><TD
|
><TD
|
><PRE
|
><PRE
|
CLASS="PROGRAMLISTING"
|
CLASS="PROGRAMLISTING"
|
>synth::load_image <image name> <filename>
|
>synth::load_image <image name> <filename>
|
synth::register_ballon_help <widget> <message>
|
synth::register_ballon_help <widget> <message>
|
synth::handle_help <URL></PRE
|
synth::handle_help <URL></PRE
|
></TD
|
></TD
|
></TR
|
></TR
|
></TABLE
|
></TABLE
|
><P
|
><P
|
><B
|
><B
|
CLASS="COMMAND"
|
CLASS="COMMAND"
|
>synth::load_image</B
|
>synth::load_image</B
|
> can be used to add a new image to
|
> can be used to add a new image to
|
the current interpreter. If the specified file has a
|
the current interpreter. If the specified file has a
|
<TT
|
<TT
|
CLASS="FILENAME"
|
CLASS="FILENAME"
|
>.xbm</TT
|
>.xbm</TT
|
> extension then the image will be a
|
> extension then the image will be a
|
monochrome bitmap, otherwise it will be a colour image of some sort.
|
monochrome bitmap, otherwise it will be a colour image of some sort.
|
A boolean will be returned to indicate success or failure, and
|
A boolean will be returned to indicate success or failure, and
|
suitable diagnostics will be generated if necessary.
|
suitable diagnostics will be generated if necessary.
|
</P
|
</P
|
><P
|
><P
|
><B
|
><B
|
CLASS="COMMAND"
|
CLASS="COMMAND"
|
>synth::register_balloon_help</B
|
>synth::register_balloon_help</B
|
> provides balloon help
|
> provides balloon help
|
for a specific widget, usually a button on the toolbar.
|
for a specific widget, usually a button on the toolbar.
|
</P
|
</P
|
><P
|
><P
|
><B
|
><B
|
CLASS="COMMAND"
|
CLASS="COMMAND"
|
>synth::handle_help</B
|
>synth::handle_help</B
|
> is a utility routine that can be
|
> is a utility routine that can be
|
installed as the command for displaying online help, for example:
|
installed as the command for displaying online help, for example:
|
</P
|
</P
|
><TABLE
|
><TABLE
|
BORDER="5"
|
BORDER="5"
|
BGCOLOR="#E0E0F0"
|
BGCOLOR="#E0E0F0"
|
WIDTH="70%"
|
WIDTH="70%"
|
><TR
|
><TR
|
><TD
|
><TD
|
><PRE
|
><PRE
|
CLASS="PROGRAMLISTING"
|
CLASS="PROGRAMLISTING"
|
> .menubar.help add command -label "my device" -command \
|
> .menubar.help add command -label "my device" -command \
|
[list synth::handle_help "file://$path"]</PRE
|
[list synth::handle_help "file://$path"]</PRE
|
></TD
|
></TD
|
></TR
|
></TR
|
></TABLE
|
></TABLE
|
></DIV
|
></DIV
|
><DIV
|
><DIV
|
CLASS="NAVFOOTER"
|
CLASS="NAVFOOTER"
|
><HR
|
><HR
|
ALIGN="LEFT"
|
ALIGN="LEFT"
|
WIDTH="100%"><TABLE
|
WIDTH="100%"><TABLE
|
SUMMARY="Footer navigation table"
|
SUMMARY="Footer navigation table"
|
WIDTH="100%"
|
WIDTH="100%"
|
BORDER="0"
|
BORDER="0"
|
CELLPADDING="0"
|
CELLPADDING="0"
|
CELLSPACING="0"
|
CELLSPACING="0"
|
><TR
|
><TR
|
><TD
|
><TD
|
WIDTH="33%"
|
WIDTH="33%"
|
ALIGN="left"
|
ALIGN="left"
|
VALIGN="top"
|
VALIGN="top"
|
><A
|
><A
|
HREF="synth-new-target.html"
|
HREF="synth-new-target.html"
|
ACCESSKEY="P"
|
ACCESSKEY="P"
|
>Prev</A
|
>Prev</A
|
></TD
|
></TD
|
><TD
|
><TD
|
WIDTH="34%"
|
WIDTH="34%"
|
ALIGN="center"
|
ALIGN="center"
|
VALIGN="top"
|
VALIGN="top"
|
><A
|
><A
|
HREF="hal-synth-arch.html"
|
HREF="hal-synth-arch.html"
|
ACCESSKEY="H"
|
ACCESSKEY="H"
|
>Home</A
|
>Home</A
|
></TD
|
></TD
|
><TD
|
><TD
|
WIDTH="33%"
|
WIDTH="33%"
|
ALIGN="right"
|
ALIGN="right"
|
VALIGN="top"
|
VALIGN="top"
|
><A
|
><A
|
HREF="synth-porting.html"
|
HREF="synth-porting.html"
|
ACCESSKEY="N"
|
ACCESSKEY="N"
|
>Next</A
|
>Next</A
|
></TD
|
></TD
|
></TR
|
></TR
|
><TR
|
><TR
|
><TD
|
><TD
|
WIDTH="33%"
|
WIDTH="33%"
|
ALIGN="left"
|
ALIGN="left"
|
VALIGN="top"
|
VALIGN="top"
|
>Writing New Devices - target</TD
|
>Writing New Devices - target</TD
|
><TD
|
><TD
|
WIDTH="34%"
|
WIDTH="34%"
|
ALIGN="center"
|
ALIGN="center"
|
VALIGN="top"
|
VALIGN="top"
|
> </TD
|
> </TD
|
><TD
|
><TD
|
WIDTH="33%"
|
WIDTH="33%"
|
ALIGN="right"
|
ALIGN="right"
|
VALIGN="top"
|
VALIGN="top"
|
>Porting</TD
|
>Porting</TD
|
></TR
|
></TR
|
></TABLE
|
></TABLE
|
></DIV
|
></DIV
|
></BODY
|
></BODY
|
></HTML
|
></HTML
|
|
|