Mercurial > ecos
changeset 332:7c1c8dc43ba1
Now witness the firepower of this fully armed and operational
synthetic target.
line wrap: on
line diff
new file mode 100644 --- /dev/null +++ b/packages/devs/eth/synth/ecosynth/current/ChangeLog @@ -0,0 +1,35 @@ +2002-08-07 Bart Veer <bartv@ecoscentric.com> + + * synthetic target ethernet driver package created + +//=========================================================================== +//####ECOSGPLCOPYRIGHTBEGIN#### +// ------------------------------------------- +// This file is part of eCos, the Embedded Configurable Operating System. +// Copyright (C) 2002 Bart Veer +// +// eCos is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 or (at your option) any later version. +// +// eCos is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License along +// with eCos; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. +// +// As a special exception, if other files instantiate templates or use macros +// or inline functions from this file, or you compile this file and link it +// with other works to produce a work based on this file, this file does not +// by itself cause the resulting work to be covered by the GNU General Public +// License. However the source code for this file must still be made available +// in accordance with section (3) of the GNU General Public License. +// +// This exception does not invalidate any other reasons why a work based on +// this file might be covered by the GNU General Public License. +// ------------------------------------------- +//####ECOSGPLCOPYRIGHTEND#### +//===========================================================================
new file mode 100644 --- /dev/null +++ b/packages/devs/eth/synth/ecosynth/current/cdl/syntheth.cdl @@ -0,0 +1,143 @@ +# ==================================================================== +# +# syntheth.cdl +# +# Synthetic target ethernet package. +# +# ==================================================================== +#####ECOSGPLCOPYRIGHTBEGIN#### +## ------------------------------------------- +## This file is part of eCos, the Embedded Configurable Operating System. +## Copyright (C) 2002 Bart Veer +## +## eCos is free software; you can redistribute it and/or modify it under +## the terms of the GNU General Public License as published by the Free +## Software Foundation; either version 2 or (at your option) any later version. +## +## eCos is distributed in the hope that it will be useful, but WITHOUT ANY +## WARRANTY; without even the implied warranty of MERCHANTABILITY or +## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +## for more details. +## +## You should have received a copy of the GNU General Public License along +## with eCos; if not, write to the Free Software Foundation, Inc., +## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. +## +## As a special exception, if other files instantiate templates or use macros +## or inline functions from this file, or you compile this file and link it +## with other works to produce a work based on this file, this file does not +## by itself cause the resulting work to be covered by the GNU General Public +## License. However the source code for this file must still be made available +## in accordance with section (3) of the GNU General Public License. +## +## This exception does not invalidate any other reasons why a work based on +## this file might be covered by the GNU General Public License. +## +## Alternative licenses for eCos may be arranged by contacting the +## copyright holder(s). +## ------------------------------------------- +#####ECOSGPLCOPYRIGHTEND#### +# ==================================================================== +######DESCRIPTIONBEGIN#### +# +# Author(s): bartv +# Original data: bartv +# Contributors: +# Date: 2002-08-07 +# +#####DESCRIPTIONEND#### +# ==================================================================== + +cdl_package CYGPKG_DEVS_ETH_ECOSYNTH { + display "Synthetic target ethernet driver" + description " + The ethernet driver for the eCos synthetic target allows applications + and other packages such as a TCP/IP stack to perform ethernet I/O. + This can involve either an unused ethernet device, or an emulated + ethernet device as provided by the Linux kernel's tunnel/tap + support. The eCos code interacts with a suitable Linux application + through the I/O auxiliary. Up to four ethernet devices are + supported, and the host-side target definition file controls how + each device will perform its I/O." + + parent CYGPKG_IO_ETH_DRIVERS + active_if CYGPKG_IO_ETH_DRIVERS + active_if CYGPKG_HAL_SYNTH + + cdl_option CYGVAR_DEVS_ETH_ECOSYNTH_ETH0 { + display "Provide eth0 device" + description " + The synthetic target can provide up to four ethernet devices, + eth0 to eth3. By default eth0 is enabled when a TCP/IP stack + is part of the configuration, disabled otherwise." + default_value CYGPKG_NET_STACK + implements CYGHWR_NET_DRIVERS + implements CYGHWR_NET_DRIVER_ETH0 + } + + cdl_option CYGVAR_DEVS_ETH_ECOSYNTH_ETH1 { + display "Provide eth1 device" + description " + The synthetic target can provide up to four ethernet devices, + eth0 to eth3. By default eth1 is always disabled, but can + be enabled if the eCos application needs more than one ethernet + device." + default_value 0 + implements CYGHWR_NET_DRIVERS + implements CYGHWR_NET_DRIVER_ETH1 + } + + cdl_option CYGVAR_DEVS_ETH_ECOSYNTH_ETH2 { + display "Provide eth2 device" + description " + The synthetic target can provide up to four ethernet devices, + eth0 to eth3. By default eth2 is always disabled, but can + be enabled if the eCos application needs more than two ethernet + devices." + default_value 0 + implements CYGHWR_NET_DRIVERS + } + + cdl_option CYGVAR_DEVS_ETH_ECOSYNTH_ETH3 { + display "Provide eth3 device" + description " + The synthetic target can provide up to four ethernet devices, + eth0 to eth3. By default eth3 is always disabled, but can + be enabled if the eCos application needs more than three ethernet + devices." + default_value 0 + implements CYGHWR_NET_DRIVERS + } + + cdl_component CYGPKG_DEVS_ETH_ECOSYNTH_OPTIONS { + display "Build options" + active_if { CYGVAR_DEVS_ETH_ECOSYNTH_ETH0 || CYGVAR_DEVS_ETH_ECOSYNTH_ETH1 || CYGVAR_DEVS_ETH_ECOSYNTH_ETH2 || CYGVAR_DEVS_ETH_ECOSYNTH_ETH3 } + flavor none + compile -library=libextras.a syntheth.c + description " + Package-specific build options including control over compiler + flags used only in building this package." + + cdl_option CYGPKG_DEVS_ETH_ECOSYNTH_CFLAGS_ADD { + display "Additional compiler flags" + flavor data + no_define + default_value { "" } + description " + This option modifies the set of compiler flags for + building this package. These flags are used in addition + to the set of global flags." + } + cdl_option CYGPKG_DEVS_ETH_ECOSYNTH_CFLAGS_REMOVE { + display "Suppressed compiler flags" + flavor data + no_define + default_value { "" } + description " + This option modifies the set of compiler flags for + building this package. These flags are removed from + the set of global flags if present." + } + } +} +
new file mode 100644 --- /dev/null +++ b/packages/devs/eth/synth/ecosynth/current/doc/devs-eth-synth-ecosynth.html @@ -0,0 +1,912 @@ +<!-- Copyright (C) 2002 Red Hat, Inc. --> +<!-- This material may be distributed only subject to the terms --> +<!-- and conditions set forth in the Open Publication License, v1.0 --> +<!-- or later (the latest version is presently available at --> +<!-- http://www.opencontent.org/openpub/). --> +<!-- Distribution of substantively modified versions of this --> +<!-- document is prohibited without the explicit permission of the --> +<!-- copyright holder. --> +<!-- Distribution of the work or derivative of the work in any --> +<!-- standard (paper) book form is prohibited unless prior --> +<!-- permission is obtained from the copyright holder. --> +<HTML +><HEAD +><TITLE +>Synthetic Target Ethernet Driver</TITLE +><meta name="MSSmartTagsPreventParsing" content="TRUE"> +<META +NAME="GENERATOR" +CONTENT="Modular DocBook HTML Stylesheet Version 1.76b+ +"></HEAD +><BODY +CLASS="REFENTRY" +BGCOLOR="#FFFFFF" +TEXT="#000000" +LINK="#0000FF" +VLINK="#840084" +ALINK="#0000FF" +><H1 +><A +NAME="DEVS-ETH-SYNTH-ECOSYNTH">Synthetic Target Ethernet Driver</H1 +><DIV +CLASS="REFNAMEDIV" +><A +NAME="AEN4" +></A +><H2 +>Name</H2 +>Synthetic Target Ethernet Support -- Allow synthetic target applications to perform ethernet I/O</DIV +><DIV +CLASS="REFSECT1" +><A +NAME="AEN7" +></A +><H2 +>Overview</H2 +><P +>The synthetic target ethernet package can provide up to four network +devices, <TT +CLASS="VARNAME" +>eth0</TT +> to <TT +CLASS="VARNAME" +>eth3</TT +>. These can +be used directly by the eCos application or, more commonly, by a +TCP/IP stack that is linked with the eCos application. Each eCos +device can be mapped on to a real Linux network device. For example, +if the Linux PC has two ethernet cards and <TT +CLASS="VARNAME" +>eth1</TT +> is +not currently being used by Linux itself, then one of the eCos devices +can be mapped on to this Linux device. Alternatively, it is possible +to map some or all of the eCos devices on to the ethertap support +provided by the Linux kernel. + </P +><P +>The ethernet package depends on the I/O auxiliary provided by the +synthetic target architectural HAL package. During initialization the +eCos application will attempt to instantiate the desired devices, by +sending a request to the auxiliary. This will load a Tcl script +<TT +CLASS="FILENAME" +>ethernet.tcl</TT +> that is responsible for handling the +instantiation request and subsequent I/O operations, for example +transmitting an ethernet packet. However, some of the low-level I/O +operations cannot conveniently be done by a Tcl script so +<TT +CLASS="FILENAME" +>ethernet.tcl</TT +> will actually run a separate program +<B +CLASS="COMMAND" +>rawether</B +> to interact with the Linux network device. + </P +><DIV +CLASS="INFORMALFIGURE" +><A +NAME="AEN17"><P +></P +><DIV +CLASS="MEDIAOBJECT" +><P +><IMG +SRC="overview.gif" +ALIGN="CENTER"></P +></DIV +><P +></P +></DIV +><P +>On the target-side there are configuration options to control which +network devices should be present. For many applications a single +device will be sufficient, but if the final eCos application is +something like a network bridge then the package can support multiple +devices. On the host-side each eCos network device needs to be mapped +on to a Linux one, either a real ethernet device or an ethertap +device. This is handled by an entry in the target definition file: + </P +><TABLE +BORDER="5" +BGCOLOR="#E0E0F0" +WIDTH="70%" +><TR +><TD +><PRE +CLASS="PROGRAMLISTING" +>synth_device ethernet { + eth0 real eth1 + eth1 ethertap tap3 00:01:02:03:FE:05 + … +}</PRE +></TD +></TR +></TABLE +><P +>The ethernet package also comes with support for packet logging, +and provides various facilities for use by user Tcl scripts. + </P +></DIV +><DIV +CLASS="REFSECT1" +><A +NAME="DEVS-ETH-ECOSYNTH-INSTALL" +></A +><H2 +>Installation</H2 +><P +>Before a synthetic target eCos application can access ethernet devices +it is necessary to build and install host-side support. The relevant +code resides in the <TT +CLASS="FILENAME" +>host</TT +> +subdirectory of the synthetic target ethernet package, and building it +involves the standard <B +CLASS="COMMAND" +>configure</B +>, +<B +CLASS="COMMAND" +>make</B +> and <B +CLASS="COMMAND" +>make install</B +> steps. +The build involves a new executable <B +CLASS="COMMAND" +>rawether</B +> which +must be able to access a raw Linux network device. This is achieved by +installing it suid root, so the <B +CLASS="COMMAND" +>make install</B +> step +has to be run with superuser privileges. + </P +><DIV +CLASS="CAUTION" +><P +></P +><TABLE +CLASS="CAUTION" +BORDER="1" +WIDTH="100%" +><TR +><TD +ALIGN="CENTER" +><B +>Caution</B +></TD +></TR +><TR +><TD +ALIGN="LEFT" +><P +>Installing <B +CLASS="COMMAND" +>rawether</B +> suid root introduces a +potential security problem. Although normally +<B +CLASS="COMMAND" +>rawether</B +> is executed only by the I/O auxiliary, +theoretically it can be run by any program. Effectively it gives any +user the ability to monitor all ethernet traffic and to inject +arbitrary packets into the network. Also, as with any suid root +programs there may be as yet undiscovered exploits. Users and system +administrators should consider the risks before running <B +CLASS="COMMAND" +>make +install</B +>. + </P +></TD +></TR +></TABLE +></DIV +><P +>There are two main ways of building the host-side software. It is +possible to build both the generic host-side software and all +package-specific host-side software, including the ethernet support, +in a single build tree. This involves using the +<B +CLASS="COMMAND" +>configure</B +> script at the toplevel of the eCos +repository. For more information on this, see the +<TT +CLASS="FILENAME" +>README.host</TT +> file at the top of the repository. +Note that if you have an existing build tree which does not include +the synthetic target ethernet support then it will be necessary to +rerun the toplevel configure script: the search for appropriate +packages happens at configure time. + </P +><P +>The alternative is to build just the host-side for this package. +This requires a separate build directory, building directly in the +source tree is disallowed. The <B +CLASS="COMMAND" +>configure</B +> options +are much the same as for a build from the toplevel, and the +<TT +CLASS="FILENAME" +>README.host</TT +> file can be consulted for more +details. It is essential that the ethernet support be configured with +the same <TT +CLASS="OPTION" +>--prefix</TT +> option as other eCos host-side +software, especially the I/O auxiliary provided by the architectural +synthetic target HAL package, otherwise the I/O auxiliary will be +unable to locate the ethernet support. + </P +></DIV +><DIV +CLASS="REFSECT1" +><A +NAME="DEVS-ETH-ECOSYNTH-OPTIONS" +></A +><H2 +>Target-side Configuration Options</H2 +><P +>The target-side code can be configured to support up to four ethernet +devices, <TT +CLASS="VARNAME" +>eth0</TT +> to <TT +CLASS="VARNAME" +>eth3</TT +>. By +default <TT +CLASS="VARNAME" +>eth0</TT +> is enabled if the configuration +includes a TCP/IP stack, otherwise it is disabled. The other three +devices are always disabled by default. If any of the devices are +enabled then there will also be the usual configuration options +related to building this package. Other options related to network +devices, for example whether or not to use DHCP, are provided by +the generic network device package. + </P +></DIV +><DIV +CLASS="REFSECT1" +><A +NAME="DEVS-ETH-ECOSYNTH-REAL" +></A +><H2 +>Real Ethernet</H2 +><P +>One obvious way of providing a synthetic target eCos application with +ethernet I/O is to use a real ethernet device in the PC: transmitted +packets go out on a real network, and packets on the network addressed +to the right MAC address are passed on to eCos. This way synthetic +target networking behaves just like networking on a real target with +ethernet hardware. For example, if there is a DHCP server anywhere on +the network then eCos will be able to contact it during networking +startup and get hold of IP address information. + </P +><P +>Configuring the ethernet support to use a real ethernet device +requires a simple entry in the target definition file: + </P +><TABLE +BORDER="5" +BGCOLOR="#E0E0F0" +WIDTH="70%" +><TR +><TD +><PRE +CLASS="PROGRAMLISTING" +>synth_device ethernet { + <eCos device> real <linux device> + … +}</PRE +></TD +></TR +></TABLE +><P +>For example, to map the eCos network device <TT +CLASS="VARNAME" +>eth0</TT +> to +the Linux device <TT +CLASS="VARNAME" +>eth1</TT +>: + </P +><TABLE +BORDER="5" +BGCOLOR="#E0E0F0" +WIDTH="70%" +><TR +><TD +><PRE +CLASS="PROGRAMLISTING" +>synth_device ethernet { + eth0 real eth1 + … +}</PRE +></TD +></TR +></TABLE +><P +>It is not possible for an ethernet device to be shared by both the +eCos TCP/IP stack and the Linux one: there would be no simple way to +work out which stack incoming packets are intended for. In theory +it might be possible to do some demultiplexing using distinct IP +addresses, but it would be impossible to support some functionality +such as DHCP. Therefore the <B +CLASS="COMMAND" +>rawether</B +> program will +refuse to access any ethernet device already in use. On a typical +Linux system <TT +CLASS="VARNAME" +>eth0</TT +> will be used for Linux +networking, and the PC will have to be equipped with additional +ethernet devices for use by eCos. + </P +><P +>The <B +CLASS="COMMAND" +>rawether</B +> program will access the hardware via +the appropriate Linux device driver, so it is important that the +system is set up such that the relevant module will be automatically +loaded or is already loaded. The details of this will depend on the +installed distribution and version, but typically it will involve an +entry in <TT +CLASS="FILENAME" +>/etc/modules.conf</TT +>. + </P +></DIV +><DIV +CLASS="REFSECT1" +><A +NAME="DEVS-ETH-ECOSYNTH-ETHERTAP" +></A +><H2 +>Ethertap</H2 +><P +>The Linux kernel's ethertap facility provides a virtual network +interface. A Linux application, for example the +<B +CLASS="COMMAND" +>rawether</B +> program, can open a special character +device <TT +CLASS="FILENAME" +>/dev/net/tun</TT +>, perform various +<TT +CLASS="FUNCTION" +>ioctl</TT +> calls, and then <TT +CLASS="FILENAME" +>write</TT +> +and <TT +CLASS="FILENAME" +>read</TT +> ethernet packets. When the device is +opened the Linux kernel automatically creates a new network interface, +for example <TT +CLASS="VARNAME" +>tap0</TT +>. The Linux TCP/IP stack can be +made to use this network interface like any other interface, receiving +and transmitting ethernet packets. The net effect is a virtual network +connecting just the Linux and eCos TCP/IP stacks, with no other nodes +attached. By default all traffic remains inside this virtual network +and is never forwarded to a real network. + </P +><P +>Support for the ethertap facility may or may not be provided +automatically, depending on your Linux distribution and version. If +your system does not have a device <TT +CLASS="FILENAME" +>/dev/net/tun</TT +> +or a module <TT +CLASS="FILENAME" +>tun.o</TT +> then the appropriate kernel +documentation should be consulted, for example +<TT +CLASS="FILENAME" +>/usr/src/linux-2.4/Documentation/networking/tuntap.txt</TT +>. + </P +><P +>The target definition file is used to map eCos network devices on to +ethertap devices. The simplest usage is: + </P +><TABLE +BORDER="5" +BGCOLOR="#E0E0F0" +WIDTH="70%" +><TR +><TD +><PRE +CLASS="PROGRAMLISTING" +>synth_device ethernet { + eth0 ethertap + … +}</PRE +></TD +></TR +></TABLE +><P +>The Linux kernel will automatically allocate the next available tap +network interface. Usually this will be <TT +CLASS="VARNAME" +>tap0</TT +> but if +other software is using the ethertap facility, for example to +implement a VPN, then a different number may be allocated. Usually it +will be better to specify the particular tap device that should be +used for each eCos device, for example: + </P +><TABLE +BORDER="5" +BGCOLOR="#E0E0F0" +WIDTH="70%" +><TR +><TD +><PRE +CLASS="PROGRAMLISTING" +>synth_device ethernet { + eth0 ethertap tap3 + eth1 ethertap tap4 + … +}</PRE +></TD +></TR +></TABLE +><P +>The user now knows exactly which eCos device is mapped onto which +Linux device, avoiding much potential confusion. Because the virtual +devices are emulated ethernet devices, they require MAC addresses. +There is no physical hardware to provide these addresses, so normally +MAC addresses will be invented. That means that each time the eCos +application is run it will have different MAC addresses, which makes +it more difficult to compare the results of different runs. To get +more deterministic behaviour it is possible to specify the MAC +addresses in the target definition file: + </P +><TABLE +BORDER="5" +BGCOLOR="#E0E0F0" +WIDTH="70%" +><TR +><TD +><PRE +CLASS="PROGRAMLISTING" +>synth_device ethernet { + eth0 ethertap tap3 00:01:02:03:FE:05 + eth1 ethertap tap4 00:01:02:03:FE:06 + … +}</PRE +></TD +></TR +></TABLE +><P +>During the initialization phase the eCos application will instantiate +the various network devices. This will cause the I/O auxiliary to load +the <TT +CLASS="FILENAME" +>ethernet.tcl</TT +> script and spawn +<B +CLASS="COMMAND" +>rawether</B +> processes, which in turn will +<TT +CLASS="FUNCTION" +>open</TT +> <TT +CLASS="FILENAME" +>/dev/net/tun</TT +> and +perform the appropriate <TT +CLASS="FILENAME" +>ioctl</TT +> calls. On the Linux +side there will now be new network interfaces such as +<TT +CLASS="VARNAME" +>tap3</TT +>, and these can be configured like any other +network interface using commands such as <B +CLASS="COMMAND" +>ifconfig</B +>. +In addition, if the Linux system is set up with hotplug support then +it may be possible to arrange for the network interface to become +active automatically. On a Red Hat Linux system this would require +files such as +<TT +CLASS="FILENAME" +>/etc/sysconfig/network-scripts/ifcfg-tap3</TT +>, +containing data like: + </P +><TABLE +BORDER="5" +BGCOLOR="#E0E0F0" +WIDTH="70%" +><TR +><TD +><PRE +CLASS="PROGRAMLISTING" +>DEVICE="tap3" +BOOTPROTO="none" +BROADCAST=10.2.2.255 +IPADDR="10.2.2.1" +NETMASK="255.255.255.0" +NETWORK=10.2.2.0 +ONBOOT="no"</PRE +></TD +></TR +></TABLE +><P +>This gives the Linux interface the address <TT +CLASS="LITERAL" +>10.2.2.1</TT +> +on the network <TT +CLASS="LITERAL" +>10.2.2.0</TT +>. The eCos network device +should be configured with a compatible address. One way of doing this +would be to enable <TT +CLASS="VARNAME" +>CYGHWR_NET_DRIVER_ETH0_ADDRS</TT +>, +set <TT +CLASS="VARNAME" +>CYGHWR_NET_DRIVER_ETH0_ADDRS_IP</TT +> to +<TT +CLASS="LITERAL" +>10.2.2.2</TT +>, and similarly update the +<TT +CLASS="VARNAME" +>NETMASK</TT +>, <TT +CLASS="VARNAME" +>BROADCAST</TT +>, +<TT +CLASS="VARNAME" +>GATEWAY</TT +> and <TT +CLASS="VARNAME" +>SERVER</TT +> configuration +options. + </P +><P +>It should be noted that the ethertap facility provides a virtual +network, and any packets transmitted by the eCos application will +not appear on a real network. Therefore usually there will no +accessible DHCP server, and eCos cannot use DHCP or BOOTP to obtain IP +address information. Instead the eCos configuration should use manual +or static addresses. + </P +><P +>An alternative approach would be to set up the Linux box as a network +bridge, using commands like <B +CLASS="COMMAND" +>brctl</B +> to connect the +virtual network interface <TT +CLASS="VARNAME" +>tap3</TT +> to a physical +network interface such as <TT +CLASS="VARNAME" +>eth0</TT +>. Any packets sent by +the eCos application will get forwarded automatically to the real +network, and some packets on the real network will get forwarded over +the virtual network to the eCos application. Note that the eCos +application might also get some packets that were not intended for it, +but usually those will just be discarded by the eCos TCP/IP stack. The +exact details of setting up a network bridge are left as an exercise +to the reader. + </P +></DIV +><DIV +CLASS="REFSECT1" +><A +NAME="DEVS-ETH-ECOSYNTH-LOGGING" +></A +><H2 +>Packet Logging</H2 +><P +>The ethernet support comes with support for logging the various +packets that are transferred, including a simple protocol analyser. +This generates simple text output using the filter mechanisms provided +by the I/O auxiliary, so it is possible to control the appearance and +visibility of different types of output. For example the user might +want to see IPv4 headers and all ICMPv4 and ARP operations, but not +TCP headers or any of the packet data. + </P +><P +>The protocol analyser is not intended to be a fully functional +analyser with knowledge of many different TCP/IP protocols, advanced +search facilities, graphical traffic displays, and so on. +Functionality like that is already provided by other tools such as +<SPAN +CLASS="APPLICATION" +>ethereal</SPAN +> and +<SPAN +CLASS="APPLICATION" +>tcpdump</SPAN +>. Achieving similar levels of +functionality would require a lot of work, for very little gain. It is +still useful to have some protocol analysis functionality available +because the output will be interleaved with other output, for example +<TT +CLASS="FILENAME" +>printf</TT +> calls from the application. That may make +it easier to understand the sequence of events. + </P +><P +>One problem with logging ethernet traffic is that it can involve very +large amounts of data. If the application is expected to run for a +long time or is very I/O intensive then it is easy to end up with many +megabytes. When running in graphical mode all the logging data will be +held in memory, even data that is not currently visible. At some point +the system will begin to run low on memory and performance will +suffer. To avoid problems, the ethernet script maintains a flag that +controls whether or not packet logging is active. The default is to +run with logging disabled, but this can be changed in the target +definition file: + </P +><TABLE +BORDER="5" +BGCOLOR="#E0E0F0" +WIDTH="70%" +><TR +><TD +><PRE +CLASS="PROGRAMLISTING" +>synth_device ethernet { + … + logging 1 +}</PRE +></TD +></TR +></TABLE +><P +>The ethernet script will add a toolbar button that allows this flag to +be changed at run-time, allowing the user to capture traffic for +certain periods of time while the application continues running. + </P +><P +>The target definition file can contain the following entries for the +various packet logging filters: + </P +><TABLE +BORDER="5" +BGCOLOR="#E0E0F0" +WIDTH="70%" +><TR +><TD +><PRE +CLASS="PROGRAMLISTING" +>synth_device ethernet { + … + filter ether -hide 0 -background LightBlue -foreground "#000080" + filter arp -hide 0 -background LightBlue -foreground "#000050" + filter ipv4 -hide 0 -background LightBlue -foreground "#000040" + filter ipv6 -hide 1 -background LightBlue -foreground "#000040" + filter icmpv4 -hide 0 -background LightBlue -foreground "#000070" + filter icmpv6 -hide 1 -background LightBlue -foreground "#000070" + filter udp -hide 0 -background LightBlue -foreground "#000030" + filter tcp -hide 0 -background LightBlue -foreground "#000020" + filter hexdata -hide 1 -background LightBlue -foreground "#000080" + filter asciidata -hide 1 -background LightBlue -foreground "#000080" +}</PRE +></TD +></TR +></TABLE +><P +>All output will show the eCos network device, for example +<TT +CLASS="LITERAL" +>eth0</TT +>, and the direction relative to the eCos +application. Some of the filters will show packet headers, for example +<TT +CLASS="LITERAL" +>ether</TT +> gives details of the ethernet packet header +and <TT +CLASS="LITERAL" +>tcp</TT +> gives information about TCP headers such as +whether or not the SYN flag is set. The TCP and UDP filters will also +show source and destination addresses, using numerical addresses and +if possible host names. However, host names will only be shown if the +host appears in <TT +CLASS="FILENAME" +>/etc/hosts</TT +>: doing full DNS +lookups while the data is being captured would add significantly to +complexity and overhead. The <TT +CLASS="LITERAL" +>hexdata</TT +> and +<TT +CLASS="LITERAL" +>asciidata</TT +> filters show the remainder of the packets +after the ethernet, IP and TCP or UDP headers have been stripped. + </P +><P +>Some of the filters will provide raw dumps of some of the packet data. +Showing up to 1500 bytes of data for each packet would be expensive, +and often the most interesting information is near the start of the +packet. Therefore it is possible to set a limit on the number of bytes +that will be shown using the target definition file. The default limit +is 64 bytes. + </P +><TABLE +BORDER="5" +BGCOLOR="#E0E0F0" +WIDTH="70%" +><TR +><TD +><PRE +CLASS="PROGRAMLISTING" +>synth_device ethernet { + … + max_show 128 +}</PRE +></TD +></TR +></TABLE +></DIV +><DIV +CLASS="REFSECT1" +><A +NAME="DEVS-ETH-ECOSYNTH-GUI" +></A +><H2 +>User Interface Additions</H2 +><P +>When running in graphical mode the ethernet script extends the user +interface in two ways: a button is added to the toolbar so that users +can enable or disable packet logging; and an entry is added to the +<SPAN +CLASS="GUIMENU" +>Help</SPAN +> menu for the ethernet-specific documentation. + </P +></DIV +><DIV +CLASS="REFSECT1" +><A +NAME="DEVS-ETH-ECOSYNTH-ARGS" +></A +><H2 +>Command Line Arguments</H2 +><P +>The synthetic target ethernet support does not use any command line +arguments. All configuration is handled through the target definition +file. + </P +></DIV +><DIV +CLASS="REFSECT1" +><A +NAME="DEVS-ETH-ECOSYNTH-HOOKS" +></A +><H2 +>Hooks</H2 +><P +>The ethernet support defines two hooks that can be used by other +scripts, especially user scripts: <TT +CLASS="LITERAL" +>ethernet_tx</TT +> and +<TT +CLASS="LITERAL" +>ethernet_rx</TT +>. The tx hook is called whenever eCos +tries to transmit a packet. The rx hook is called whenever an incoming +packet is passed to the eCos application. Note that this may be a +little bit after the packet was actually received by the I/O auxiliary +since it can buffer some packets. Both hooks are called with two +arguments, the name of the network device and the packet being +transferred. Typical usage might look like: + </P +><TABLE +BORDER="5" +BGCOLOR="#E0E0F0" +WIDTH="70%" +><TR +><TD +><PRE +CLASS="PROGRAMLISTING" +> proc my_tx_hook { arg_list } { + set dev [lindex $arg_list 0] + incr ::my_ethernet_tx_packets($dev) + incr ::my_ethernet_tx_bytes($dev) [string length [lindex $arg_list 1]] + } + proc my_rx_hook { arg_list } { + set dev [lindex $arg_list 0] + incr ::my_ethernet_rx_packets($dev) + incr ::my_ethernet_rx_bytes($dev) [string length [lindex $arg_list 1]] + } + synth::hook_add "ethernet_tx" my_tx_hook + synth::hook_add "ethernet_rx" my_rx_hook</PRE +></TD +></TR +></TABLE +><P +>The global arrays <TT +CLASS="VARNAME" +>my_ethernet_tx_packets</TT +> etc. will +now be updated whenever there is ethernet traffic. Other code, +probably running at regular intervals by use of the Tcl +<B +CLASS="COMMAND" +>after</B +> procedure, can then use this information to +update a graphical monitor of some sort. + </P +></DIV +><DIV +CLASS="REFSECT1" +><A +NAME="DEVS-ETH-ECOSYNTH-TCL" +></A +><H2 +>Additional Tcl Procedures</H2 +><P +>The ethernet support provides one additional Tcl procedure that can be +used by other scripts; + </P +><TABLE +BORDER="5" +BGCOLOR="#E0E0F0" +WIDTH="70%" +><TR +><TD +><PRE +CLASS="PROGRAMLISTING" +>ethernet::devices_get_list </PRE +></TD +></TR +></TABLE +><P +>This procedure returns a list of the ethernet devices that have been +instantiated, for example <TT +CLASS="LITERAL" +>{eth0 eth1}</TT +>. + </P +></DIV +></BODY +></HTML +> \ No newline at end of file
new file mode 100644 --- /dev/null +++ b/packages/devs/eth/synth/ecosynth/current/doc/makefile @@ -0,0 +1,34 @@ +#============================================================================= +# +# makefile +# +# For building the synthetic target ethernet package documentation +# +#============================================================================= +#####COPYRIGHTBEGIN#### +# +# =============================================================== +# Copyright (C) 2002 Bart Veer +# This material may be distributed only subject to the terms +# and conditions set forth in the Open Publication License, v1.0 +# or later (the latest version is presently available at +# http://www.opencontent.org/openpub/) +# =============================================================== +# +#####COPYRIGHTEND#### +#============================================================================= +#####DESCRIPTIONBEGIN#### +# +# Author(s): bartv +# Date: 2002-08-20 +#####DESCRIPTIONEND#### +#============================================================================= + +TOPLEVEL := ../../../../../.. +MAIN_SGML := syntheth.sgml +MAIN_HTML := devs-eth-synth.html +MAIN_PDF := devs-eth-synth.pdf +OTHER_SGML := +PICTURES := + +include $(TOPLEVEL)/pkgconf/rules.doc
new file mode 100644 --- /dev/null +++ b/packages/devs/eth/synth/ecosynth/current/doc/overview.fig @@ -0,0 +1,54 @@ +#FIG 3.2 +Landscape +Center +Inches +Letter +100.00 +Single +-2 +1200 2 +2 1 1 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2 + 1500 300 1500 1500 +2 1 1 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2 + 2400 300 2400 1500 +2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5 + 300 300 3000 300 3000 1500 300 1500 300 300 +2 2 0 1 0 7 50 0 -1 4.000 0 0 -1 0 0 5 + 3600 300 6000 300 6000 1500 3600 1500 3600 300 +2 1 1 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2 + 4800 300 4800 1500 +2 1 0 1 0 7 50 0 -1 4.000 0 0 7 1 1 2 + 1 1 1.00 60.00 120.00 + 1 1 1.00 60.00 120.00 + 3000 900 3600 900 +2 1 0 1 0 7 50 0 -1 4.000 0 0 7 1 1 2 + 1 1 1.00 60.00 120.00 + 1 1 1.00 60.00 120.00 + 6000 1050 6600 1050 +2 1 0 1 0 7 50 0 -1 4.000 0 0 7 1 1 2 + 1 1 1.00 60.00 120.00 + 1 1 1.00 60.00 120.00 + 7500 450 8100 450 +2 1 0 1 0 7 50 0 -1 4.000 0 0 7 1 1 2 + 1 1 1.00 60.00 120.00 + 1 1 1.00 60.00 120.00 + 7500 1050 8100 1050 +2 2 0 1 0 7 50 0 -1 4.000 0 0 -1 0 0 5 + 6600 900 7500 900 7500 1200 6600 1200 6600 900 +2 2 0 1 0 7 50 0 -1 4.000 0 0 -1 0 0 5 + 6600 300 7500 300 7500 600 6600 600 6600 300 +2 1 0 1 0 7 50 0 -1 4.000 0 0 7 1 1 2 + 1 1 1.00 60.00 120.00 + 1 1 1.00 60.00 120.00 + 6000 450 6600 450 +4 0 0 50 0 0 12 0.0000 4 180 825 375 1200 application\001 +4 0 0 50 0 0 12 0.0000 4 135 390 600 900 eCos\001 +4 0 0 50 0 0 12 0.0000 4 135 540 1650 900 TCP/IP\001 +4 0 0 50 0 0 12 0.0000 4 135 330 2550 675 eth0\001 +4 0 0 50 0 0 12 0.0000 4 135 330 2550 1200 eth1\001 +4 0 0 50 0 0 12 0.0000 4 180 975 3675 900 I/O Auxiliary\001 +4 0 0 50 0 0 12 0.0000 4 135 870 4950 900 ethernet.tcl\001 +4 0 0 50 0 0 12 0.0000 4 135 330 8175 525 eth1\001 +4 0 0 50 0 0 12 0.0000 4 180 330 8175 1125 tap3\001 +4 0 0 50 0 0 12 0.0000 4 135 675 6675 1125 rawether\001 +4 0 0 50 0 0 12 0.0000 4 135 675 6675 525 rawether\001
new file mode 100644 index 0000000000000000000000000000000000000000..d404959783366417f0eafc180c0d2bae6d8182d3 GIT binary patch literal 1581 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
new file mode 100644 --- /dev/null +++ b/packages/devs/eth/synth/ecosynth/current/doc/syntheth.sgml @@ -0,0 +1,506 @@ +<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V3.1//EN"> + +<!-- {{{ Banner --> + +<!-- =============================================================== --> +<!-- --> +<!-- syntheth.sgml --> +<!-- --> +<!-- Synthetic target ethernet support package. --> +<!-- --> +<!-- =============================================================== --> +<!-- ####COPYRIGHTBEGIN#### --> +<!-- --> +<!-- =============================================================== --> +<!-- Copyright (C) 2002 Bart Veer --> +<!-- This material may be distributed only subject to the terms --> +<!-- and conditions set forth in the Open Publication License, v1.0 --> +<!-- or later (the latest version is presently available at --> +<!-- http://www.opencontent.org/openpub/) --> +<!-- =============================================================== --> +<!-- --> +<!-- ####COPYRIGHTEND#### --> +<!-- =============================================================== --> +<!-- #####DESCRIPTIONBEGIN#### --> +<!-- --> +<!-- Author(s): bartv --> +<!-- Contact(s): bartv --> +<!-- Date: 2002/08/20 --> +<!-- Version: 0.01 --> +<!-- --> +<!-- ####DESCRIPTIONEND#### --> +<!-- =============================================================== --> + +<!-- }}} --> + +<refentry id="devs-eth-synth-ecosynth"> + <refmeta> + <refentrytitle>Synthetic Target Ethernet Driver</refentrytitle> + </refmeta> + <refnamediv> + <refname>Synthetic Target Ethernet Support</refname> + <refpurpose>Allow synthetic target applications to perform ethernet I/O</refpurpose> + </refnamediv> + + <refsect1><title>Overview</title> + <para> +The synthetic target ethernet package can provide up to four network +devices, <varname>eth0</varname> to <varname>eth3</varname>. These can +be used directly by the eCos application or, more commonly, by a +TCP/IP stack that is linked with the eCos application. Each eCos +device can be mapped on to a real Linux network device. For example, +if the Linux PC has two ethernet cards and <varname>eth1</varname> is +not currently being used by Linux itself, then one of the eCos devices +can be mapped on to this Linux device. Alternatively, it is possible +to map some or all of the eCos devices on to the ethertap support +provided by the Linux kernel. + </para> + <para> +The ethernet package depends on the I/O auxiliary provided by the +synthetic target architectural HAL package. During initialization the +eCos application will attempt to instantiate the desired devices, by +sending a request to the auxiliary. This will load a Tcl script +<filename>ethernet.tcl</filename> that is responsible for handling the +instantiation request and subsequent I/O operations, for example +transmitting an ethernet packet. However, some of the low-level I/O +operations cannot conveniently be done by a Tcl script so +<filename>ethernet.tcl</filename> will actually run a separate program +<command>rawether</command> to interact with the Linux network device. + </para> + <informalfigure PgWide=1> + <mediaobject> + <imageobject> + <imagedata fileref="overview.gif" format="gif" Scalefit=1 Align="Center"> + </imageobject> + </mediaobject> + </informalfigure> + <para> +On the target-side there are configuration options to control which +network devices should be present. For many applications a single +device will be sufficient, but if the final eCos application is +something like a network bridge then the package can support multiple +devices. On the host-side each eCos network device needs to be mapped +on to a Linux one, either a real ethernet device or an ethertap +device. This is handled by an entry in the target definition file: + </para> + <programlisting> +synth_device ethernet { + eth0 real eth1 + eth1 ethertap tap3 00:01:02:03:FE:05 + … +} +</programlisting> + <para> +The ethernet package also comes with support for packet logging, +and provides various facilities for use by user Tcl scripts. + </para> + </refsect1> + + <refsect1 id="devs-eth-ecosynth-install"><title>Installation</title> + <para> +Before a synthetic target eCos application can access ethernet devices +it is necessary to build and install host-side support. The relevant +code resides in the <filename class="directory">host</filename> +subdirectory of the synthetic target ethernet package, and building it +involves the standard <command>configure</command>, +<command>make</command> and <command>make install</command> steps. +The build involves a new executable <command>rawether</command> which +must be able to access a raw Linux network device. This is achieved by +installing it suid root, so the <command>make install</command> step +has to be run with superuser privileges. + </para> + <caution><para> +Installing <command>rawether</command> suid root introduces a +potential security problem. Although normally +<command>rawether</command> is executed only by the I/O auxiliary, +theoretically it can be run by any program. Effectively it gives any +user the ability to monitor all ethernet traffic and to inject +arbitrary packets into the network. Also, as with any suid root +programs there may be as yet undiscovered exploits. Users and system +administrators should consider the risks before running <command>make +install</command>. + </para></caution> + <para> +There are two main ways of building the host-side software. It is +possible to build both the generic host-side software and all +package-specific host-side software, including the ethernet support, +in a single build tree. This involves using the +<command>configure</command> script at the toplevel of the eCos +repository. For more information on this, see the +<filename>README.host</filename> file at the top of the repository. +Note that if you have an existing build tree which does not include +the synthetic target ethernet support then it will be necessary to +rerun the toplevel configure script: the search for appropriate +packages happens at configure time. + </para> + <para> +The alternative is to build just the host-side for this package. +This requires a separate build directory, building directly in the +source tree is disallowed. The <command>configure</command> options +are much the same as for a build from the toplevel, and the +<filename>README.host</filename> file can be consulted for more +details. It is essential that the ethernet support be configured with +the same <option>--prefix</option> option as other eCos host-side +software, especially the I/O auxiliary provided by the architectural +synthetic target HAL package, otherwise the I/O auxiliary will be +unable to locate the ethernet support. + </para> + </refsect1> + + <refsect1 id="devs-eth-ecosynth-options"><title>Target-side Configuration Options</title> + <para> +The target-side code can be configured to support up to four ethernet +devices, <varname>eth0</varname> to <varname>eth3</varname>. By +default <varname>eth0</varname> is enabled if the configuration +includes a TCP/IP stack, otherwise it is disabled. The other three +devices are always disabled by default. If any of the devices are +enabled then there will also be the usual configuration options +related to building this package. Other options related to network +devices, for example whether or not to use DHCP, are provided by +the generic network device package. + </para> + </refsect1> + + <refsect1 id="devs-eth-ecosynth-real"><title>Real Ethernet</title> + <para> +One obvious way of providing a synthetic target eCos application with +ethernet I/O is to use a real ethernet device in the PC: transmitted +packets go out on a real network, and packets on the network addressed +to the right MAC address are passed on to eCos. This way synthetic +target networking behaves just like networking on a real target with +ethernet hardware. For example, if there is a DHCP server anywhere on +the network then eCos will be able to contact it during networking +startup and get hold of IP address information. + </para> + <para> +Configuring the ethernet support to use a real ethernet device +requires a simple entry in the target definition file: + </para> + <programlisting> +synth_device ethernet { + <eCos device> real <linux device> + … +} +</programlisting> + <para> +For example, to map the eCos network device <varname>eth0</varname> to +the Linux device <varname>eth1</varname>: + </para> + <programlisting> +synth_device ethernet { + eth0 real eth1 + … +} +</programlisting> + <para> +It is not possible for an ethernet device to be shared by both the +eCos TCP/IP stack and the Linux one: there would be no simple way to +work out which stack incoming packets are intended for. In theory +it might be possible to do some demultiplexing using distinct IP +addresses, but it would be impossible to support some functionality +such as DHCP. Therefore the <command>rawether</command> program will +refuse to access any ethernet device already in use. On a typical +Linux system <varname>eth0</varname> will be used for Linux +networking, and the PC will have to be equipped with additional +ethernet devices for use by eCos. + </para> + <para> +The <command>rawether</command> program will access the hardware via +the appropriate Linux device driver, so it is important that the +system is set up such that the relevant module will be automatically +loaded or is already loaded. The details of this will depend on the +installed distribution and version, but typically it will involve an +entry in <filename>/etc/modules.conf</filename>. + </para> + </refsect1> + + <refsect1 id="devs-eth-ecosynth-ethertap"><title>Ethertap</title> + <para> +The Linux kernel's ethertap facility provides a virtual network +interface. A Linux application, for example the +<command>rawether</command> program, can open a special character +device <filename>/dev/net/tun</filename>, perform various +<function>ioctl</function> calls, and then <filename>write</filename> +and <filename>read</filename> ethernet packets. When the device is +opened the Linux kernel automatically creates a new network interface, +for example <varname>tap0</varname>. The Linux TCP/IP stack can be +made to use this network interface like any other interface, receiving +and transmitting ethernet packets. The net effect is a virtual network +connecting just the Linux and eCos TCP/IP stacks, with no other nodes +attached. By default all traffic remains inside this virtual network +and is never forwarded to a real network. + </para> + <para> +Support for the ethertap facility may or may not be provided +automatically, depending on your Linux distribution and version. If +your system does not have a device <filename>/dev/net/tun</filename> +or a module <filename>tun.o</filename> then the appropriate kernel +documentation should be consulted, for example +<filename>/usr/src/linux-2.4/Documentation/networking/tuntap.txt</filename>. + </para> + <para> +The target definition file is used to map eCos network devices on to +ethertap devices. The simplest usage is: + </para> + <programlisting> +synth_device ethernet { + eth0 ethertap + … +} +</programlisting> + <para> +The Linux kernel will automatically allocate the next available tap +network interface. Usually this will be <varname>tap0</varname> but if +other software is using the ethertap facility, for example to +implement a VPN, then a different number may be allocated. Usually it +will be better to specify the particular tap device that should be +used for each eCos device, for example: + </para> + <programlisting> +synth_device ethernet { + eth0 ethertap tap3 + eth1 ethertap tap4 + … +} +</programlisting> + <para> +The user now knows exactly which eCos device is mapped onto which +Linux device, avoiding much potential confusion. Because the virtual +devices are emulated ethernet devices, they require MAC addresses. +There is no physical hardware to provide these addresses, so normally +MAC addresses will be invented. That means that each time the eCos +application is run it will have different MAC addresses, which makes +it more difficult to compare the results of different runs. To get +more deterministic behaviour it is possible to specify the MAC +addresses in the target definition file: + </para> + <programlisting> +synth_device ethernet { + eth0 ethertap tap3 00:01:02:03:FE:05 + eth1 ethertap tap4 00:01:02:03:FE:06 + … +} +</programlisting> + <para> +During the initialization phase the eCos application will instantiate +the various network devices. This will cause the I/O auxiliary to load +the <filename>ethernet.tcl</filename> script and spawn +<command>rawether</command> processes, which in turn will +<function>open</function> <filename>/dev/net/tun</filename> and +perform the appropriate <filename>ioctl</filename> calls. On the Linux +side there will now be new network interfaces such as +<varname>tap3</varname>, and these can be configured like any other +network interface using commands such as <command>ifconfig</command>. +In addition, if the Linux system is set up with hotplug support then +it may be possible to arrange for the network interface to become +active automatically. On a Red Hat Linux system this would require +files such as +<filename>/etc/sysconfig/network-scripts/ifcfg-tap3</filename>, +containing data like: + </para> + <programlisting> +DEVICE="tap3" +BOOTPROTO="none" +BROADCAST=10.2.2.255 +IPADDR="10.2.2.1" +NETMASK="255.255.255.0" +NETWORK=10.2.2.0 +ONBOOT="no" +</programlisting> + <para> +This gives the Linux interface the address <literal>10.2.2.1</literal> +on the network <literal>10.2.2.0</literal>. The eCos network device +should be configured with a compatible address. One way of doing this +would be to enable <varname>CYGHWR_NET_DRIVER_ETH0_ADDRS</varname>, +set <varname>CYGHWR_NET_DRIVER_ETH0_ADDRS_IP</varname> to +<literal>10.2.2.2</literal>, and similarly update the +<varname>NETMASK</varname>, <varname>BROADCAST</varname>, +<varname>GATEWAY</varname> and <varname>SERVER</varname> configuration +options. + </para> + <para> +It should be noted that the ethertap facility provides a virtual +network, and any packets transmitted by the eCos application will +not appear on a real network. Therefore usually there will no +accessible DHCP server, and eCos cannot use DHCP or BOOTP to obtain IP +address information. Instead the eCos configuration should use manual +or static addresses. + </para> + <para> +An alternative approach would be to set up the Linux box as a network +bridge, using commands like <command>brctl</command> to connect the +virtual network interface <varname>tap3</varname> to a physical +network interface such as <varname>eth0</varname>. Any packets sent by +the eCos application will get forwarded automatically to the real +network, and some packets on the real network will get forwarded over +the virtual network to the eCos application. Note that the eCos +application might also get some packets that were not intended for it, +but usually those will just be discarded by the eCos TCP/IP stack. The +exact details of setting up a network bridge are left as an exercise +to the reader. + </para> + </refsect1> + + <refsect1 id="devs-eth-ecosynth-logging"><title>Packet Logging</title> + <para> +The ethernet support comes with support for logging the various +packets that are transferred, including a simple protocol analyser. +This generates simple text output using the filter mechanisms provided +by the I/O auxiliary, so it is possible to control the appearance and +visibility of different types of output. For example the user might +want to see IPv4 headers and all ICMPv4 and ARP operations, but not +TCP headers or any of the packet data. + </para> + <para> +The protocol analyser is not intended to be a fully functional +analyser with knowledge of many different TCP/IP protocols, advanced +search facilities, graphical traffic displays, and so on. +Functionality like that is already provided by other tools such as +<application>ethereal</application> and +<application>tcpdump</application>. Achieving similar levels of +functionality would require a lot of work, for very little gain. It is +still useful to have some protocol analysis functionality available +because the output will be interleaved with other output, for example +<filename>printf</filename> calls from the application. That may make +it easier to understand the sequence of events. + </para> + <para> +One problem with logging ethernet traffic is that it can involve very +large amounts of data. If the application is expected to run for a +long time or is very I/O intensive then it is easy to end up with many +megabytes. When running in graphical mode all the logging data will be +held in memory, even data that is not currently visible. At some point +the system will begin to run low on memory and performance will +suffer. To avoid problems, the ethernet script maintains a flag that +controls whether or not packet logging is active. The default is to +run with logging disabled, but this can be changed in the target +definition file: + </para> + <programlisting> +synth_device ethernet { + … + logging 1 +} +</programlisting> + <para> +The ethernet script will add a toolbar button that allows this flag to +be changed at run-time, allowing the user to capture traffic for +certain periods of time while the application continues running. + </para> + <para> +The target definition file can contain the following entries for the +various packet logging filters: + </para> + <programlisting width=72> +synth_device ethernet { + … + filter ether -hide 0 -background LightBlue -foreground "#000080" + filter arp -hide 0 -background LightBlue -foreground "#000050" + filter ipv4 -hide 0 -background LightBlue -foreground "#000040" + filter ipv6 -hide 1 -background LightBlue -foreground "#000040" + filter icmpv4 -hide 0 -background LightBlue -foreground "#000070" + filter icmpv6 -hide 1 -background LightBlue -foreground "#000070" + filter udp -hide 0 -background LightBlue -foreground "#000030" + filter tcp -hide 0 -background LightBlue -foreground "#000020" + filter hexdata -hide 1 -background LightBlue -foreground "#000080" + filter asciidata -hide 1 -background LightBlue -foreground "#000080" +} +</programlisting> + <para> +All output will show the eCos network device, for example +<literal>eth0</literal>, and the direction relative to the eCos +application. Some of the filters will show packet headers, for example +<literal>ether</literal> gives details of the ethernet packet header +and <literal>tcp</literal> gives information about TCP headers such as +whether or not the SYN flag is set. The TCP and UDP filters will also +show source and destination addresses, using numerical addresses and +if possible host names. However, host names will only be shown if the +host appears in <filename>/etc/hosts</filename>: doing full DNS +lookups while the data is being captured would add significantly to +complexity and overhead. The <literal>hexdata</literal> and +<literal>asciidata</literal> filters show the remainder of the packets +after the ethernet, IP and TCP or UDP headers have been stripped. + </para> + <para> +Some of the filters will provide raw dumps of some of the packet data. +Showing up to 1500 bytes of data for each packet would be expensive, +and often the most interesting information is near the start of the +packet. Therefore it is possible to set a limit on the number of bytes +that will be shown using the target definition file. The default limit +is 64 bytes. + </para> + <programlisting width=72> +synth_device ethernet { + … + max_show 128 +} +</programlisting> + </refsect1> + + <refsect1 id="devs-eth-ecosynth-gui"><title>User Interface Additions</title> + <para> +When running in graphical mode the ethernet script extends the user +interface in two ways: a button is added to the toolbar so that users +can enable or disable packet logging; and an entry is added to the +<guimenu>Help</guimenu> menu for the ethernet-specific documentation. + </para> + </refsect1> + + <refsect1 id="devs-eth-ecosynth-args"><title>Command Line Arguments</title> + <para> +The synthetic target ethernet support does not use any command line +arguments. All configuration is handled through the target definition +file. + </para> + </refsect1> + + <refsect1 id="devs-eth-ecosynth-hooks"><title>Hooks</title> + <para> +The ethernet support defines two hooks that can be used by other +scripts, especially user scripts: <literal>ethernet_tx</literal> and +<literal>ethernet_rx</literal>. The tx hook is called whenever eCos +tries to transmit a packet. The rx hook is called whenever an incoming +packet is passed to the eCos application. Note that this may be a +little bit after the packet was actually received by the I/O auxiliary +since it can buffer some packets. Both hooks are called with two +arguments, the name of the network device and the packet being +transferred. Typical usage might look like: + </para> + <programlisting> + proc my_tx_hook { arg_list } { + set dev [lindex $arg_list 0] + incr ::my_ethernet_tx_packets($dev) + incr ::my_ethernet_tx_bytes($dev) [string length [lindex $arg_list 1]] + } + proc my_rx_hook { arg_list } { + set dev [lindex $arg_list 0] + incr ::my_ethernet_rx_packets($dev) + incr ::my_ethernet_rx_bytes($dev) [string length [lindex $arg_list 1]] + } + synth::hook_add "ethernet_tx" my_tx_hook + synth::hook_add "ethernet_rx" my_rx_hook +</programlisting> + <para> +The global arrays <varname>my_ethernet_tx_packets</varname> etc. will +now be updated whenever there is ethernet traffic. Other code, +probably running at regular intervals by use of the Tcl +<command>after</command> procedure, can then use this information to +update a graphical monitor of some sort. + </para> + </refsect1> + + <refsect1 id="devs-eth-ecosynth-tcl"><title>Additional Tcl Procedures</title> + <para> +The ethernet support provides one additional Tcl procedure that can be +used by other scripts; + </para> + <programlisting> +ethernet::devices_get_list +</programlisting> + <para> +This procedure returns a list of the ethernet devices that have been +instantiated, for example <literal>{eth0 eth1}</literal>. + </para> + </refsect1> + +</refentry>
new file mode 100644 --- /dev/null +++ b/packages/devs/eth/synth/ecosynth/current/host/Makefile.am @@ -0,0 +1,91 @@ +## Process this file with automake to produce Makefile.in +## ===================================================================== +## +## Makefile.am +## +## Build support for the host-side synthetic target support, +## the ethernetpackage. +## +## ===================================================================== +######COPYRIGHTBEGIN#### +# +# ---------------------------------------------------------------------------- +# Copyright (C) 2002 Bart Veer +# +# This file is part of the eCos synthetic target ethernet support. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the Free +# Software Foundation; either version 2 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, write to the Free Software Foundation, Inc., +# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# ---------------------------------------------------------------------------- +# +######COPYRIGHTEND#### +## ===================================================================== +#######DESCRIPTIONBEGIN#### +## +## Author(s): bartv +## Contact(s): bartv +## Date: 2002/08/07 +## Version: 0.01 +## +######DESCRIPTIONEND#### +## ===================================================================== + +AUTOMAKE_OPTIONS = 1.3 foreign + +## Only some platforms are supported. Having the configure script throw +## an error when attempting to configure on an unsupported platform +## would be a mistake, since that would prevent any configury from +## the toplevel on unsupported platforms. Instead an automake conditional +## is used, leading to null makefiles on unsupported platforms. + +if SUPPORTED + +AM_CFLAGS = @ecos_CFLAGS@ -DECOSYNTH_VERSION=\"@VERSION@\" \ + -DECOS_REPOSITORY=\"@ECOS_REPOSITORY@\" \ + -DLIBEXECDIR=\"$(libexecdir)\" \ + -DPACKAGE_DIR=\"@PACKAGE_DIR@\" \ + -DPACKAGE_VERSION=\"@PACKAGE_VERSION@\" \ + -DPACKAGE_INSTALL=\"@PACKAGE_INSTALL@\" +AM_CXXFLAGS = @ecos_CXXFLAGS@ +INCLUDES = @ecos_INCLUDES@ +LIBS = @ecos_LIBS@ @ecos_LDADD@ + +## The synthetic target support consists of a single program rawether, +## a number of Tcl scripts, and some additional data files. These are +## all installed in a single directory $(libexec)/ecos/<package>_<version>/ +## Neither the rawether executable nor any of the scripts are directly +## executable, instead rawether gets fork()'d/execve()'d by the Tcl +## script so $(libexec) is appropriate. Strictly speaking the +## Tcl scripts and data files are architecture-independent so should +## probably be installed in an analogous directory below $(datadir), +## but that would add more directories for little real gain. The scripts +## are treated as data files since they should not be executed directly, +## i.e. they should not be installed with the execute bit set. + +etherdir = $(libexecdir)/ecos/@PACKAGE_INSTALL@ +ether_PROGRAMS = rawether +ether_DATA = ethernet.tcl ethernet.tdf netrecord.xbm + +rawether_SOURCES = rawether.c + +## Manual dependencies +rawether.$(OBJEXT) : Makefile ../src/protocol.h + +## The rawether program needs to run with root privileges, or it will +## be unable to access the ethernet hardware. +install-data-hook: + chown root $(etherdir)/rawether + chmod u+s $(etherdir)/rawether + +endif
new file mode 100644 --- /dev/null +++ b/packages/devs/eth/synth/ecosynth/current/host/Makefile.in @@ -0,0 +1,450 @@ +# Makefile.in generated automatically by automake 1.4-p5 from Makefile.am + +# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +######COPYRIGHTBEGIN#### +# +# ---------------------------------------------------------------------------- +# Copyright (C) 2002 Bart Veer +# +# This file is part of the eCos synthetic target ethernet support. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the Free +# Software Foundation; either version 2 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, write to the Free Software Foundation, Inc., +# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# ---------------------------------------------------------------------------- +# +######COPYRIGHTEND#### +#######DESCRIPTIONBEGIN#### +######DESCRIPTIONEND#### + + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DESTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = . + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_alias = @host_alias@ +host_triplet = @host@ +CC = @CC@ +CXX = @CXX@ +ECOS_REPOSITORY = @ECOS_REPOSITORY@ +EXEEXT = @EXEEXT@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MSVC_SRCDIR = @MSVC_SRCDIR@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_DIR = @PACKAGE_DIR@ +PACKAGE_INSTALL = @PACKAGE_INSTALL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +VERSION = @VERSION@ +ecos_CFLAGS = @ecos_CFLAGS@ +ecos_CXXFLAGS = @ecos_CXXFLAGS@ +ecos_INCLUDES = @ecos_INCLUDES@ +ecos_LDADD = @ecos_LDADD@ +ecos_LIBS = @ecos_LIBS@ +ecos_infra_incdir = @ecos_infra_incdir@ +ecos_infra_libdir = @ecos_infra_libdir@ +ecos_libcdl_incdir = @ecos_libcdl_incdir@ +ecos_libcdl_libdir = @ecos_libcdl_libdir@ +ecos_tk_libs = @ecos_tk_libs@ + +AUTOMAKE_OPTIONS = 1.3 foreign + +@SUPPORTED_TRUE@AM_CFLAGS = @SUPPORTED_TRUE@@ecos_CFLAGS@ -DECOSYNTH_VERSION=\"@VERSION@\" \ +@SUPPORTED_TRUE@ -DECOS_REPOSITORY=\"@ECOS_REPOSITORY@\" \ +@SUPPORTED_TRUE@ -DLIBEXECDIR=\"$(libexecdir)\" \ +@SUPPORTED_TRUE@ -DPACKAGE_DIR=\"@PACKAGE_DIR@\" \ +@SUPPORTED_TRUE@ -DPACKAGE_VERSION=\"@PACKAGE_VERSION@\" \ +@SUPPORTED_TRUE@ -DPACKAGE_INSTALL=\"@PACKAGE_INSTALL@\" +@SUPPORTED_TRUE@AM_CXXFLAGS = @SUPPORTED_TRUE@@ecos_CXXFLAGS@ +@SUPPORTED_TRUE@INCLUDES = @SUPPORTED_TRUE@@ecos_INCLUDES@ +@SUPPORTED_TRUE@LIBS = @SUPPORTED_TRUE@@ecos_LIBS@ @ecos_LDADD@ + +@SUPPORTED_TRUE@etherdir = @SUPPORTED_TRUE@$(libexecdir)/ecos/@PACKAGE_INSTALL@ +@SUPPORTED_TRUE@ether_PROGRAMS = @SUPPORTED_TRUE@rawether +@SUPPORTED_TRUE@ether_DATA = @SUPPORTED_TRUE@ethernet.tcl ethernet.tdf netrecord.xbm + +@SUPPORTED_TRUE@rawether_SOURCES = @SUPPORTED_TRUE@rawether.c +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +mkinstalldirs = $(SHELL) $(top_srcdir)/../../../../../../../acsupport/mkinstalldirs +CONFIG_CLEAN_FILES = +@SUPPORTED_TRUE@ether_PROGRAMS = rawether$(EXEEXT) +PROGRAMS = $(ether_PROGRAMS) + + +DEFS = @DEFS@ -I. -I$(srcdir) +CPPFLAGS = @CPPFLAGS@ +LDFLAGS = @LDFLAGS@ +@SUPPORTED_TRUE@rawether_OBJECTS = rawether.$(OBJEXT) +rawether_LDADD = $(LDADD) +rawether_DEPENDENCIES = +rawether_LDFLAGS = +CFLAGS = @CFLAGS@ +COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ +DATA = $(ether_DATA) + +DIST_COMMON = Makefile.am Makefile.in acinclude.m4 aclocal.m4 configure \ +configure.in + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = gtar +GZIP_ENV = --best +DEP_FILES = .deps/rawether.P +SOURCES = $(rawether_SOURCES) +OBJECTS = $(rawether_OBJECTS) + +all: all-redirect +.SUFFIXES: +.SUFFIXES: .S .c .o .obj .s +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES) + cd $(top_builddir) \ + && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status + +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ configure.in acinclude.m4 + cd $(srcdir) && $(ACLOCAL) + +config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck +$(srcdir)/configure: @MAINTAINER_MODE_TRUE@$(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES) + cd $(srcdir) && $(AUTOCONF) + +mostlyclean-etherPROGRAMS: + +clean-etherPROGRAMS: + -test -z "$(ether_PROGRAMS)" || rm -f $(ether_PROGRAMS) + +distclean-etherPROGRAMS: + +maintainer-clean-etherPROGRAMS: + +install-etherPROGRAMS: $(ether_PROGRAMS) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(etherdir) + @list='$(ether_PROGRAMS)'; for p in $$list; do \ + if test -f $$p; then \ + echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(etherdir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \ + $(INSTALL_PROGRAM) $$p $(DESTDIR)$(etherdir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ + else :; fi; \ + done + +uninstall-etherPROGRAMS: + @$(NORMAL_UNINSTALL) + list='$(ether_PROGRAMS)'; for p in $$list; do \ + rm -f $(DESTDIR)$(etherdir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ + done + +# FIXME: We should only use cygpath when building on Windows, +# and only if it is available. +.c.obj: + $(COMPILE) -c `cygpath -w $<` + +.s.o: + $(COMPILE) -c $< + +.S.o: + $(COMPILE) -c $< + +mostlyclean-compile: + -rm -f *.o core *.core + -rm -f *.$(OBJEXT) + +clean-compile: + +distclean-compile: + -rm -f *.tab.c + +maintainer-clean-compile: + +rawether$(EXEEXT): $(rawether_OBJECTS) $(rawether_DEPENDENCIES) + @rm -f rawether$(EXEEXT) + $(LINK) $(rawether_LDFLAGS) $(rawether_OBJECTS) $(rawether_LDADD) $(LIBS) + +install-etherDATA: $(ether_DATA) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(etherdir) + @list='$(ether_DATA)'; for p in $$list; do \ + if test -f $(srcdir)/$$p; then \ + echo " $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(etherdir)/$$p"; \ + $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(etherdir)/$$p; \ + else if test -f $$p; then \ + echo " $(INSTALL_DATA) $$p $(DESTDIR)$(etherdir)/$$p"; \ + $(INSTALL_DATA) $$p $(DESTDIR)$(etherdir)/$$p; \ + fi; fi; \ + done + +uninstall-etherDATA: + @$(NORMAL_UNINSTALL) + list='$(ether_DATA)'; for p in $$list; do \ + rm -f $(DESTDIR)$(etherdir)/$$p; \ + done + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + here=`pwd` && cd $(srcdir) \ + && mkid -f$$here/ID $$unique $(LISP) + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ + || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS) + +mostlyclean-tags: + +clean-tags: + +distclean-tags: + -rm -f TAGS ID + +maintainer-clean-tags: + +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + -rm -rf $(distdir) + GZIP=$(GZIP_ENV) $(TAR) zxf $(distdir).tar.gz + mkdir $(distdir)/=build + mkdir $(distdir)/=inst + dc_install_base=`cd $(distdir)/=inst && pwd`; \ + cd $(distdir)/=build \ + && ../configure --srcdir=.. --prefix=$$dc_install_base \ + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) dvi \ + && $(MAKE) $(AM_MAKEFLAGS) check \ + && $(MAKE) $(AM_MAKEFLAGS) install \ + && $(MAKE) $(AM_MAKEFLAGS) installcheck \ + && $(MAKE) $(AM_MAKEFLAGS) dist + -rm -rf $(distdir) + @banner="$(distdir).tar.gz is ready for distribution"; \ + dashes=`echo "$$banner" | sed s/./=/g`; \ + echo "$$dashes"; \ + echo "$$banner"; \ + echo "$$dashes" +dist: distdir + -chmod -R a+r $(distdir) + GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir) + -rm -rf $(distdir) +dist-all: distdir + -chmod -R a+r $(distdir) + GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir) + -rm -rf $(distdir) +distdir: $(DISTFILES) + -rm -rf $(distdir) + mkdir $(distdir) + -chmod 777 $(distdir) + here=`cd $(top_builddir) && pwd`; \ + top_distdir=`cd $(distdir) && pwd`; \ + distdir=`cd $(distdir) && pwd`; \ + cd $(top_srcdir) \ + && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --foreign Makefile + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + if test -d $$d/$$file; then \ + cp -pr $$d/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ + done + +DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :) + +-include $(DEP_FILES) + +mostlyclean-depend: + +clean-depend: + +distclean-depend: + -rm -rf .deps + +maintainer-clean-depend: + +%.o: %.c + @echo '$(COMPILE) -c $<'; \ + $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $< + @-cp .deps/$(*F).pp .deps/$(*F).P; \ + tr ' ' '\012' < .deps/$(*F).pp \ + | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \ + >> .deps/$(*F).P; \ + rm .deps/$(*F).pp + +%.lo: %.c + @echo '$(LTCOMPILE) -c $<'; \ + $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $< + @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \ + < .deps/$(*F).pp > .deps/$(*F).P; \ + tr ' ' '\012' < .deps/$(*F).pp \ + | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \ + >> .deps/$(*F).P; \ + rm -f .deps/$(*F).pp +info-am: +info: info-am +dvi-am: +dvi: dvi-am +check-am: all-am +check: check-am +installcheck-am: +installcheck: installcheck-am +install-exec-am: +install-exec: install-exec-am + +install-data-am: install-etherPROGRAMS install-etherDATA + @$(NORMAL_INSTALL) + $(MAKE) $(AM_MAKEFLAGS) install-data-hook +install-data: install-data-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-am +uninstall-am: uninstall-etherPROGRAMS uninstall-etherDATA +uninstall: uninstall-am +all-am: Makefile $(PROGRAMS) $(DATA) +all-redirect: all-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install +installdirs: + $(mkinstalldirs) $(DESTDIR)$(etherdir) $(DESTDIR)$(etherdir) + + +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + +maintainer-clean-generic: +mostlyclean-am: mostlyclean-etherPROGRAMS mostlyclean-compile \ + mostlyclean-tags mostlyclean-depend mostlyclean-generic + +mostlyclean: mostlyclean-am + +clean-am: clean-etherPROGRAMS clean-compile clean-tags clean-depend \ + clean-generic mostlyclean-am + +clean: clean-am + +distclean-am: distclean-etherPROGRAMS distclean-compile distclean-tags \ + distclean-depend distclean-generic clean-am + +distclean: distclean-am + -rm -f config.status + +maintainer-clean-am: maintainer-clean-etherPROGRAMS \ + maintainer-clean-compile maintainer-clean-tags \ + maintainer-clean-depend maintainer-clean-generic \ + distclean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +maintainer-clean: maintainer-clean-am + -rm -f config.status + +.PHONY: mostlyclean-etherPROGRAMS distclean-etherPROGRAMS \ +clean-etherPROGRAMS maintainer-clean-etherPROGRAMS \ +uninstall-etherPROGRAMS install-etherPROGRAMS mostlyclean-compile \ +distclean-compile clean-compile maintainer-clean-compile \ +uninstall-etherDATA install-etherDATA tags mostlyclean-tags \ +distclean-tags clean-tags maintainer-clean-tags distdir \ +mostlyclean-depend distclean-depend clean-depend \ +maintainer-clean-depend info-am info dvi-am dvi check check-am \ +installcheck-am installcheck install-exec-am install-exec \ +install-data-am install-data install-am install uninstall-am uninstall \ +all-redirect all-am all installdirs mostlyclean-generic \ +distclean-generic clean-generic maintainer-clean-generic clean \ +mostlyclean distclean maintainer-clean + + +@SUPPORTED_TRUE@rawether.$(OBJEXT) : Makefile ../src/protocol.h + +@SUPPORTED_TRUE@install-data-hook: +@SUPPORTED_TRUE@ chown root $(etherdir)/rawether +@SUPPORTED_TRUE@ chmod u+s $(etherdir)/rawether + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT:
new file mode 100644 --- /dev/null +++ b/packages/devs/eth/synth/ecosynth/current/host/acinclude.m4 @@ -0,0 +1,45 @@ +dnl Process this file with aclocal to get an aclocal.m4 file. Then +dnl process that with autoconf. +dnl ==================================================================== +dnl +dnl acinclude.m4 +dnl +dnl ==================================================================== +dnl####COPYRIGHTBEGIN#### +dnl +dnl ---------------------------------------------------------------------------- +dnl Copyright (C) 2002 Bart Veer +dnl +dnl This file is part of the eCos host tools. +dnl +dnl This program is free software; you can redistribute it and/or modify it +dnl under the terms of the GNU General Public License as published by the Free +dnl Software Foundation; either version 2 of the License, or (at your option) +dnl any later version. +dnl +dnl This program is distributed in the hope that it will be useful, but WITHOUT +dnl ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +dnl FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +dnl more details. +dnl +dnl You should have received a copy of the GNU General Public License along with +dnl this program; if not, write to the Free Software Foundation, Inc., +dnl 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +dnl ---------------------------------------------------------------------------- +dnl +dnl####COPYRIGHTEND#### +dnl ==================================================================== +dnl#####DESCRIPTIONBEGIN#### +dnl +dnl Author(s): bartv +dnl Contact(s): bartv +dnl Date: 2002/08/07 +dnl Version: 0.01 +dnl +dnl####DESCRIPTIONEND#### +dnl ==================================================================== + +dnl Access shared macros. +dnl AM_CONDITIONAL needs to be mentioned here or else aclocal does not +dnl incorporate the macro into aclocal.m4 +sinclude(../../../../../../../acsupport/acinclude.m4)
new file mode 100644 --- /dev/null +++ b/packages/devs/eth/synth/ecosynth/current/host/aclocal.m4 @@ -0,0 +1,183 @@ +dnl aclocal.m4 generated automatically by aclocal 1.4-p5 + +dnl Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl This program is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without +dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A +dnl PARTICULAR PURPOSE. + +dnl Process this file with aclocal to get an aclocal.m4 file. Then +dnl process that with autoconf. +dnl ==================================================================== +dnl +dnl acinclude.m4 +dnl +dnl ==================================================================== +dnl####COPYRIGHTBEGIN#### +dnl +dnl ---------------------------------------------------------------------------- +dnl Copyright (C) 2002 Bart Veer +dnl +dnl This file is part of the eCos host tools. +dnl +dnl This program is free software; you can redistribute it and/or modify it +dnl under the terms of the GNU General Public License as published by the Free +dnl Software Foundation; either version 2 of the License, or (at your option) +dnl any later version. +dnl +dnl This program is distributed in the hope that it will be useful, but WITHOUT +dnl ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +dnl FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +dnl more details. +dnl +dnl You should have received a copy of the GNU General Public License along with +dnl this program; if not, write to the Free Software Foundation, Inc., +dnl 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +dnl ---------------------------------------------------------------------------- +dnl +dnl####COPYRIGHTEND#### +dnl ==================================================================== +dnl#####DESCRIPTIONBEGIN#### +dnl +dnl Author(s): bartv +dnl Contact(s): bartv +dnl Date: 2002/08/07 +dnl Version: 0.01 +dnl +dnl####DESCRIPTIONEND#### +dnl ==================================================================== + +dnl Access shared macros. +dnl AM_CONDITIONAL needs to be mentioned here or else aclocal does not +dnl incorporate the macro into aclocal.m4 +sinclude(../../../../../../../acsupport/acinclude.m4) + +# Define a conditional. + +AC_DEFUN([AM_CONDITIONAL], +[AC_SUBST($1_TRUE) +AC_SUBST($1_FALSE) +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi]) + +# Do all the work for Automake. This macro actually does too much -- +# some checks are only needed if your package does certain things. +# But this isn't really a big deal. + +# serial 1 + +dnl Usage: +dnl AM_INIT_AUTOMAKE(package,version, [no-define]) + +AC_DEFUN([AM_INIT_AUTOMAKE], +[AC_REQUIRE([AC_PROG_INSTALL]) +PACKAGE=[$1] +AC_SUBST(PACKAGE) +VERSION=[$2] +AC_SUBST(VERSION) +dnl test to see if srcdir already configured +if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) +fi +ifelse([$3],, +AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) +AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])) +AC_REQUIRE([AM_SANITY_CHECK]) +AC_REQUIRE([AC_ARG_PROGRAM]) +dnl FIXME This is truly gross. +missing_dir=`cd $ac_aux_dir && pwd` +AM_MISSING_PROG(ACLOCAL, aclocal, $missing_dir) +AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir) +AM_MISSING_PROG(AUTOMAKE, automake, $missing_dir) +AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir) +AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir) +AC_REQUIRE([AC_PROG_MAKE_SET])]) + +# +# Check to make sure that the build environment is sane. +# + +AC_DEFUN([AM_SANITY_CHECK], +[AC_MSG_CHECKING([whether build environment is sane]) +# Just in case +sleep 1 +echo timestamp > conftestfile +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null` + if test "[$]*" = "X"; then + # -L didn't work. + set X `ls -t $srcdir/configure conftestfile` + fi + if test "[$]*" != "X $srcdir/configure conftestfile" \ + && test "[$]*" != "X conftestfile $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken +alias in your environment]) + fi + + test "[$]2" = conftestfile + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +rm -f conftest* +AC_MSG_RESULT(yes)]) + +dnl AM_MISSING_PROG(NAME, PROGRAM, DIRECTORY) +dnl The program must properly implement --version. +AC_DEFUN([AM_MISSING_PROG], +[AC_MSG_CHECKING(for working $2) +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if ($2 --version) < /dev/null > /dev/null 2>&1; then + $1=$2 + AC_MSG_RESULT(found) +else + $1="$3/missing $2" + AC_MSG_RESULT(missing) +fi +AC_SUBST($1)]) + +# Add --enable-maintainer-mode option to configure. +# From Jim Meyering + +# serial 1 + +AC_DEFUN([AM_MAINTAINER_MODE], +[AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) + dnl maintainer-mode is disabled by default + AC_ARG_ENABLE(maintainer-mode, +[ --enable-maintainer-mode enable make rules and dependencies not useful + (and sometimes confusing) to the casual installer], + USE_MAINTAINER_MODE=$enableval, + USE_MAINTAINER_MODE=no) + AC_MSG_RESULT($USE_MAINTAINER_MODE) + AM_CONDITIONAL(MAINTAINER_MODE, test $USE_MAINTAINER_MODE = yes) + MAINT=$MAINTAINER_MODE_TRUE + AC_SUBST(MAINT)dnl +] +) +
new file mode 100644 --- /dev/null +++ b/packages/devs/eth/synth/ecosynth/current/host/configure @@ -0,0 +1,2013 @@ +#! /bin/sh + +# Guess values for system-dependent variables and create Makefiles. +# Generated automatically using autoconf version 2.13 +# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. + +# Defaults: +ac_help= +ac_default_prefix=/usr/local +# Any additions from configure.in: +ac_help="$ac_help + --enable-maintainer-mode enable make rules and dependencies not useful + (and sometimes confusing) to the casual installer" +ac_help="$ac_help + --enable-debug do a debug rather than a release build" +ac_help="$ac_help + --enable-ansi do an ANSI rather than a unicode build" +ac_help="$ac_help + --with-tcl-version=<vsn> version of Tcl to be used" +ac_help="$ac_help + --with-tcl-header=<path> location of Tcl header" +ac_help="$ac_help + --with-tcl-lib=<path> location of Tcl libraries" +ac_help="$ac_help + --with-tcl=<path> location of Tcl header and libraries" + +# Initialize some variables set by options. +# The variables have the same names as the options, with +# dashes changed to underlines. +build=NONE +cache_file=./config.cache +exec_prefix=NONE +host=NONE +no_create= +nonopt=NONE +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +target=NONE +verbose= +x_includes=NONE +x_libraries=NONE +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datadir='${prefix}/share' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +libdir='${exec_prefix}/lib' +includedir='${prefix}/include' +oldincludedir='/usr/include' +infodir='${prefix}/info' +mandir='${prefix}/man' + +# Initialize some other variables. +subdirs= +MFLAGS= MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} +# Maximum number of lines to put in a shell here document. +ac_max_here_lines=12 + +ac_prev= +for ac_option +do + + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + + case "$ac_option" in + -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) ac_optarg= ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case "$ac_option" in + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir="$ac_optarg" ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build="$ac_optarg" ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file="$ac_optarg" ;; + + -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir="$ac_optarg" ;; + + -disable-* | --disable-*) + ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + eval "enable_${ac_feature}=no" ;; + + -enable-* | --enable-*) + ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "enable_${ac_feature}='$ac_optarg'" ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix="$ac_optarg" ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he) + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat << EOF +Usage: configure [options] [host] +Options: [defaults in brackets after descriptions] +Configuration: + --cache-file=FILE cache test results in FILE + --help print this message + --no-create do not create output files + --quiet, --silent do not print \`checking...' messages + --version print the version of autoconf that created configure +Directory and file names: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [same as prefix] + --bindir=DIR user executables in DIR [EPREFIX/bin] + --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] + --libexecdir=DIR program executables in DIR [EPREFIX/libexec] + --datadir=DIR read-only architecture-independent data in DIR + [PREFIX/share] + --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data in DIR + [PREFIX/com] + --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] + --libdir=DIR object code libraries in DIR [EPREFIX/lib] + --includedir=DIR C header files in DIR [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] + --infodir=DIR info documentation in DIR [PREFIX/info] + --mandir=DIR man documentation in DIR [PREFIX/man] + --srcdir=DIR find the sources in DIR [configure dir or ..] + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM + run sed PROGRAM on installed program names +EOF + cat << EOF +Host type: + --build=BUILD configure for building on BUILD [BUILD=HOST] + --host=HOST configure for HOST [guessed] + --target=TARGET configure for TARGET [TARGET=HOST] +Features and packages: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --x-includes=DIR X include files are in DIR + --x-libraries=DIR X library files are in DIR +EOF + if test -n "$ac_help"; then + echo "--enable and --with options recognized:$ac_help" + fi + exit 0 ;; + + -host | --host | --hos | --ho) + ac_prev=host ;; + -host=* | --host=* | --hos=* | --ho=*) + host="$ac_optarg" ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir="$ac_optarg" ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir="$ac_optarg" ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir="$ac_optarg" ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir="$ac_optarg" ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst \ + | --locals | --local | --loca | --loc | --lo) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* \ + | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + localstatedir="$ac_optarg" ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir="$ac_optarg" ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir="$ac_optarg" ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix="$ac_optarg" ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix="$ac_optarg" ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix="$ac_optarg" ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name="$ac_optarg" ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir="$ac_optarg" ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir="$ac_optarg" ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site="$ac_optarg" ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir="$ac_optarg" ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir="$ac_optarg" ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target="$ac_optarg" ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers) + echo "configure generated by autoconf version 2.13" + exit 0 ;; + + -with-* | --with-*) + ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "with_${ac_package}='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`echo $ac_option|sed -e 's/-*without-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + eval "with_${ac_package}=no" ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes="$ac_optarg" ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries="$ac_optarg" ;; + + -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } + ;; + + *) + if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then + echo "configure: warning: $ac_option: invalid host type" 1>&2 + fi + if test "x$nonopt" != xNONE; then + { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } + fi + nonopt="$ac_option" + ;; + + esac +done + +if test -n "$ac_prev"; then + { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } +fi + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +# File descriptor usage: +# 0 standard input +# 1 file creation +# 2 errors and warnings +# 3 some systems may open it to /dev/tty +# 4 used on the Kubota Titan +# 6 checking for... messages and results +# 5 compiler messages saved in config.log +if test "$silent" = yes; then + exec 6>/dev/null +else + exec 6>&1 +fi +exec 5>./config.log + +echo "\ +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. +" 1>&5 + +# Strip out --no-create and --no-recursion so they do not pile up. +# Also quote any args containing shell metacharacters. +ac_configure_args= +for ac_arg +do + case "$ac_arg" in + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) ;; + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) + ac_configure_args="$ac_configure_args '$ac_arg'" ;; + *) ac_configure_args="$ac_configure_args $ac_arg" ;; + esac +done + +# NLS nuisances. +# Only set these to C if already set. These must not be set unconditionally +# because not all systems understand e.g. LANG=C (notably SCO). +# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! +# Non-C LC_CTYPE values break the ctype check. +if test "${LANG+set}" = set; then LANG=C; export LANG; fi +if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi +if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi +if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo > confdefs.h + +# A filename unique to this package, relative to the directory that +# configure is in, which we can look for to find out if srcdir is correct. +ac_unique_file=rawether.c + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then its parent. + ac_prog=$0 + ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` + test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r $srcdir/$ac_unique_file; then + if test "$ac_srcdir_defaulted" = yes; then + { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } + else + { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } + fi +fi +srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` + +# Prefer explicitly selected file to automatically selected ones. +if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi +fi +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + echo "loading site script $ac_site_file" + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + echo "loading cache $cache_file" + . $cache_file +else + echo "creating cache $cache_file" + > $cache_file +fi + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +ac_exeext= +ac_objext=o +if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then + # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. + if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then + ac_n= ac_c=' +' ac_t=' ' + else + ac_n=-n ac_c= ac_t= + fi +else + ac_n= ac_c='\c' ac_t= +fi + + + +ac_aux_dir= +for ac_dir in ../../../../../../../acsupport $srcdir/../../../../../../../acsupport; do + if test -f $ac_dir/install-sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f $ac_dir/install.sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { echo "configure: error: can not find install-sh or install.sh in ../../../../../../../acsupport $srcdir/../../../../../../../acsupport" 1>&2; exit 1; } +fi +ac_config_guess=$ac_aux_dir/config.guess +ac_config_sub=$ac_aux_dir/config.sub +ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. + + + + echo $ac_n "checking that a separate build tree is being used""... $ac_c" 1>&6 +echo "configure:563: checking that a separate build tree is being used" >&5 + ecos_cwd=`/bin/pwd` + if test "${srcdir}" = "." ; then + srcdir=${ecos_cwd} + fi + if test "${ecos_cwd}" = "${srcdir}" ; then + echo "$ac_t""no" 1>&6 + { echo "configure: error: This configure script should not be run inside the source tree. Instead please use a separate build tree" 1>&2; exit 1; } + else + echo "$ac_t""yes" 1>&6 + fi + + +# Make sure we can run config.sub. +if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then : +else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; } +fi + +echo $ac_n "checking host system type""... $ac_c" 1>&6 +echo "configure:582: checking host system type" >&5 + +host_alias=$host +case "$host_alias" in +NONE) + case $nonopt in + NONE) + if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then : + else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; } + fi ;; + *) host_alias=$nonopt ;; + esac ;; +esac + +host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias` +host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$host" 1>&6 + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# ./install, which can be erroneously created by make from ./install.sh. +echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 +echo "configure:614: checking for a BSD compatible install" >&5 +if test -z "$INSTALL"; then +if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":" + for ac_dir in $PATH; do + # Account for people who put trailing slashes in PATH elements. + case "$ac_dir/" in + /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + if test -f $ac_dir/$ac_prog; then + if test $ac_prog = install && + grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + else + ac_cv_path_install="$ac_dir/$ac_prog -c" + break 2 + fi + fi + done + ;; + esac + done + IFS="$ac_save_IFS" + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL="$ac_cv_path_install" + else + # As a last resort, use the slow shell script. We don't cache a + # path for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the path is relative. + INSTALL="$ac_install_sh" + fi +fi +echo "$ac_t""$INSTALL" 1>&6 + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +echo $ac_n "checking whether build environment is sane""... $ac_c" 1>&6 +echo "configure:667: checking whether build environment is sane" >&5 +# Just in case +sleep 1 +echo timestamp > conftestfile +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t $srcdir/configure conftestfile` + fi + if test "$*" != "X $srcdir/configure conftestfile" \ + && test "$*" != "X conftestfile $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + { echo "configure: error: ls -t appears to fail. Make sure there is not a broken +alias in your environment" 1>&2; exit 1; } + fi + + test "$2" = conftestfile + ) +then + # Ok. + : +else + { echo "configure: error: newly created file is older than distributed files! +Check your system clock" 1>&2; exit 1; } +fi +rm -f conftest* +echo "$ac_t""yes" 1>&6 +if test "$program_transform_name" = s,x,x,; then + program_transform_name= +else + # Double any \ or $. echo might interpret backslashes. + cat <<\EOF_SED > conftestsed +s,\\,\\\\,g; s,\$,$$,g +EOF_SED + program_transform_name="`echo $program_transform_name|sed -f conftestsed`" + rm -f conftestsed +fi +test "$program_prefix" != NONE && + program_transform_name="s,^,${program_prefix},; $program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s,\$\$,${program_suffix},; $program_transform_name" + +# sed with no file args requires a program. +test "$program_transform_name" = "" && program_transform_name="s,x,x," + +echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6 +echo "configure:724: checking whether ${MAKE-make} sets \${MAKE}" >&5 +set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftestmake <<\EOF +all: + @echo 'ac_maketemp="${MAKE}"' +EOF +# GNU make sometimes prints "make[1]: Entering...", which would confuse us. +eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=` +if test -n "$ac_maketemp"; then + eval ac_cv_prog_make_${ac_make}_set=yes +else + eval ac_cv_prog_make_${ac_make}_set=no +fi +rm -f conftestmake +fi +if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then + echo "$ac_t""yes" 1>&6 + SET_MAKE= +else + echo "$ac_t""no" 1>&6 + SET_MAKE="MAKE=${MAKE-make}" +fi + + +PACKAGE=eCos_synthetic_target_ethernet + +VERSION=0.1 + +if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then + { echo "configure: error: source directory already configured; run "make distclean" there first" 1>&2; exit 1; } +fi + + + +missing_dir=`cd $ac_aux_dir && pwd` +echo $ac_n "checking for working aclocal""... $ac_c" 1>&6 +echo "configure:763: checking for working aclocal" >&5 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (aclocal --version) < /dev/null > /dev/null 2>&1; then + ACLOCAL=aclocal + echo "$ac_t""found" 1>&6 +else + ACLOCAL="$missing_dir/missing aclocal" + echo "$ac_t""missing" 1>&6 +fi + +echo $ac_n "checking for working autoconf""... $ac_c" 1>&6 +echo "configure:776: checking for working autoconf" >&5 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (autoconf --version) < /dev/null > /dev/null 2>&1; then + AUTOCONF=autoconf + echo "$ac_t""found" 1>&6 +else + AUTOCONF="$missing_dir/missing autoconf" + echo "$ac_t""missing" 1>&6 +fi + +echo $ac_n "checking for working automake""... $ac_c" 1>&6 +echo "configure:789: checking for working automake" >&5 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (automake --version) < /dev/null > /dev/null 2>&1; then + AUTOMAKE=automake + echo "$ac_t""found" 1>&6 +else + AUTOMAKE="$missing_dir/missing automake" + echo "$ac_t""missing" 1>&6 +fi + +echo $ac_n "checking for working autoheader""... $ac_c" 1>&6 +echo "configure:802: checking for working autoheader" >&5 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (autoheader --version) < /dev/null > /dev/null 2>&1; then + AUTOHEADER=autoheader + echo "$ac_t""found" 1>&6 +else + AUTOHEADER="$missing_dir/missing autoheader" + echo "$ac_t""missing" 1>&6 +fi + +echo $ac_n "checking for working makeinfo""... $ac_c" 1>&6 +echo "configure:815: checking for working makeinfo" >&5 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (makeinfo --version) < /dev/null > /dev/null 2>&1; then + MAKEINFO=makeinfo + echo "$ac_t""found" 1>&6 +else + MAKEINFO="$missing_dir/missing makeinfo" + echo "$ac_t""missing" 1>&6 +fi + + +echo $ac_n "checking whether to enable maintainer-specific portions of Makefiles""... $ac_c" 1>&6 +echo "configure:829: checking whether to enable maintainer-specific portions of Makefiles" >&5 + # Check whether --enable-maintainer-mode or --disable-maintainer-mode was given. +if test "${enable_maintainer_mode+set}" = set; then + enableval="$enable_maintainer_mode" + USE_MAINTAINER_MODE=$enableval +else + USE_MAINTAINER_MODE=no +fi + + echo "$ac_t""$USE_MAINTAINER_MODE" 1>&6 + + +if test $USE_MAINTAINER_MODE = yes; then + MAINTAINER_MODE_TRUE= + MAINTAINER_MODE_FALSE='#' +else + MAINTAINER_MODE_TRUE='#' + MAINTAINER_MODE_FALSE= +fi + MAINT=$MAINTAINER_MODE_TRUE + + + +case "${host}" in + i[34567]86-*-linux-gnu* ) SUPPORTED="yes";; + * ) SUPPORTED="no" +esac + + +if test "${SUPPORTED}" = "yes"; then + SUPPORTED_TRUE= + SUPPORTED_FALSE='#' +else + SUPPORTED_TRUE='#' + SUPPORTED_FALSE= +fi + +if test "${SUPPORTED}" = "yes" ; then + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:870: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="gcc" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:900: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_prog_rejected=no + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + break + fi + done + IFS="$ac_save_ifs" +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# -gt 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + set dummy "$ac_dir/$ac_word" "$@" + shift + ac_cv_prog_CC="$@" + fi +fi +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$CC"; then + case "`uname -s`" in + *win32* | *WIN32*) + # Extract the first word of "cl", so it can be a program name with args. +set dummy cl; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:951: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="cl" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + ;; + esac + fi + test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } +fi + +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 +echo "configure:983: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +cat > conftest.$ac_ext << EOF + +#line 994 "configure" +#include "confdefs.h" + +main(){return(0);} +EOF +if { (eval echo configure:999: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + ac_cv_prog_cc_works=yes + # If we can't run a trivial program, we are probably using a cross compiler. + if (./conftest; exit) 2>/dev/null; then + ac_cv_prog_cc_cross=no + else + ac_cv_prog_cc_cross=yes + fi +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_cv_prog_cc_works=no +fi +rm -fr conftest* +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 +if test $ac_cv_prog_cc_works = no; then + { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } +fi +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 +echo "configure:1025: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 +cross_compiling=$ac_cv_prog_cc_cross + +echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 +echo "configure:1030: checking whether we are using GNU C" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.c <<EOF +#ifdef __GNUC__ + yes; +#endif +EOF +if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1039: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then + ac_cv_prog_gcc=yes +else + ac_cv_prog_gcc=no +fi +fi + +echo "$ac_t""$ac_cv_prog_gcc" 1>&6 + +if test $ac_cv_prog_gcc = yes; then + GCC=yes +else + GCC= +fi + +ac_test_CFLAGS="${CFLAGS+set}" +ac_save_CFLAGS="$CFLAGS" +CFLAGS= +echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 +echo "configure:1058: checking whether ${CC-cc} accepts -g" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + echo 'void f(){}' > conftest.c +if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then + ac_cv_prog_cc_g=yes +else + ac_cv_prog_cc_g=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 +if test "$ac_test_CFLAGS" = set; then + CFLAGS="$ac_save_CFLAGS" +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi + + for ac_prog in $CCC c++ g++ gcc CC cxx cc++ cl +do +# Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1094: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CXX'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CXX"; then + ac_cv_prog_CXX="$CXX" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CXX="$ac_prog" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CXX="$ac_cv_prog_CXX" +if test -n "$CXX"; then + echo "$ac_t""$CXX" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +test -n "$CXX" && break +done +test -n "$CXX" || CXX="gcc" + + +echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works""... $ac_c" 1>&6 +echo "configure:1126: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works" >&5 + +ac_ext=C +# CXXFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='${CXX-g++} -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cxx_cross + +cat > conftest.$ac_ext << EOF + +#line 1137 "configure" +#include "confdefs.h" + +int main(){return(0);} +EOF +if { (eval echo configure:1142: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + ac_cv_prog_cxx_works=yes + # If we can't run a trivial program, we are probably using a cross compiler. + if (./conftest; exit) 2>/dev/null; then + ac_cv_prog_cxx_cross=no + else + ac_cv_prog_cxx_cross=yes + fi +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_cv_prog_cxx_works=no +fi +rm -fr conftest* +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +echo "$ac_t""$ac_cv_prog_cxx_works" 1>&6 +if test $ac_cv_prog_cxx_works = no; then + { echo "configure: error: installation or configuration problem: C++ compiler cannot create executables." 1>&2; exit 1; } +fi +echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 +echo "configure:1168: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "$ac_t""$ac_cv_prog_cxx_cross" 1>&6 +cross_compiling=$ac_cv_prog_cxx_cross + +echo $ac_n "checking whether we are using GNU C++""... $ac_c" 1>&6 +echo "configure:1173: checking whether we are using GNU C++" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_gxx'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.C <<EOF +#ifdef __GNUC__ + yes; +#endif +EOF +if { ac_try='${CXX-g++} -E conftest.C'; { (eval echo configure:1182: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then + ac_cv_prog_gxx=yes +else + ac_cv_prog_gxx=no +fi +fi + +echo "$ac_t""$ac_cv_prog_gxx" 1>&6 + +if test $ac_cv_prog_gxx = yes; then + GXX=yes +else + GXX= +fi + +ac_test_CXXFLAGS="${CXXFLAGS+set}" +ac_save_CXXFLAGS="$CXXFLAGS" +CXXFLAGS= +echo $ac_n "checking whether ${CXX-g++} accepts -g""... $ac_c" 1>&6 +echo "configure:1201: checking whether ${CXX-g++} accepts -g" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_cxx_g'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + echo 'void f(){}' > conftest.cc +if test -z "`${CXX-g++} -g -c conftest.cc 2>&1`"; then + ac_cv_prog_cxx_g=yes +else + ac_cv_prog_cxx_g=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_prog_cxx_g" 1>&6 +if test "$ac_test_CXXFLAGS" = set; then + CXXFLAGS="$ac_save_CXXFLAGS" +elif test $ac_cv_prog_cxx_g = yes; then + if test "$GXX" = yes; then + CXXFLAGS="-g -O2" + else + CXXFLAGS="-g" + fi +else + if test "$GXX" = yes; then + CXXFLAGS="-O2" + else + CXXFLAGS= + fi +fi + +for ac_declaration in \ + ''\ + '#include <stdlib.h>' \ + 'extern "C" void std::exit (int) throw (); using std::exit;' \ + 'extern "C" void std::exit (int); using std::exit;' \ + 'extern "C" void exit (int) throw ();' \ + 'extern "C" void exit (int);' \ + 'void exit (int);' +do + cat > conftest.$ac_ext <<EOF +#line 1242 "configure" +#include "confdefs.h" +#include <stdlib.h> +$ac_declaration +int main() { +exit (42); +; return 0; } +EOF +if { (eval echo configure:1250: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + : +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + continue +fi +rm -f conftest* + cat > conftest.$ac_ext <<EOF +#line 1260 "configure" +#include "confdefs.h" +$ac_declaration +int main() { +exit (42); +; return 0; } +EOF +if { (eval echo configure:1267: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + break +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 +fi +rm -f conftest* +done +if test -n "$ac_declaration"; then + echo '#ifdef __cplusplus' >>confdefs.h + echo $ac_declaration >>confdefs.h + echo '#endif' >>confdefs.h +fi + + + echo $ac_n "checking for object suffix""... $ac_c" 1>&6 +echo "configure:1284: checking for object suffix" >&5 +if eval "test \"`echo '$''{'ac_cv_objext'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + rm -f conftest* +echo 'int i = 1;' > conftest.$ac_ext +if { (eval echo configure:1290: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + for ac_file in conftest.*; do + case $ac_file in + *.c) ;; + *) ac_cv_objext=`echo $ac_file | sed -e s/conftest.//` ;; + esac + done +else + { echo "configure: error: installation or configuration problem; compiler does not work" 1>&2; exit 1; } +fi +rm -f conftest* +fi + +echo "$ac_t""$ac_cv_objext" 1>&6 +OBJEXT=$ac_cv_objext +ac_objext=$ac_cv_objext + + echo $ac_n "checking for Cygwin environment""... $ac_c" 1>&6 +echo "configure:1308: checking for Cygwin environment" >&5 +if eval "test \"`echo '$''{'ac_cv_cygwin'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 1313 "configure" +#include "confdefs.h" + +int main() { + +#ifndef __CYGWIN__ +#define __CYGWIN__ __CYGWIN32__ +#endif +return __CYGWIN__; +; return 0; } +EOF +if { (eval echo configure:1324: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_cygwin=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_cygwin=no +fi +rm -f conftest* +rm -f conftest* +fi + +echo "$ac_t""$ac_cv_cygwin" 1>&6 +CYGWIN= +test "$ac_cv_cygwin" = yes && CYGWIN=yes +echo $ac_n "checking for mingw32 environment""... $ac_c" 1>&6 +echo "configure:1341: checking for mingw32 environment" >&5 +if eval "test \"`echo '$''{'ac_cv_mingw32'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 1346 "configure" +#include "confdefs.h" + +int main() { +return __MINGW32__; +; return 0; } +EOF +if { (eval echo configure:1353: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_mingw32=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_mingw32=no +fi +rm -f conftest* +rm -f conftest* +fi + +echo "$ac_t""$ac_cv_mingw32" 1>&6 +MINGW32= +test "$ac_cv_mingw32" = yes && MINGW32=yes + + +echo $ac_n "checking for executable suffix""... $ac_c" 1>&6 +echo "configure:1372: checking for executable suffix" >&5 +if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$CYGWIN" = yes || test "$MINGW32" = yes; then + ac_cv_exeext=.exe +else + rm -f conftest* + echo 'int main () { return 0; }' > conftest.$ac_ext + ac_cv_exeext= + if { (eval echo configure:1382: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then + for file in conftest.*; do + case $file in + *.c | *.o | *.obj) ;; + *) ac_cv_exeext=`echo $file | sed -e s/conftest//` ;; + esac + done + else + { echo "configure: error: installation or configuration problem: compiler cannot create executables." 1>&2; exit 1; } + fi + rm -f conftest* + test x"${ac_cv_exeext}" = x && ac_cv_exeext=no +fi +fi + +EXEEXT="" +test x"${ac_cv_exeext}" != xno && EXEEXT=${ac_cv_exeext} +echo "$ac_t""${ac_cv_exeext}" 1>&6 +ac_exeext=$EXEEXT + + + ecos_CFLAGS="" + ecos_CXXFLAGS="" + ecos_LDADD="" + ecos_INCLUDES="" + ecos_LIBS="" + + + + + + + + + + + + echo $ac_n "checking "for Visual C++"""... $ac_c" 1>&6 +echo "configure:1420: checking "for Visual C++"" >&5 + MSVC="no"; + if test "${CC}" = "cl" ; then + MSVC="yes" + CXX="cl" + + + + if test "${MSVC}" = "yes" ; then + MSVC_SRCDIR=`cygpath -w ${MSVC_SRCDIR} | tr \\\\\\\\ /` + fi + + + ecos_INCLUDES="${ecos_INCLUDES} \"-I${msvc_srcdir}\"" + ecos_LDADD="-link" + ecos_LIBS="advapi32.lib" + fi + + +if test "${MSVC}" = "yes"; then + MSVC_TRUE= + MSVC_FALSE='#' +else + MSVC_TRUE='#' + MSVC_FALSE= +fi + if test "${MSVC}" = "yes" ; then + echo "$ac_t""unfortunately yes" 1>&6 + else + echo "$ac_t""no" 1>&6 + fi + + + + + + + + echo $ac_n "checking "the default compiler flags"""... $ac_c" 1>&6 +echo "configure:1459: checking "the default compiler flags"" >&5 + + ecosflags_enable_debug="no" + # Check whether --enable-debug or --disable-debug was given. +if test "${enable_debug+set}" = set; then + enableval="$enable_debug" + case "${enableval}" in + yes) ecosflags_enable_debug="yes" ;; + *) ecosflags_enable_debug="no" ;; + esac +fi + + + ecosflags_enable_ansi="no" + if test "${MSVC}" = "yes" ; then + # Check whether --enable-ansi or --disable-ansi was given. +if test "${enable_ansi+set}" = set; then + enableval="$enable_ansi" + case "${enableval}" in + yes) ecosflags_enable_ansi="yes" ;; + *) ecosflags_enable_ansi="no" ;; + esac +fi + + fi + + if test "${GCC}" = "yes" ; then + ecos_CFLAGS="${ecos_CFLAGS} -pipe -Wall -Wpointer-arith -Wbad-function-cast -Wcast-qual -Wstrict-prototypes -Wmissing-prototypes -Wnested-externs" + ecos_CXXFLAGS="${ecos_CXXFLAGS} -pipe -Wall -Wpointer-arith -Wbad-function-cast -Wcast-qual -Wstrict-prototypes -Wmissing-prototypes -Wnested-externs -Woverloaded-virtual" + elif test "${MSVC}" = "yes" ; then + ecos_CFLAGS="${ecos_CFLAGS} -nologo -W3" + ecos_CXXFLAGS="${ecos_CXXFLAGS} -nologo -W3 -GR -GX" + else + { echo "configure: error: "default flags for ${CC} are not known"" 1>&2; exit 1; } + fi + + if test "${ecosflags_enable_debug}" = "yes" ; then + if test "${GCC}" = "yes" ; then + ecos_CFLAGS="${ecos_CFLAGS} -g -O0" + ecos_CXXFLAGS="${ecos_CXXFLAGS} -g -O0" + elif test "${MSVC}" = "yes" ; then + ecos_CFLAGS="${ecos_CFLAGS} -MDd -Zi" + ecos_CXXFLAGS="${ecos_CXXFLAGS} -MDd -Zi" + fi + else + if test "${GCC}" = "yes" ; then + ecos_CFLAGS="${ecos_CFLAGS} -O0" + ecos_CXXFLAGS="${ecos_CXXFLAGS} -O0" + elif test "${MSVC}" = "yes" ; then + ecos_CFLAGS="${ecos_CFLAGS} -MD -O2" + ecos_CXXFLAGS="${ecos_CXXFLAGS} -MD -O2" + fi + fi + + CFLAGS="${ac_save_CFLAGS}" + CXXFLAGS="${ac_save_CXXFLAGS}" + + echo "$ac_t""done" 1>&6 + + + + + + + + ecos_tcl_version="" + ecos_tcl_incdir="" + ecos_tcl_libdir="" + ecos_tk_libs="" + + + echo $ac_n "checking for Tcl version""... $ac_c" 1>&6 +echo "configure:1531: checking for Tcl version" >&5 + # Check whether --with-tcl-version or --without-tcl-version was given. +if test "${with_tcl_version+set}" = set; then + withval="$with_tcl_version" + + ecos_tcl_version=${with_tcl_version} + +else + + if test "${MSVC}" = "yes" ; then + ecos_tcl_version=80 + elif test "${ac_cv_cygwin}" = "yes" ; then + ecos_tcl_version=80 + else + ecos_tcl_version="" + fi + +fi + + echo "$ac_t""${ecos_tcl_version}" 1>&6 + + echo $ac_n "checking for Tcl installation""... $ac_c" 1>&6 +echo "configure:1553: checking for Tcl installation" >&5 + + # Check whether --with-tcl-header or --without-tcl-header was given. +if test "${with_tcl_header+set}" = set; then + withval="$with_tcl_header" + : +fi + + # Check whether --with-tcl-lib or --without-tcl-lib was given. +if test "${with_tcl_lib+set}" = set; then + withval="$with_tcl_lib" + : +fi + + # Check whether --with-tcl or --without-tcl was given. +if test "${with_tcl+set}" = set; then + withval="$with_tcl" + : +fi + + + + if test "${MSVC}" = "yes" ; then + + if test "${with_tcl_header+set}" = set ; then + ecos_tcl_incdir=${with_tcl_header} + elif test "${with_tcl+set}" = set ; then + ecos_tcl_incdir="${with_tcl}/include" + else + { echo "configure: error: You must specify a Tcl installation with either --with-tcl=<path> or --with-tcl-header=<path>" 1>&2; exit 1; } + fi + + if test \! -r "${ecos_tcl_incdir}/tcl.h" ; then + { echo "configure: error: unable to locate Tcl header file tcl.h" 1>&2; exit 1; } + fi + ecos_msvc_tcl_incdir="${ecos_tcl_incdir}" + + + + if test "${MSVC}" = "yes" ; then + ecos_msvc_tcl_incdir=`cygpath -w ${ecos_msvc_tcl_incdir} | tr \\\\\\\\ /` + fi + + ecos_INCLUDES="${ecos_INCLUDES} \"-I${ecos_msvc_tcl_incdir}\"" + + if test "${with_tcl_lib+set}" = set; then + ecos_tcl_libdir=${with_tcl_lib} + elif test "${with_tcl+set}" = set; then + ecos_tcl_libdir="${with_tcl}/lib" + else + { echo "configure: error: You must specify a Tcl installation with either --with-tcl=<path> or --with-tcl-lib=<path>" 1>&2; exit 1; } + fi + + + + if test "${MSVC}" = "yes" ; then + ecos_tcl_libdir=`cygpath -w ${ecos_tcl_libdir} | tr \\\\\\\\ /` + fi + + ecos_LIBS="${ecos_LIBS} tcl${ecos_tcl_version}.lib" + ecos_LDADD="${ecos_LDADD} \"-libpath=${ecos_tcl_libdir}\"" + + ecos_tk_libs="" + + else + possibles="${with_tcl_header} ${with_tcl}/include ${prefix}/include /usr/include/tcl${ecos_tcl_version} /usr/include" + + ecos_tcl_incdir="" + for i in ${possibles}; do + if test -r "$i/"tcl.h""; then + ecos_tcl_incdir=$i + break + fi + done + + if test \! -r "${ecos_tcl_incdir}/tcl.h" ; then + { echo "configure: error: unable to locate Tcl header file tcl.h" 1>&2; exit 1; } + else + if test "${ecos_tcl_incdir}" != "/usr/include" ; then + ecos_INCLUDES="${ecos_INCLUDES} -I${ecos_tcl_incdir}" + fi + fi + possibles="${with_tcl_lib} ${with_tcl}/lib ${libdir} ${prefix}/lib /usr/lib/tcl$${ecos_tcl_version} /usr/lib" + + ecos_tcl_libdir="" + for i in ${possibles}; do + if test -r "$i/"tclConfig.sh""; then + ecos_tcl_libdir=$i + break + fi + done + + if test \! -r "${ecos_tcl_libdir}/tclConfig.sh" ; then + { echo "configure: error: unable to locate Tcl config file tclConfig.sh" 1>&2; exit 1; } + else + . ${ecos_tcl_libdir}/tclConfig.sh + ecos_LIBS="${ecos_LIBS} -ltcl${ecos_tcl_version} ${TCL_LIBS}" + fi + + possible_tk_libdir=`echo ${ecos_tcl_libdir} | sed -e 's,tcl,tk,'` + possibles="${ecos_tcl_libdir} ${possible_tk_libdir}" + + ecos_tk_libdir="" + for i in ${possibles}; do + if test -r "$i/"tkConfig.sh""; then + ecos_tk_libdir=$i + break + fi + done + + if test \! -r "${ecos_tk_libdir}/tkConfig.sh" ; then + { echo "configure: error: unable to locate Tk config file tkConfig.sh" 1>&2; exit 1; } + else + . ${ecos_tk_libdir}/tkConfig.sh + ecos_tk_libs="-ltk${ecos_tcl_version} ${TK_LIBS}" + for lib in ${TCL_LIBS} ; do + ecos_tk_libs=`echo ${ecos_tk_libs} | sed -e "s!${lib}!!"` + done + fi + fi + + echo "$ac_t""-I${ecos_tcl_incdir} -L${ecos_tcl_libdir}" 1>&6 + + + + if test "${TK_MAJOR_VERSION}" = "8" ; then + if test ${TK_MINOR_VERSION} -lt 3 ; then + { echo "configure: error: The synthetic target ethernet support requires at least version 8.3 of Tcl/Tk" 1>&2; exit 1; } + fi + fi + + + package_dir=`cd ${srcdir} && /bin/pwd` + PACKAGE_VERSION=`dirname ${package_dir}` + PACKAGE_VERSION=`basename ${PACKAGE_VERSION}` + + package_dir=`dirname ${package_dir}` + package_dir=`dirname ${package_dir}` + + possibles="${package_dir}/.. ${package_dir}/../.. ${package_dir}/../../.. ${package_dir}/../../../.." + possibles="${possibles} ${package_dir}/../../../../.. ${package_dir}/../../../../../.." + + repository_root="" + for i in ${possibles}; do + if test -d "$i/"acsupport""; then + repository_root=$i + break + fi + done + + if test "${repository_root}" = "" ; then + { echo "configure: error: Failed to identify this package's position within the eCos repository" 1>&2; exit 1; } + fi + ECOS_REPOSITORY=`cd "${repository_root}/packages/pkgconf/.." && /bin/pwd` + + PACKAGE_DIR=`echo ${package_dir} | sed -e "s:${ECOS_REPOSITORY}/::"` + + PACKAGE_INSTALL="${PACKAGE_DIR}/${PACKAGE_VERSION}" + + + + + + +fi + + +trap '' 1 2 15 +cat > confcache <<\EOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs. It is not useful on other systems. +# If it contains results you don't want to keep, you may remove or edit it. +# +# By default, configure uses ./config.cache as the cache file, +# creating it if it does not exist already. You can give configure +# the --cache-file=FILE option to use a different cache file; that is +# what configure does when it calls configure scripts in +# subdirectories, so they share the cache. +# Giving --cache-file=/dev/null disables caching, for debugging configure. +# config.status only pays attention to the cache file if you give it the +# --recheck option to rerun configure. +# +EOF +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +(set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote substitution + # turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + -e "s/'/'\\\\''/g" \ + -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' + ;; + esac >> confcache +if cmp -s $cache_file confcache; then + : +else + if test -w $cache_file; then + echo "updating cache $cache_file" + cat confcache > $cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# Any assignment to VPATH causes Sun make to only execute +# the first set of double-colon rules, so remove it if not needed. +# If there is a colon in the path, we need to keep it. +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' +fi + +trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 + +# Transform confdefs.h into DEFS. +# Protect against shell expansion while executing Makefile rules. +# Protect against Makefile macro expansion. +cat > conftest.defs <<\EOF +s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g +s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g +s%\[%\\&%g +s%\]%\\&%g +s%\$%$$%g +EOF +DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '` +rm -f conftest.defs + + +# Without the "./", some shells look in PATH for config.status. +: ${CONFIG_STATUS=./config.status} + +echo creating $CONFIG_STATUS +rm -f $CONFIG_STATUS +cat > $CONFIG_STATUS <<EOF +#! /bin/sh +# Generated automatically by configure. +# Run this file to recreate the current configuration. +# This directory was configured as follows, +# on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# +# $0 $ac_configure_args +# +# Compiler output produced by configure, useful for debugging +# configure, is in ./config.log if it exists. + +ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" +for ac_option +do + case "\$ac_option" in + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" + exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; + -version | --version | --versio | --versi | --vers | --ver | --ve | --v) + echo "$CONFIG_STATUS generated by autoconf version 2.13" + exit 0 ;; + -help | --help | --hel | --he | --h) + echo "\$ac_cs_usage"; exit 0 ;; + *) echo "\$ac_cs_usage"; exit 1 ;; + esac +done + +ac_given_srcdir=$srcdir +ac_given_INSTALL="$INSTALL" + +trap 'rm -fr `echo "Makefile:Makefile.in" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 +EOF +cat >> $CONFIG_STATUS <<EOF + +# Protect against being on the right side of a sed subst in config.status. +sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g; + s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF +$ac_vpsub +$extrasub +s%@SHELL@%$SHELL%g +s%@CFLAGS@%$CFLAGS%g +s%@CPPFLAGS@%$CPPFLAGS%g +s%@CXXFLAGS@%$CXXFLAGS%g +s%@FFLAGS@%$FFLAGS%g +s%@DEFS@%$DEFS%g +s%@LDFLAGS@%$LDFLAGS%g +s%@LIBS@%$LIBS%g +s%@exec_prefix@%$exec_prefix%g +s%@prefix@%$prefix%g +s%@program_transform_name@%$program_transform_name%g +s%@bindir@%$bindir%g +s%@sbindir@%$sbindir%g +s%@libexecdir@%$libexecdir%g +s%@datadir@%$datadir%g +s%@sysconfdir@%$sysconfdir%g +s%@sharedstatedir@%$sharedstatedir%g +s%@localstatedir@%$localstatedir%g +s%@libdir@%$libdir%g +s%@includedir@%$includedir%g +s%@oldincludedir@%$oldincludedir%g +s%@infodir@%$infodir%g +s%@mandir@%$mandir%g +s%@host@%$host%g +s%@host_alias@%$host_alias%g +s%@host_cpu@%$host_cpu%g +s%@host_vendor@%$host_vendor%g +s%@host_os@%$host_os%g +s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g +s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g +s%@INSTALL_DATA@%$INSTALL_DATA%g +s%@PACKAGE@%$PACKAGE%g +s%@VERSION@%$VERSION%g +s%@ACLOCAL@%$ACLOCAL%g +s%@AUTOCONF@%$AUTOCONF%g +s%@AUTOMAKE@%$AUTOMAKE%g +s%@AUTOHEADER@%$AUTOHEADER%g +s%@MAKEINFO@%$MAKEINFO%g +s%@SET_MAKE@%$SET_MAKE%g +s%@MAINTAINER_MODE_TRUE@%$MAINTAINER_MODE_TRUE%g +s%@MAINTAINER_MODE_FALSE@%$MAINTAINER_MODE_FALSE%g +s%@MAINT@%$MAINT%g +s%@SUPPORTED_TRUE@%$SUPPORTED_TRUE%g +s%@SUPPORTED_FALSE@%$SUPPORTED_FALSE%g +s%@CC@%$CC%g +s%@CXX@%$CXX%g +s%@OBJEXT@%$OBJEXT%g +s%@EXEEXT@%$EXEEXT%g +s%@ecos_CFLAGS@%$ecos_CFLAGS%g +s%@ecos_CXXFLAGS@%$ecos_CXXFLAGS%g +s%@ecos_LDADD@%$ecos_LDADD%g +s%@ecos_INCLUDES@%$ecos_INCLUDES%g +s%@ecos_LIBS@%$ecos_LIBS%g +s%@MSVC_SRCDIR@%$MSVC_SRCDIR%g +s%@MSVC_TRUE@%$MSVC_TRUE%g +s%@MSVC_FALSE@%$MSVC_FALSE%g +s%@ecos_tk_libs@%$ecos_tk_libs%g +s%@ECOS_REPOSITORY@%$ECOS_REPOSITORY%g +s%@PACKAGE_DIR@%$PACKAGE_DIR%g +s%@PACKAGE_VERSION@%$PACKAGE_VERSION%g +s%@PACKAGE_INSTALL@%$PACKAGE_INSTALL%g + +CEOF +EOF + +cat >> $CONFIG_STATUS <<\EOF + +# Split the substitutions into bite-sized pieces for seds with +# small command number limits, like on Digital OSF/1 and HP-UX. +ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. +ac_file=1 # Number of current file. +ac_beg=1 # First line for current file. +ac_end=$ac_max_sed_cmds # Line after last line for current file. +ac_more_lines=: +ac_sed_cmds="" +while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file + else + sed "${ac_end}q" conftest.subs > conftest.s$ac_file + fi + if test ! -s conftest.s$ac_file; then + ac_more_lines=false + rm -f conftest.s$ac_file + else + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f conftest.s$ac_file" + else + ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" + fi + ac_file=`expr $ac_file + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_cmds` + fi +done +if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat +fi +EOF + +cat >> $CONFIG_STATUS <<EOF + +CONFIG_FILES=\${CONFIG_FILES-"Makefile:Makefile.in"} +EOF +cat >> $CONFIG_STATUS <<\EOF +for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. + + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" + # A "../" for each directory in $ac_dir_suffix. + ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` + else + ac_dir_suffix= ac_dots= + fi + + case "$ac_given_srcdir" in + .) srcdir=. + if test -z "$ac_dots"; then top_srcdir=. + else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; + /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; + *) # Relative path. + srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" + top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + + case "$ac_given_INSTALL" in + [/$]*) INSTALL="$ac_given_INSTALL" ;; + *) INSTALL="$ac_dots$ac_given_INSTALL" ;; + esac + + echo creating "$ac_file" + rm -f "$ac_file" + configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." + case "$ac_file" in + *Makefile*) ac_comsub="1i\\ +# $configure_input" ;; + *) ac_comsub= ;; + esac + + ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` + sed -e "$ac_comsub +s%@configure_input@%$configure_input%g +s%@srcdir@%$srcdir%g +s%@top_srcdir@%$top_srcdir%g +s%@INSTALL@%$INSTALL%g +" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file +fi; done +rm -f conftest.s* + +EOF +cat >> $CONFIG_STATUS <<EOF + +EOF +cat >> $CONFIG_STATUS <<\EOF + +exit 0 +EOF +chmod +x $CONFIG_STATUS +rm -fr confdefs* $ac_clean_files +test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 +
new file mode 100644 --- /dev/null +++ b/packages/devs/eth/synth/ecosynth/current/host/configure.in @@ -0,0 +1,92 @@ +dnl Process this file with autoconf to produce a configure script. +dnl ==================================================================== +dnl +dnl configure.in +dnl +dnl configure script for eCos synthetic target ethernet +dnl host-side support +dnl +dnl ==================================================================== +dnl####COPYRIGHTBEGIN#### +dnl +dnl ---------------------------------------------------------------------------- +dnl Copyright (C) 2002 Bart Veer +dnl +dnl This file is part of the eCos synthetic target support. +dnl +dnl This program is free software; you can redistribute it and/or modify it +dnl under the terms of the GNU General Public License as published by the Free +dnl Software Foundation; either version 2 of the License, or (at your option) +dnl any later version. +dnl +dnl This program is distributed in the hope that it will be useful, but WITHOUT +dnl ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +dnl FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +dnl more details. +dnl +dnl You should have received a copy of the GNU General Public License along with +dnl this program; if not, write to the Free Software Foundation, Inc., +dnl 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +dnl ---------------------------------------------------------------------------- +dnl +dnl####COPYRIGHTEND#### +dnl ==================================================================== +dnl#####DESCRIPTIONBEGIN#### +dnl +dnl Author(s): bartv +dnl Contact(s): bartv +dnl Date: 2002/08/07 +dnl Version: 0.01 +dnl +dnl####DESCRIPTIONEND#### +dnl ==================================================================== + + +AC_INIT(rawether.c) + +dnl Pick up the support files from the top-level acsupport directory. +AC_CONFIG_AUX_DIR(../../../../../../../acsupport) + +ECOS_CHECK_BUILD_ne_SRC +AC_CANONICAL_HOST +AM_INIT_AUTOMAKE(eCos_synthetic_target_ethernet,0.1,0) +AM_MAINTAINER_MODE + +dnl The current version of the synthetic target is implemented only for +dnl x86 Linux platforms, so a test is appropriate here. However +dnl it is not a good idea for the configure script to report an error: +dnl that would prevent any top-level configury working for other +dnl platforms. Instead an automake conditional is used to suppress adding +dnl targets to the build. +case "${host}" in + i[[34567]]86-*-linux-gnu* ) SUPPORTED="yes";; + * ) SUPPORTED="no" +esac +AM_CONDITIONAL(SUPPORTED, test "${SUPPORTED}" = "yes") + +if test "${SUPPORTED}" = "yes" ; then + AC_PROG_CC + AC_PROG_CXX + AC_OBJEXT + AC_EXEEXT + ECOS_PROG_MSVC + ECOS_PROG_STANDARD_COMPILER_FLAGS + + ECOS_PATH_TCL + dnl Check that the version of tk is sufficiently recent. + dnl For example the text widget's tag -elide facility was + dnl added between 8.2 and 8.3. Initial development of + dnl the synthetic target used 8.3.1 + if test "${TK_MAJOR_VERSION}" = "8" ; then + if test ${TK_MINOR_VERSION} -lt 3 ; then + AC_MSG_ERROR([The synthetic target ethernet support requires at least version 8.3 of Tcl/Tk]) + fi + fi + ECOS_PACKAGE_DIRS +fi + +dnl There is no real need for a config.h file at this time, since the code +dnl is specific to x86 Linux. This may change in future. +dnl AM_CONFIG_HEADER(config.h:config.h.in) + +AC_OUTPUT(Makefile:Makefile.in)
new file mode 100644 --- /dev/null +++ b/packages/devs/eth/synth/ecosynth/current/host/ethernet.tcl @@ -0,0 +1,1226 @@ +# {{{ Banner + +# ============================================================================ +# +# ethernet.tcl +# +# Ethernet support for the eCos synthetic target I/O auxiliary +# +# ============================================================================ +# ####COPYRIGHTBEGIN#### +# +# ---------------------------------------------------------------------------- +# Copyright (C) 2002 Bart Veer +# +# This file is part of the eCos host tools. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the Free +# Software Foundation; either version 2 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, write to the Free Software Foundation, Inc., +# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# ---------------------------------------------------------------------------- +# +# ####COPYRIGHTEND#### +# ============================================================================ +# #####DESCRIPTIONBEGIN#### +# +# Author(s): bartv +# Contact(s): bartv +# Date: 2002/08/07 +# Version: 0.01 +# Description: +# Implementation of the ethernet device. This script should only ever +# be run from inside the ecosynth auxiliary. +# +# ####DESCRIPTIONEND#### +# ============================================================================ + +# }}} + +# Overview. +# +# Linux provides a number of different ways of performing low-level +# ethernet I/O from user space, including accessing an otherwise +# unused ethernet card via a PF_PACKET socket, and the tap facility. +# The necessary functionality is not readily accessible from Tcl, +# and performing this low-level I/O generally requires special +# privileges. Therefore the actual I/O happens in a C program +# rawether, installed suid root, +# +# The synthetic ethernet package supports up to four ethernet devices, +# eth0 to eth3. The target definition file maps these onto the +# underlying I/O facility. Instantiation requires spawning a rawether +# process with appropriate arguments, and then waiting for a message +# from that process indicating whether or not the instantiation +# succeeded. That message includes the MAC address. A file event +# handler is installed to handle data detected by raw ether. +# +# eCos can send a number of requests: transmit a packet, start the +# interface (possibly in promiscuous mode), stop the interface, +# or get the various parameters such as the MAC address. All those +# requests can just be passed on to the rawether process. Incoming +# ethernet packets are slightly more complicated: rawether will +# immediately pass these up to this Tcl script, which will buffer +# the packets until they are requested by eCos; in addition an +# interrupt will be raised. + +namespace eval ethernet { + # The protocol between eCos and this script. + variable SYNTH_ETH_TX 0x01 + variable SYNTH_ETH_RX 0x02 + variable SYNTH_ETH_START 0x03 + variable SYNTH_ETH_STOP 0x04 + variable SYNTH_ETH_GETPARAMS 0x05 + variable SYNTH_ETH_MULTIALL 0x06 + + # This array holds all the interesting data for all the + # interfaces, indexed by the instance id. It is also useful + # to keep track of the instance id's associated with ethernet + # devices. + array set data [list] + set ids [list] + + # One-off initialization, for example loading images. If this fails + # then all attempts at instantiation will fail as well. + variable init_ok 1 + variable install_dir $synth::device_install_dir + variable rawether_executable [file join $ethernet::install_dir "rawether"] + + if { ![file exists $rawether_executable] } { + synth::report_error "Ethernet device, rawether executable has not been installed in $ethernet::install_dir.\n" + set init_ok 0 + } elseif { ![file executable $rawether_executable] } { + synth::report_error "Ethernet device, installed program $rawether_executable is not executable.\n" + set init_ok 0 + } + + if { $synth::flag_gui } { + foreach _image [list "netrecord.xbm"] { + variable image_[file rootname $_image] + if { ! [synth::load_image "ethernet::image_[file rootname $_image]" [file join $ethernet::install_dir $_image]] } { + set init_ok 0 + } + } + unset _image + } + + # Maximum number of packets that should be buffered per interface. + # This can be changed in the target definition + variable max_buffered_packets 16 + + if { [synth::tdf_has_option "ethernet" "max_buffer"] } { + set ethernet::max_buffered_packets [synth::tdf_get_option "ethernet" "max_buffer"] + if { ![string is integer -strict $ethernet::max_buffered_packets] } { + synth::report_error "Ethernet device, invalid value in target definition file $synth::target_definition\n \ + Entry max_buffer should be a simple integer, not $ethernet::max_buffered_packets\n" + set init_ok 0 + } + } + + # Define hooks for tx and rx packets + synth::hook_define "ethernet_tx" + synth::hook_define "ethernet_rx" + + # Get a list of known ethernet devices + proc devices_get_list { } { + set result [list] + foreach id $ids { + lappend result $::ethernet::data($id,name) + } + return $result + } + + # ---------------------------------------------------------------------------- + proc instantiate { id name data } { + if { ! $ethernet::init_ok } { + synth::report_warning "Cannot instantiate ethernet device $name, initialization failed.\n" + return "" + } + + # id is a small number that uniquely identifies this device. It will + # be used as an array index. + # name is something like eth0 or eth1 + # There should be no device-specific data + + # The hard work is done by an auxiliary process which needs to be + # spawned off. It requires some additional information to map the + # eCos device name on to a suitable Linux network device such + # as tap0. That information has to come from the config file. + if { ![synth::tdf_has_option "ethernet" $name] } { + synth::report_error "Cannot instantiate ethernet device $name\n \ + No entry in target definition file $synth::target_definition\n" + return "" + } + set use [synth::tdf_get_option "ethernet" $name] + + # Do some validation here, before the rawether process is started. + # Typical entries would look like + # eth0 real eth1 + # eth1 ethertap [[tap-device] [MAC]] + set junk "" + set optional "" + set mac "" + if { [regexp -- {^\s*real\s*[a-zA-z0-9_]+$} $use] } { + # Real ethernet. + } elseif { [regexp -- {^\s*ethertap\s*(.*)$} $use junk optional ] } { + if { "" != $optional } { + if { ! [regexp -- {^tap[0-9]+\s*(.*)$} $optional junk mac ] } { + synth::report_error "Cannot instantiate ethernet device $name\n \ + Invalid entry \"$use\" in target definition file $synth::target_definition\n \ + Should be \"ethertap \[<tap-device> \[<MAC address>\]\]\"\n" + return "" + } + if { "" != $mac } { + if { ! [regexp -- {^\s*([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}\s*} $mac ] } { + synth::report_error "Cannot instantiate ethernet device $name\n \ + Invalid entry \"$use\" in target definition file $synth::target_definition\n \ + MAC address should be of the form xx:xx:xx:xx:xx:xx, all hexadecimal digits.\n" + return "" + } + } + } + } else { + synth::report_error "Cannot instantiate ethernet device $name\n \ + Invalid entry \"$use\" in target definition file $synth::target_definition\n \ + Should be \"real <Linux ethernet device>\" or \"ethertap \[<tap-device> \[<MAC address>\]\]\"\n" + return "" + } + + # Now spawn the rawether process. Its stdin and stdout are + # pipes connected to ecosynth. Its stderr is redirected to + # the current tty to avoid confusion between incoming ethernet + # packets and diagnostics. + if { [catch { set rawether [open "|$ethernet::rawether_executable $use 2>/dev/tty" w+] } message ] } { + synth::report_error "Failed to spawn rawether process for device $name\n $message" + return "" + } + + # No translation on this pipe please. + fconfigure $rawether -translation binary -encoding binary -buffering none + + # Now wait for the rawether device to initialize. It should send back a single + # byte, '0' for failure or '1' for success. Failure is followed by a text + # message which should be reported. Success is followed by a six-byte MAC + # address. + set reply [read $rawether 1] + if { "" == $reply } { + synth::report_error "rawether process for device $name exited unexpectedly.\n" + catch { close $rawether } + return "" + } + + if { "1" != $reply } { + set message [read $rawether 1024] + synth::report_error "rawether process was unable to initialize eCos device $name ($use)\n $message" + catch { close $rawether } + return "" + } + + set reply [read $rawether 7] + if { [string length $reply] != 7 } { + synth::report_error "rawether process for eCos device $name ($use) failed to provide the initialization response.\n" + catch { close $rawether } + return "" + } + set mac [string range $reply 0 5] + set multi [string index $reply 6] + + # Finally allocate an interrupt vector + set vector [synth::interrupt_allocate $name] + if { -1 == $vector } { + # No more interrupts left. An error will have been reported already. + catch { close $rawether } + return "" + } + + # The device is up and running. Fill in the array entries + lappend ethernet::ids $id + set ethernet::data($id,alive) 1 + set ethernet::data($id,name) $name + set ethernet::data($id,rawether) $rawether + set ethernet::data($id,packets) [list] + set ethernet::data($id,packet_count) 0 + set ethernet::data($id,up) 0 + set ethernet::data($id,interrupt_vector) $vector + set ethernet::data($id,MAC) $mac + set ethernet::data($id,multi) $multi + + # Set up the event handler to handle incoming packets. There should + # not be any until the interface is brought up + fileevent $rawether readable [list ethernet::handle_packet $name $id $rawether] + + # Finally return the request handler. The eCos device driver will + # automatically get back an ack. + return ethernet::handle_request + } + + # ---------------------------------------------------------------------------- + # eCos has sent a request to a device instance. Most of these requests should + # just be forwarded to rawether. Some care has to be taken to preserve + # packet boundaries and avoid confusion. It is also necessary to worry + # about the rawether process exiting unexpectedly, which may cause + # puts operations to raise an error (subject to buffering). + # + # Note: it might actually be more efficient to always send a header plus + # 1514 bytes of data, reducing the number of system calls at the cost of + # some extra data copying, but with at least two process switches per + # ethernet transfer efficiency is not going to be particularly good + # anyway. + + proc send_rawether { id packet } { + if { $ethernet::data($id,alive) } { + set chan $ethernet::data($id,rawether) + if { [catch { puts -nonewline $chan $packet } ] } { + set ethernet::data($id,alive) 0 + # No further action is needed here, instead the read handler + # will detect EOF and report abnormal termination. + } + } + } + + proc handle_request { id reqcode arg1 arg2 reqdata reqlen reply_len } { + + if { $reqcode == $ethernet::SYNTH_ETH_TX } { + # Transmit a single packet. To preserve packet boundaries + # this involves a four-byte header containing opcode and + # size, followed by the data itself. + set header [binary format "ccs" $reqcode 0 [string length $reqdata]] + ethernet::send_rawether $id $header + ethernet::send_rawether $id $reqdata + if { $ethernet::logging_enabled } { + ethernet::log_packet $ethernet::data($id,name) "tx" $reqdata + } + synth::hook_call "ethernet_tx" $ethernet::data($id,name) $reqdata + + } elseif { $reqcode == $ethernet::SYNTH_ETH_RX } { + # Return a single packet to eCos, plus a count of the number + # of remaining packets. All packets are buffered here, not + # in rawether. + if { $ethernet::data($id,packet_count) == 0 } { + synth::send_reply 0 0 "" + } else { + incr ethernet::data($id,packet_count) -1 + set packet [lindex $ethernet::data($id,packets) 0] + set ethernet::data($id,packets) [lrange $ethernet::data($id,packets) 1 end] + synth::send_reply $ethernet::data($id,packet_count) [string length $packet] $packet + if { $ethernet::logging_enabled } { + ethernet::log_packet $ethernet::data($id,name) "rx" $packet + } + synth::hook_call "ethernet_rx" $ethernet::data($id,name) $packet + } + } elseif { $reqcode == $ethernet::SYNTH_ETH_START } { + # Start the interface in either normal or promiscuous + # mode, depending on arg1. No reply is expected. Also + # mark the interface as up so that any packets transmitted + # by rawether will not be discarded + set ethernet::data($id,up) 1 + set header [binary format "ccs" $reqcode $arg1 0] + ethernet::send_rawether $id $header + } elseif { $reqcode == $ethernet::SYNTH_ETH_STOP } { + # Stop the interface. All pending packets should be + # discarded and no new packets should be accepted. + # No reply is expected so just pass this on to rawether + set ethernet::data($id,up) 0 + set ethernet::data($id,packets) [list] + set ethernet::data($id,packet_count) 0 + set header [binary format "ccs" $reqcode 0 0] + ethernet::send_rawether $id $header + } elseif { $reqcode == $ethernet::SYNTH_ETH_GETPARAMS } { + # Retrieve the interrupt number, the MAC address, + # and the multicast flag for this interface. eCos should be + # expecting back 6 bytes of data for the MAC, plus an + # extra byte for the multi flag, and the interrupt + # number as the return code. This is all known locally. + set reply "$ethernet::data($id,MAC)$ethernet::data($id,multi)" + synth::send_reply $ethernet::data($id,interrupt_vector) 7 $reply + } elseif { $reqcode == $ethernet::SYNTH_ETH_MULTIALL } { + set header [binary format "ccs" $reqcode $arg1 0] + ethernet::send_rawether $id $header + } else { + synth::report_error "Received unexpected request $reqcode for ethernet device" + } + } + + # ---------------------------------------------------------------------------- + # Incoming data. + # + # The rawether process continually reads packets from the low-level device + # and tries to forward them on to this script, where they will be received + # by an event handler. The packet consists of a four-byte header containing + # the size, followed by the ethernet data itself. This ensures that + # packet boundaries are preserved. Incoming packets are buffered inside + # the auxiliary until eCos sends an RX request, and an interrupt is + # generated. + # + # If eCos stops accepting data or if it cannot process the ethernet packets + # quickly enough then the auxiliary could end up buffering an unbounded + # amount of data. That is a bad idea, so there is an upper bound on the + # number of buffered packets. Any excess packets get dropped. + # + # Error conditions or EOF indicate that rawether has terminated. This + # should not happen during normal operation. rawether should only exit + # because of an ecos_exit hook when the channel gets closed, and the + # event handler gets removed first. + # + # Incoming packets are logged when they are received by eCos, not when + # they are received from the rawether device. That gives a somewhat more + # accurate view of what is happening inside eCos - a packet stuck in + # a fifo has little impact. + proc _handle_packet_error { msg id } { + append msg " No further I/O will happen on this interface.\n" + synth::report_warning $msg + set ethernet::data($id,alive) 0 + fileevent $ethernet::data($id,rawether) readable "" + catch { close $ethernet::data($id,rawether) } + } + + proc handle_packet { name id chan } { + set header [read $chan 4] + if { 4 != [string length $header] } { + ethernet::_handle_packet_error "rawether process for $name has terminated unexpectedly.\n" $id + return + } + + binary scan $header "ccs" code arg1 len + if { $ethernet::SYNTH_ETH_RX != $code } { + set msg "protocol mismatch from rawether process for $name\n" + append msg " Function code $code not recognised.\n" + ethernet::_handle_packet_error $msg $id + return + } + if { ($len < 14) || ($len > 1514) } { + set msg "protocol mismatch from rawether process for $name\n" + append msg " Invalid transfer length $len\n" + ethernet::_handle_packet_error $msg $id + return + } + + set data [read $chan $len] + if { $len != [string length $data] } { + set msg "protocol mismatch from rawether process for $name\n" + append msg " Expected $len byte ethernet packet, received [string length $data] bytes\n" + ethernet::_handle_packet_error $msg $id + return + } + + # The data has been received correctly. Should it be buffered? + if { !$ethernet::data($id,up) } { + return + } + if { $ethernet::data($id,packet_count) >= $ethernet::max_buffered_packets } { + return + } + + # Store the packet, and inform eCos there is work to be done + lappend ethernet::data($id,packets) $data + incr ethernet::data($id,packet_count) + synth::interrupt_raise $ethernet::data($id,interrupt_vector) + + } + + # ---------------------------------------------------------------------------- + # When eCos has exited, the rawether processes can and should be + # shut down immediately. + proc ecos_exited { arg_list } { + foreach id $ethernet::ids { + if { $ethernet::data($id,alive) } { + set ethernet::data($id,alive) 0 + fileevent $ethernet::data($id,rawether) readable "" + catch { close $ethernet::data($id,rawether) } + } + } + } + synth::hook_add "ecos_exit" ethernet::ecos_exited + + # ---------------------------------------------------------------------------- + # Read in various data files for use by the filters + # + # Other possible sources of information include arp, ypcat, and + # dns. Those are avoided for now because they involve running + # additional processes that might hang for a while. Also arp + # would only give useful information for very recently accessed + # machines, NIS might not be running, and dns could involve an + # expensive lookup while the system is running . + + array set services [list] + array set hosts [list] + array set protocols [list] + + proc read_services { } { + catch { + set fd [open "/etc/services" "r"] + while { -1 != [gets $fd line] } { + set junk "" + set name "" + set number "" + set protocol "" + if { [regexp -- {^([-a-zA-Z0-9_]+)\s*([0-9]+)/((?:tcp)|(?:udp)).*$} $line junk name number protocol] } { + set ethernet::services($number,$protocol) $name + } + } + close $fd + } + } + + proc read_protocols { } { + catch { + set fd [open "/etc/protocols" "r"] + while { -1 != [gets $fd line] } { + set junk "" + set name "" + set number "" + if { [regexp -- {^([-a-zA-Z0-9_]+)\s*([0-9]+)\s.*} $line junk name number] } { + set ethernet::protocols($number) $name + } + } + close $fd + } + } + + proc read_hosts { } { + catch { + set fd [open "/etc/hosts" "r"] + while { -1 != [gets $fd line] } { + set junk "" + set name "" + set number "" + + # Deliberately ignore parts of the name after the first . + if { [regexp -- {^([0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3})\s*([a-zA-Z0-9]+)(\.|\s|$)} $line junk number name] } { + # The number should be naturalized if it is going to match reliably + scan $line "%d.%d.%d.%d" a b c d + set index [expr (($a & 0x0FF) << 24) | (($b & 0x0FF) << 16) | (($c & 0x0FF) << 8) | ($d & 0x0FF)] + set ethernet::hosts($index) $name + } + } + close $fd + } + } + + # ---------------------------------------------------------------------------- + # Filtering support. This is only really used when running in GUI mode. + # However all the relevant options are still extracted and validated, + # to avoid warnings about unrecognised options. + + variable logging_enabled 0 + variable max_show 64 + + # Construct a string for the data, either all of it or up to max_show bytes. + # This is just hex in chunks of four bytes. + proc format_hex_data { data } { + set result "" + + set len [string length $data] + if { $len > $ethernet::max_show } { + set len $ethernet::max_show + } + binary scan $data "H[expr 2 * $len]" hex + for { set i 0 } { $i < $len } { incr i 4 } { + append result "[string range $hex [expr $i * 2] [expr ($i * 2) + 7]] " + } + set result [string trimright $result] + return $result + } + + # Given an IPv4 network address, turn it into a.b.c.d and the + # host name as well (if known). The argument should be a 32-bit + # integer. + proc inet_ipv4_ntoa { number } { + set result [format "%d.%d.%d.%d" [expr ($number >> 24) & 0x0FF] [expr ($number >> 16) & 0x0FF] \ + [expr ($number >> 8) & 0x0FF] [expr $number & 0x0FF]] + if { [info exists ethernet::hosts($number) ] } { + append result "($ethernet::hosts($number))" + } + return $result + } + + # Given an ipv4 address encapsulated in an IPv6 address, do the necessary + # conversion. We have something like 123:4567, we want a.b.c.d plus + # a host address. + proc inet_ipv4_in_ipv6_ntoa { top bottom } { + if { "" == $top } { + set top 0 + } + if { "" == $bottom } { + set bottom 0 + } + set top "0x$top" + set bottom "0x$bottom" + + set ipv4 [expr ($top << 16) | $bottom] + return inet_ipv4_ntoa $ipv4 + } + + # Ditto for IPv6. The argument should be a 32-digit hexadecimal string. + # For now there is no simple way of mapping these onto host names, + # unless the address is an IPv4-mapped or compatible one, or one of + # special cases such as loopback. + proc inet_ipv6_ntoa { number } { + # We have something like 12345678abcdef. Start by inserting the appropriate + # colons. + set result [format "%s:%s:%s:%s:%s:%s:%s:%s" [string range $number 0 3] [string range $number 4 7] \ + [string range $number 8 11] [string range $number 12 15] [string range $number 16 19] \ + [string range $number 20 23] [string range $number 24 27] [string range $number 28 31]] + # Now eliminate unwanted 0's at the start of each range. + regsub {^0+} $result {} result + regsub -all {:0+} $result {:} result + + # If we have ended up with sequences of colons, abbreviate + # them into pairs. + regsub -all {::+} $result {::} result + + # There are a couple of special addresses + if { "::1" == $result } { + return "::1(loopback)" + } elseif { "::" == $result } { + return "::(IN6ADDR_ANY)" + } + + # Look for IPv4-mapped addresses. + set junk "" + set ipv4_1 "" + set ipv4_2 "" + if { [regexp -nocase -- {::ffff:([0-9a-f]{0,3}):([0-9a-f]{0,3})$} $result junk ipv4_1 ipv4_2] } { + set result [inet_ipv4_in_ipv6_nto $ipv4_1 $ipv4_2] + return "::FFFF:$result" + } elseif { [regexp -nocase -- {::([0-9a-f]{0,3}):([0-9a-f]{0,3})$} $result junk ipv4_1 ipv4_2] } { + set result [inet_ipv4_in_ipv6_nto $ipv4_1 $ipv4_2] + return "::$result" + } else { + # Could still be aggregatable global unicast, link-local, site-local or multicast. + # But not decoded further for now. + return $result + } + } + + proc log_packet { device direction packet } { + if { [string length $packet] < 14 } { + return + } + binary scan $packet {H2H2H2H2H2H2 H2H2H2H2H2H2 S} dest5 dest4 dest3 dest2 dest1 dest0 src5 src4 src3 src2 src1 src0 eth_protocol + set packet [string range $packet 14 end] + + set ether_msg "$device $direction: [string length $packet] bytes, " + append ether_msg [format ">%s:%s:%s:%s:%s:%s <%s:%s:%s:%s:%s:%s" $dest5 $dest4 $dest3 $dest2 $dest1 $dest0 $src5 $src4 $src3 $src2 $src1 $src0] + set eth_protocol [expr $eth_protocol & 0x0FFFF] + if { $eth_protocol <= 1536 } { + append ether_msg " 802.3 " + if { [string length $packet] < 8 } { + return + } + binary scan $packet {a6 S} junk eth_protocol + set packet [string range $packet 8 end] + } + append ether_msg [format " %04x" $eth_protocol] + if { $eth_protocol == 0x0800 } { + append ether_msg "(ip)" + } elseif { $eth_protocol == 0x00806 } { + append ether_msg "(arp)" + } elseif { $eth_protocol == 0x08035 } { + append ether_msg "(rarp)" + } + append ether_msg " [ethernet::format_hex_data $packet]\n" + synth::output $ether_msg "eth_ether" + + if { 0x0806 == $eth_protocol } { + # An ARP request. This should always be 28 bytes. + if { [string length $packet] < 28 } { + return + } + binary scan $packet {SSccS H2H2H2H2H2H2 I H2H2H2H2H2H2 I} hard_type prot_type hard_size prot_size op \ + sender5 sender4 sender3 sender2 sender1 sender0 sender_ip \ + target5 target4 target3 target2 target1 target0 target_ip + set hard_type [expr $hard_type & 0x0FFFF] + set prot_type [expr $prot_type & 0x0FFFF] + set hard_size [expr $hard_size & 0x0FF] + set prot_size [expr $prot_size & 0x0FF] + set op [expr $op & 0x0FFFF] + set sender_ip [expr $sender_ip & 0x0FFFFFFFF] + set target_ip [expr $target_ip & 0x0FFFFFFFF] + + set arp_msg "$device $direction: ARP " + if { $op == 1 } { + append arp_msg "request " + } elseif { $op == 2 } { + append arp_msg "reply " + } else { + append_arp_msg "<unknown opcode> " + } + if { $hard_type != 1 } { + append arp_msg "(unexpected hard_type field $hard_type, should be 1) " + } + if { $prot_type != 0x0800 } { + append arp_msg "(unexpected prot_type field $prot_type, should be 0x0800) " + } + if { $hard_size != 6 } { + append arp_msg "(unexpected hard_size field $hard_size, should be 6) " + } + if { $prot_size != 4 } { + append arp_msg "(unexpected prot_size field $prot_size, should be 4) " + } + append arp_msg [format ", sender %s:%s:%s:%s:%s:%s " $sender5 $sender4 $sender3 $sender2 $sender1 $sender0] + append arp_msg [ethernet::inet_ipv4_ntoa $sender_ip] + append arp_msg [format ", target %s:%s:%s:%s:%s:%s " $target5 $target4 $target3 $target2 $target1 $target0] + append arp_msg [ethernet::inet_ipv4_ntoa $target_ip] + append arp_msg "\n" + + synth::output $arp_msg "eth_arp" + return + } + + if { 0x0800 != $eth_protocol } { + return + } + + # We have an IP packet. Is this IPv4 or IPv6? The first byte contains + # the version and the overall length of the IP header in 32-bit words + if { [string length $packet] < 20 } { + return + } + binary scan $packet {c} tmp + set ip_version [expr ($tmp >> 4) & 0x0F] + set ip_hdrsize [expr $tmp & 0x0F] + if { 4 == $ip_version } { + binary scan $packet {ccSSSccSII} tmp tos len id frag ttl ip_protocol checksum source_ip dest_ip + set ipv4_msg "$device $direction: IPv4" + if { 0 != $tos } { + append ipv4_msg [format " tos %02x," [expr $tos & 0x0FF]] + } + append ipv4_msg [format " len %d, id %d," [expr $len & 0x0FFFF] [expr $id & 0x0FFFF]] + if { 0 != $frag } { + append ipv4_msg [format " frag %u" [expr 8 * ($frag & 0x01FFF)]] + if { 0 != ($frag & 0x04000) } { + append ipv4_msg " DF" + } + if { 0 != ($frag & 0x02000) } { + append ipv4_msg " MF" + } + append ipv4_msg "," + } + append ipv4_msg [format " ttl %d," $ttl] + set ip_protocol [expr $ip_protocol & 0x0FF] + if { [info exists ethernet::protocols($ip_protocol)] } { + append ipv4_msg " $ethernet::protocols($ip_protocol)," + } else { + append ipv4_msg [format " protocol %d" $ip_protocol] + } + + set source_name [ethernet::inet_ipv4_ntoa $source_ip] + set dest_name [ethernet::inet_ipv4_ntoa $dest_ip] + append ipv4_msg " >${dest_name}, <${source_name}\n" + + synth::output $ipv4_msg "eth_ipv4" + + # If this packet is a fragment other than the first, do not try to decode + # subsequent packets. The header information will not be present. + if { 0 != ($frag & 0x01FFF)} { + return + } + set packet [string range $packet [expr 4 * $ip_hdrsize] end] + + } elseif { 6 == $ip_version } { + if { [string length $packet] < 40 } { + return + } + binary scan $packet {ISccH16H16} flow payload_length next_header hop_limit source_ip dest_ip + set ipv6_msg "$device $direction: IPv6" + set prio [expr ($flow & 0x0F000000) >> 24] + set flow [expr $flow & 0x00FFFFFF] + if { 0 != $flow } { + append ipv6_msg [format " flow %04x prio %x," $flow $prio] + } + append ipv6_msg " payload [expr $payload bytes & 0x0FFFF]," + append ipv6_msg " hop limit [expr $hop_limit & 0x0FF]," + set next_header [expr $next_header & 0x0FF] + if { [info exists ethernet::protocols($next_header)] } { + append ipv6_msg " $ethernet::protocols($next_header)," + } else { + append ipv6_msg [format " protocol %d," $next_header] + } + + set source_name [ethernet::inet_ipv6_ntoa $source_ip] + set dest_name [ethernet::inet_ipv6_ntoa $dest_ip] + append ipv6_msg " >${dest_name}, <${source_name}\n" + + synth::output $ipv6_msg "eth_ipv6" + + set packet [string range $packet 40 end] + + } else { + synth::output "$device $direction: unknown IP version $ip_version\n" "eth_ipv4" + return + } + + + # Now for some known protocols, icmp, tcp, udp and icmpv6 + # Possible ipv6-frag should be handled here as well. The + # fragment header should be followed by another header such + # as tcp or udp. + if { 1 == $ip_protocol } { + # ipv4 ICMP + if { [string length $packet] < 4 } { + return + } + binary scan $packet {ccS} code type checksum + + set icmpv4_msg "$device $direction: ICMPv4 " + set error 0 + set data 0 + switch -- $code { + 0 { + append icmpv4_msg "ping reply" + if { [string length $packet] >= 8 } { + # The id and seq are in the sender's format, not network format. + # We have to assume either little or bigendian, so go for the former + binary scan $packet {iss} junk id seq + append icmpv4_msg [format " id %u, seq %u" [expr $id & 0x0FFFF] [expr $seq & 0x0FFFF]] + set data 1 + set packet [string range $packet 8 end] + } + } + 3 { + append icmpv4_msg "unreachable/" + switch -- $type { + 0 { append icmpv4_msg "network" } + 1 { append icmpv4_msg "host" } + 2 { append icmpv4_msg "protocol" } + 3 { append icmpv4_msg "port" } + 4 { append icmpv4_msg "frag needed but don't frag set" } + 5 { append icmpv4_msg "source route failed" } + 6 { append icmpv4_msg "destination network unknown" } + 7 { append icmpv4_msg "destination host unknown" } + 8 { append icmpv4_msg "source host isolated" } + 9 { append icmpv4_msg "destination network prohibited" } + 10 { append icmpv4_msg "destination host prohibited" } + 11 { append icmpv4_msg "network for TOS" } + 12 { append icmpv4_msg "host for TOS" } + 13 { append icmpv4_msg "communication prohibited" } + 14 { append icmpv4_msg "host precedence violation" } + 15 { append icmpv4_msg "precedence cutoff" } + default { append icmpv4_msg "unknown" } + } + set error 1 + } + 4 { + append icmpv4_msg "source quench" + set error 1 + } + 5 { + append icmpv4_msg "redirect/" + switch -- $type { + 0 { append icmpv4_msg "network" } + 1 { append icmpv4_msg "host" } + 2 { append icmpv4_msg "tos & network" } + 3 { append icmpv4_msg "tos & host" } + default { append icmpv4_msg "unknown" } + } + set error 1 + } + 8 { + append icmpv4_msg "ping request" + if { [string length $packet] >= 8 } { + binary scan $packet {iss} junk id seq + append icmpv4_msg [format " id %u, seq %u" [expr $id & 0x0FFFF] [expr $seq & 0x0FFFF]] + set data 1 + set packet [string range $packet 8 end] + } + } + 9 { + append icmpv4_msg "router advertisement" + } + 10 { + append icmpv4_msg "router solicitation" + } + 11 { + append icmpv4_msg "time exceeded/" + switch -- $type { + 0 { append icmpv4_msg "transit" } + 1 { append icmpv4_msg "reassembly" } + default { append icmpv4_msg "unknown" } + } + set error 1 + } + 12 { + append icmpv4_msg "parameter problem/" + switch -- $type { + 0 { append icmpv4_msg "IP header bad" } + 1 { append icmpv4_msg "required option missing" } + default { append icmpv4_msg "unknown" } + } + set error 1 + } + 13 { + append icmpv4_msg "timestamp request" + } + 14 { + append icmpv4_msg "timestamp reply" + } + 15 { + append icmpv4_msg "information request" + } + 16 { + append icmpv4_msg "information reply" + } + 17 { + append icmpv4_msg "address mask request" + } + 18 { + append icmpv4_msg "address mask reply" + } + default { + append icmpv4_msg "unknown" + } + } + if { $error && ([string length $packet] >= 36) } { + # The ICMP message contains an IP header and hopefully the TCP or UDP ports as well + # Only deal with the simple cases. + binary scan $packet {iiccSiccSIISS} icmp_junk1 icmp_junk2 ip_lenver ip_junk1 ip_junk2 ip_junk3 ip_junk4 ip_protocol ip_junk5 \ + ip_source ip_dest ip_source_port ip_dest_port + if { (5 == ($ip_lenver & 0x0F)) && ((6 == $ip_protocol) || (17 == $ip_protocol)) } { + if { 6 == $ip_protocol } { + append icmpv4_msg ", tcp" + } else { + append icmpv4_msg ", udp" + } + append icmpv4_msg " >[ethernet::inet_ipv4_ntoa $ip_dest]:$ip_dest_port <[ethernet::inet_ipv4_ntoa $ip_source]:$ip_source_port" + } + } + + append icmpv4_msg "\n" + synth::output $icmpv4_msg "eth_icmpv4" + + # Only some of the requests contain additional data that should be displayed + if { !$data } { + return + } + + } elseif { 58 == $ip_protocol } { + # ipv6 ICMP + if { [string length $packet] < 4 } { + return + } + binary scan $packet {ccS} code type checksum + + set icmpv6_msg "$device $direction: ICMPv6 " + set error 0 + set data 0 + switch -- $code { + 1 { + append icmpv6_msg "unreachable/" + switch -- $type { + 0 { append icmpv6_msg "no route" } + 1 { append icmpv6_msg "prohibited" } + 2 { append icmpv6_msg "not a neighbour" } + 3 { append icmpv6_msg "any other reason" } + 4 { append icmpv6_msg "UDP port unreachable" } + default { append icmpv6_msg "unknown" } + } + set error 1 + } + 2 { + append icmpv6_msg "packet too big" + set error 1 + } + 3 { + append icmpv6_msg "time exceeded/" + switch -- $type { + 0 { append icmpv6_msg "hop limit" } + 1 { append icmpv6_msg "fragment reassembly" } + default { append icmpv6_msg "unknown" } + } + set error 1 + } + 4 { + append icmpv6_msg "parameter problem" + switch -- $type { + 0 { append icmpv6_msg "erroneous header" } + 1 { append icmpv6_msg "unrecognized next header" } + 2 { append icmpv6_msg "unrecognized option" } + default { append icmpv6_msg "unknown" } + } + set error 1 + } + 128 { + append icmpv6_msg "ping request" + # FIXME: is this the same format as for icmpv4? + } + 129 { + append icmpv6_msg "ping reply" + # FIXME: is this the same format as for icmpv4? + } + 130 { + append icmpv6_msg "group membership query" + } + 131 { + append icmpv6_msg "group membership report" + } + 132 { + append icmpv6_msg "group membership reduction" + } + 133 { + append icmpv6_msg "router solicitation" + } + 134 { + append icmpv6_msg "router advertisement" + } + 135 { + append icmpv6_msg "neighbour solicitation" + } + 136 { + append icmpv6_msg "neighbour advertisement" + } + 137 { + append icmpv6_msg "redirect" + } + } + + if { $error && ([string length $packet] >= 44) } { + # The ICMP message contains an IPv6 header and hopefully the TCP or UDP ports as well + binary scan $packet {isccH16H16SS} icmp_junk1 icmp_junk2 ip_protocol icmp_junk3 ip_source ip_dest ip_source_port ip_dest_port + if { 6 == $ip_protocol } { + append icmpv6_msg ", tcp" + } elseif { 17 == $ip_protocol } { + append icmpv6_msg ", udp" + } + append icmpv6_msg " >[ethernet::inet_ipv4_ntoa $ip_dest]:$ip_dest_port <[ethernet::inet_ipv6_ntoa $ip_source]:$ip_source_port" + } + append icmpv6_msg "\n" + synth::output $icmpv6_msg "eth_icmpv6" + + if { !$data } { + return + } + + } elseif { 6 == $ip_protocol } { + # TCP + if { [string length $packet] < 20 } { + return + } + binary scan $packet {SSIIccSSS} source_port dest_port seq ack hdrsize flags winsize checksum urg + set source_port [expr $source_port & 0x0FFFF] + set dest_port [expr $dest_port & 0x0FFFF] + set hdrsize [expr ($hdrsize >> 4) & 0x0F] + set winsize [expr $winsize & 0x0FFFF] + set urg [expr $urg & 0x0FFFF] + + set tcp_msg "$device $direction tcp: " + append tcp_msg " >${dest_name}:${dest_port}" + if { [info exists ethernet::services($dest_port,udp)] } { + append tcp_msg "($ethernet::services($dest_port,udp))" + } + append tcp_msg "<${source_name}:$source_port" + if { [info exists ethernet::services($source_port,udp)] } { + append tcp_msg "($ethernet::services($source_port,udp))" + } + + append tcp_msg ", " + if { $flags & 0x08 } { + append tcp_msg "PSH " + } + if { $flags & 0x04 } { + append tcp_msg "RST " + } + if { $flags & 0x02 } { + append tcp_msg "SYN " + } + if { $flags & 0x01 } { + append tcp_msg "FIN " + } + append tcp_msg [format "seq %u" $seq] + + if { 0 != ($flags & 0x010) } { + append tcp_msg [format ", ACK %u" $ack] + } + append tcp_msg ", win $winsize" + if { 0 != ($flags & 0x020) } { + append tcp_msg ", URG $urg" + } + append tcp_msg "\n" + synth::output $tcp_msg "eth_tcp" + + set packet [string range $packet [expr 4 * $hdrsize] end] + } elseif { 17 == $ip_protocol } { + # UDP + if { [string length $packet] < 8 } { + return + } + set udp_msg "$device $direction: udp " + binary scan $packet {SSSS} source_port dest_port len checksum + set source_port [expr $source_port & 0x0FFFF] + set dest_port [expr $dest_port & 0x0FFFF] + append udp_msg [format "%d bytes, " [expr $len & 0x0FFFF]] + append udp_msg " >${dest_name}:$dest_port" + if { [info exists ethernet::services($dest_port,udp)] } { + append udp_msg "($ethernet::services($dest_port,udp))" + } + append udp_msg "<${source_name}:$source_port" + if { [info exists ethernet::services($source_port,udp)] } { + append udp_msg "($ethernet::services($source_port,udp))" + } + append udp_msg "\n" + synth::output $udp_msg "eth_udp" + set packet [string range $packet 8 end] + } else { + # Unknown protocol, so no way of knowing where the data starts. + return + } + + # At this point we may have a payload. This should be + # dumped in both hex and ascii. The code tries to preserve + # alignment. + if { [string length $packet] == 0 } { + return + } + set hexdata_msg "$device $direction: data [format_hex_data $packet]\n" + set asciidata_msg "$device $direction: data " + set len [string length $packet] + if { $len > $ethernet::max_show } { + set len $ethernet::max_show + } + for { set i 0 } { $i < $len } { incr i } { + set char [string index $packet $i] + if { "\r" == $char } { + append asciidata_msg "\\r" + } elseif { "\n" == $char } { + append asciidata_msg "\\n" + } elseif { "\t" == $char } { + append asciidata_msg "\\t" + } elseif { [string is print -strict $char] } { + append asciidata_msg " $char" + } else { + append asciidata_msg "??" + } + if { 3 == ($i % 4) } { + append asciidata_msg " " + } + } + append asciidata_msg "\n" + synth::output $hexdata_msg "eth_hexdata" + synth::output $asciidata_msg "eth_asciidata" + + return + } + + # A utility for handling the ethernet record button on the toolbar + proc logging_button_toggle { } { + if { $ethernet::logging_enabled } { + set ethernet::logging_enabled 0 + .toolbar.ethernet_logging configure -relief flat + } else { + set ethernet::logging_enabled 1 + .toolbar.ethernet_logging configure -relief sunken + } + } + + # A dummy procedure for initialization. All of this could execute at + # the toplevel, but there are lots of locals. + proc filters_initialize { } { + ethernet::read_services + ethernet::read_protocols + ethernet::read_hosts + + # Add a button on the toolbar for enabling/disabling logging. + # Also add an entry to the help menu + if { $synth::flag_gui } { + button .toolbar.ethernet_logging -image $ethernet::image_netrecord -borderwidth 2 -relief flat -command ethernet::logging_button_toggle] + pack .toolbar.ethernet_logging -side left -padx 2 + synth::register_balloon_help .toolbar.ethernet_logging "Record ethernet traffic" + + if { [synth::tdf_has_option "ethernet" "logging"] } { + set ethernet::logging_enabled [synth::tdf_get_option "ethernet" "logging"] + } else { + # Default to logging ethernet traffic. This may not be the right thing to do + # because users may see too much output by default, but it is easy enough + # to disable. + set ethernet::logging_enabled 1 + } + if { $ethernet::logging_enabled } { + .toolbar.ethernet_logging configure -relief sunken + } + + set ethernet_help [file join $synth::device_src_dir "doc" "devs-eth-synth-ecosynth.html"] + if { ![file readable $ethernet_help] } { + synth::report_warning "Failed to locate synthetic ethernet documentation $ethernet_help\n \ + Help->Ethernet target menu option disabled.\n" + set ethernet_help "" + } + if { "" == $ethernet_help } { + .menubar.help add command -label "Ethernet" -state disabled + } else { + .menubar.help add command -label "Ethernet" -command [list synth::handle_help "file://$ethernet_help"] + } + } + + if { [synth::tdf_has_option "ethernet" "max_show"] } { + set ethernet::max_show [synth::tdf_get_option "ethernet" "max_show"] + if { ! [string is integer -strict $ethernet::max_show] } { + synth::report_error "Ethernet device, invalid value in target definition file $synth::target_definition\n \ + Entry max_show should be a simple integer, not $ethernet::max_show\n" + set ethernet::init_ok 0 + } + } + + # Filters. First, perform some validation. + set known_filters [list "ether" "arp" "ipv4" "ipv6" "icmpv4" "icmpv6" "udp" "tcp" "hexdata" "asciidata"] + set tdf_filters [synth::tdf_get_options "ethernet" "filter"] + array set filter_options [list] + + foreach filter $tdf_filters { + if { 0 == [llength $filter] } { + synth::report_error "Ethernet device, invalid value in target definition file $synth::target_definition\n \ + Option \"filter\" requires the name of a known filters.\n" + set ethernet::init_ok 0 + continue + } + set name [lindex $filter 0] + if { [info exists filter_options($name)] } { + synth::report_error "Ethernet device, invalid value in target definition file $synth::target_definition\n \ + \"filter $name\" should be defined only once.\n" + set ethernet::init_ok 0 + continue + } + if { -1 == [lsearch -exact $known_filters $name] } { + synth::report_error "Ethernet device, invalid value in target definition file $synth::target_definition\n \ + Unknown filter \"$name\".\n \ + Known filters are $known_filters\n" + set ethernet::init_ok 0 + continue + } + set filter_options($name) [lrange $filter 1 end] + } + + # We now know about all the filter entries in the target definition file. + # Time to create the filters themselves, provided we are running in GUI mode. + if { $synth::flag_gui } { + foreach filter $known_filters { + if { ! [info exists filter_options($filter)] } { + synth::filter_add "eth_$filter" -text "ethernet $filter" + } else { + array set parsed_options [list] + set message "" + if { ![synth::filter_parse_options $filter_options($filter) parsed_options message] } { + synth::report_error \ + "Invalid entry in target definition file $synth::target_definition\n \ + Ethernet filter $filter\n $message" + set ethernet::init_ok 0 + } else { + set parsed_options("-text") "ethernet $filter" + synth::filter_add_parsed "eth_$filter" parsed_options + } + } + } + } + } + ethernet::filters_initialize +} + +return ethernet::instantiate
new file mode 100644 --- /dev/null +++ b/packages/devs/eth/synth/ecosynth/current/host/ethernet.tdf @@ -0,0 +1,117 @@ +# Target definition file fragment for ethernet devices. +# +# The target-side can instantiate up to four ethernet devices, +# eth0 to eth3. Each instance requires an entry in the +# target definition file specifying what underlying Linux +# kernel facility should be used to implement the I/O. This +# can take the following forms: +# +# 1) an existing ethernet device, e.g. +# eth0 real eth1 +# thus mapping the eCos device eth0 on to the Linux device eth1. +# The latter network interface must not currently be in use +# by Linux. Traffic will flow to and from the real ethernet, and +# communication is possible with any machine on the LAN. +# +# 2) the Linux kernel's tap facility. +# eth0 ethertap +# This will result in a Linux ethernet interface such as +# tap3 appearing. The interface can be configured like any +# other network device, for example by using the ifconfig +# command or by creating a configuration file +# /etc/sysconfig/network-scripts/ifcfg-tap3 +# The result is a virtual ethernet segment visible only +# to the Linux host and eCos. Bridge software inside the +# Linux host can be used to connect eCos to a larger network. +# +# Optionally a specific tap device can be configured, +# eth0 ethertap tap3 +# By default the code will pick up the next free tap device, +# usually tap0. If the Linux interface should come up automatically +# then this can be achieved with an ifcfg-tap?? configuration +# file. Explicitly specifying the tap device can avoid some +# confusion. +# +# Both the eCos and the Linux network interface need a unique +# MAC address. There is no real ethernet hardware involved to +# supply these addresses, so they have to be invented. The +# Linux kernel will automatically invent one for its interface. +# By default a random MAC address will also be generated for +# the eCos interface, but to make the system more deterministic +# it is possible to specify the MAC address to be used. This +# facility is only available in conjunction with an explicit +# tap device, e.g.: +# eth0 ethertap tap3 00:01:02:03:04:05 +# The MAC address should be in the usual format: six 2-digit +# hexadecimal numbers separated by colons. It is the user's +# responsibility to make sure that the address specified +# does not match any other real or invented address visible +# on the local network. +# +# It is possible that bursts of ethernet traffic occur, causing +# packets to arrive faster than they can be forwarded to and +# processed by eCos. It is desirable that some number of packets +# be buffered, matching the behaviour of many ethernet devices +# with built-in fifos. However the number of these packets should +# be restricted: if eCos stops accepting ethernet packets or +# cannot handle the data quickly enough, then it is possible that +# an unlimited number of packets could accumulate in the I/O +# auxiliary until all available memory and swap space is exhausted. +# By default up to 16 packets will be buffered per device, but +# this can be changes with the max_buffer option. +# +# The ethernet emulation code can perform logging and limited +# analysis of each ethernet packet. For example if a particular +# packet is an IPv4 ICMP request then details of the request +# will be logged to the main text window. The appearance of the +# various filters can be controlled here, using the usual +# options such as -foreground, -background, and -hide. +# +# This logging of each ethernet frame can be somewhat time-consuming +# and, for a long run, require a lot of memory. Logging can be +# disabled by default if desired, and a button on the toolbar allows +# this setting to be toggled. +# +# Ethernet packets can be up to 1514 bytes, so showing entire packets +# on a single line can mean very wide lines. In practice the interesting +# data is usually at the start, so the output can be truncated to a +# maximum number of bytes. The data is displayed in hex so each byte +# requires two columns, and some spacing will be added as well to +# improve legibility. + +synth_device ethernet { + ## Map eCos devices on to Linux ones. + + # eth0 real eth1 + # eth0 ethertap + # eth0 ethertap tap3 + eth0 ethertap tap3 00:FE:42:63:84:A5 + + # eth1 ethertap tap4 00:FE:12:34:56:78 + # eth2 ethertap tap5 00:FE:9A:BC:DE:F0 + # eth3 real eth2 + + ## Maximum number of packets that should be buffered per interface. + ## Default 16 + max_buffer 32 + + ## Should packets be logged? The default is yes. + # logging 0 + + ## Maximum number of data bytes to be shown. + ## Default 64 + # max_show 128 + + ## Filters for the various recognised protocols. + ## By default all filters are visible and use standard colours. + # filter ether -hide 0 + # filter arp -hide 1 + # filter ipv4 -hide 1 + # filter ipv6 -hide 1 + # filter icmpv4 -hide 1 + # filter icmpv6 -hide 1 + # filter udp -hide 1 + # filter tcp -hide 1 + # filter hexdata -hide 0 + # filter asciidata -hide 0 +}
new file mode 100644 --- /dev/null +++ b/packages/devs/eth/synth/ecosynth/current/host/fromnet.xbm @@ -0,0 +1,4 @@ +#define fromnet_width 8 +#define fromnet_height 8 +static unsigned char fromnet_bits[] = { + 0x00, 0x87, 0xa5, 0x95, 0xfd, 0x95, 0xa5, 0x87};
new file mode 100644 --- /dev/null +++ b/packages/devs/eth/synth/ecosynth/current/host/netrecord.xbm @@ -0,0 +1,6 @@ +#define netrecord_width 16 +#define netrecord_height 15 +static unsigned char netrecord_bits[] = { + 0x00, 0x00, 0xce, 0x39, 0x4a, 0x08, 0xce, 0x09, 0x46, 0x08, 0xca, 0x39, + 0x00, 0x00, 0x0e, 0x20, 0x4a, 0x24, 0x2a, 0x28, 0xfa, 0x3f, 0x2a, 0x28, + 0x4a, 0x24, 0x0e, 0x20, 0x00, 0x00};
new file mode 100644 --- /dev/null +++ b/packages/devs/eth/synth/ecosynth/current/host/rawether.c @@ -0,0 +1,757 @@ +//============================================================================ +// +// rawether.c +// +// A utility program to perform low-level ethernet operations +// +//============================================================================ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 2002 Bart Veer +// +// This file is part of the eCos host tools. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// ---------------------------------------------------------------------------- +// +//####COPYRIGHTEND#### +//============================================================================ +//#####DESCRIPTIONBEGIN#### +// +// Author(s): bartv +// Contact(s): bartv +// Date: 2002/08/07 +// Version: 0.01 +// Description: +// +// This program is fork'ed by the ethernet.tcl script running inside +// the synthetic target auxiliary. It is responsible for performing +// low-level ethernet I/O. +// +//####DESCRIPTIONEND#### +//============================================================================ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include <signal.h> +#include <limits.h> +#include <unistd.h> +#include <fcntl.h> +#include <errno.h> +#include <sys/param.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/ioctl.h> +#include <net/if.h> +#include <net/if_arp.h> +#include <netinet/in.h> +#include <netinet/if_ether.h> +#include <linux/if_packet.h> +#include <linux/if_ether.h> +#include <linux/if_tun.h> + +// The protocol between host and target is defined by a private +// target-side header. +#include "../src/protocol.h" + +// Allow debug builds. Set this flag to 0, 1 or 2 +#define DEBUG 0 + +// ---------------------------------------------------------------------------- +// Statics. + +// Are we using a real ethernet device or ethertap? +static int real_ether = 0; +static int ethertap = 0; + +// The six-byte MAC address, which must be returned to eCos +static unsigned char MAC[6]; + +// Does the driver support multicasting? +static int multicast_supported = 0; + +// The file descriptor for incoming data ethernet packets. +// Used for select() together with fd 0 corresponding to ecosynth +static int ether_fd = -1; + +// Is the interface up? +static int up = 0; + +// Space for incoming and outgoing packets. In the case of rx_buffer +// there are an extra four bytes at the front for the protocol header. +#define MTU 1514 +static unsigned char tx_buffer[MTU]; +static unsigned char rx_buffer[MTU+4]; + +// ---------------------------------------------------------------------------- +// A utility buffer for messages. +#define MSG_SIZE 256 +static unsigned char msg[MSG_SIZE]; + +// Report an error to ecosynth during initialization. This means a +// single byte 0, followed by a string. +static void +report_error(char* msg) +{ + write(1, "0", 1); + write(1, msg, strlen(msg)); + close(1); + exit(0); +} + +// Report success to ecosynth. This means a byte 1 followed by +// the MAC address. +static void +report_success(void) +{ + write(1, "1", 1); + memcpy(msg, MAC, 6); + msg[6] = multicast_supported; + write(1, msg, 7); +} + + +// ---------------------------------------------------------------------------- +// Real ethernet. This involves creating a SOCK_RAW socket and binding it +// to the appropriate interface. Relevant documentation can be found in +// the man pages (packet(7) and netdevice(7)). + +// The device name. Needed for various ioctl()'s. +static char real_devname[IFNAMSIZ]; + +// The interface index. +static int real_ifindex = -1; + +// Transmit a single ethernet frame. The socket should be set up so a +// simple send() operation should do the trick. Errors such as EAGAIN, +// indicating that the network device is still busy, are ignored. +// Ethernet is not a reliable communication medium. +static void +real_handle_tx(unsigned char* buffer, int size) +{ + int result; + + result = send(ether_fd, buffer, size, MSG_DONTWAIT); + if (result < 0) { + // It appears that one retry is worthwhile, to clear pending + // errors or something. + result = send(ether_fd, buffer, size, MSG_DONTWAIT); + } +#if (DEBUG > 0) + fprintf(stderr, "rawether dbg: tx %d bytes -> %d\n", size, result); +#endif +#if (DEBUG > 1) + fprintf(stderr, " %x:%x:%x:%x:%x:%x %x:%x:%x:%x:%x:%x %x:%x\n", + buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5], + buffer[6], buffer[7], buffer[8], buffer[9], buffer[10], buffer[11], + buffer[12], buffer[13]); +#endif +} + +// Receive a single ethernet frame, using the static rxbuffer. If the +// interface is not currently up discard it. Otherwise forward it on +// to ecosynth. + +static void +real_handle_rx(void) +{ + int size; + int result; + + size = recv(ether_fd, rx_buffer + 4, MTU, MSG_TRUNC); + +#if (DEBUG > 0) + fprintf(stderr, "rawether dbg: rx returned %d, errno %s (%d)\n", size, (errno < sys_nerr) ? sys_errlist[errno] : "<unknown>", errno); +#endif + + if (size < 0) { + return; // Ignore errors, just go around the main loop again. + } + if ((size < 14) || (size > MTU)) { + return; // Invalid packet size. Discard the packet. + } + +#if (DEBUG > 1) + fprintf(stderr, " %x:%x:%x:%x:%x:%x %x:%x:%x:%x:%x:%x %x:%x\n", + rx_buffer[4], rx_buffer[5], rx_buffer[6], rx_buffer[7], rx_buffer[8], rx_buffer[9], + rx_buffer[10], rx_buffer[11], rx_buffer[12], rx_buffer[13], rx_buffer[14], rx_buffer[15], + rx_buffer[16], rx_buffer[17]); +#endif + + if (!up) { + // eCos is not currently expecting packets, so discard them. + // This may not actually be necessary because the interface + // is only up when eCos wants it to be up. + return; + } + + // It looks this packet should get forwarded to eCos. + rx_buffer[0] = SYNTH_ETH_RX; + rx_buffer[1] = 0; + rx_buffer[2] = size & 0x00FF; + rx_buffer[3] = (size >> 8) & 0x00FF; + do { + result = write(1, rx_buffer, 4 + size); + } while ((-1 == result) && (EINTR == errno)); + + if (result != (size + 4)) { + fprintf(stderr, "rawether(%s): failed to send ethernet packet to I/O auxiliary, exiting.\n", real_devname); + exit(1); + } +} + +// Utility to manipulate interface flags. This involves retrieving the +// current flags, or'ing in some bits, and'ing out others, and updating. +static void +real_update_ifflags(int set_bits, int clear_bits) +{ + struct ifreq request; + int flags; + + strncpy(request.ifr_name, real_devname, IFNAMSIZ); + if (ioctl(ether_fd, SIOCGIFFLAGS, &request) < 0) { + fprintf(stderr, "rawether (%s): failed to get interface flags, exiting\n", real_devname); + exit(1); + } + + flags = request.ifr_flags; + + flags |= set_bits; + flags &= ~clear_bits; + + if (flags == request.ifr_flags) { + // Nothing is changing. + return; + } + + strncpy(request.ifr_name, real_devname, IFNAMSIZ); + request.ifr_flags = flags; + if (ioctl(ether_fd, SIOCSIFFLAGS, &request) < 0) { + fprintf(stderr, "rawether (%s): failed to update interface flags, exiting\n", real_devname); + exit(1); + } +} + + +// Starting an interface. This involves bringing the interface up, +// and optionally setting promiscuous mode. +// NOTE: is UP really the right thing here? There is no IP address +// for this interface. In theory this should not matter because +// we have a bound socket which should receive all packets for +// this interface. + +static void +real_handle_start(int promiscuous) +{ + if (promiscuous) { + real_update_ifflags(IFF_UP | IFF_PROMISC, 0); + } else { + real_update_ifflags(IFF_UP, IFF_PROMISC); + } + up = 1; +} + +// Stopping an interface means clearing the UP flag +static void +real_handle_stop(void) +{ + up = 0; + real_update_ifflags(0, IFF_UP | IFF_PROMISC); +} + +// Enabling/disabling multicast support. +static void +real_handle_multiall(int on) +{ + struct packet_mreq req; + + req.mr_ifindex = real_ifindex; + req.mr_type = PACKET_MR_ALLMULTI; + req.mr_alen = 0; + if (setsockopt(ether_fd, SOL_PACKET, on ? PACKET_ADD_MEMBERSHIP : PACKET_DROP_MEMBERSHIP, (void*)&req, sizeof(req)) < 0) { + fprintf(stderr, "rawether (%s): failed to manipulate multicast-all flag, exiting\n", real_devname); + exit(1); + } +} + +// When the application exists make sure that the interface goes down again. + +static void +real_atexit(void) +{ + if (up) { + real_update_ifflags(0, IFF_UP | IFF_PROMISC); + } +} + +static void +real_init(char* devname) +{ + struct sockaddr_ll addr; + struct ifreq request; + + if (strlen(devname) >= IFNAMSIZ) { + snprintf(msg, MSG_SIZE, "Invalid real network device name \"%s\", too long.\n", devname); + report_error(msg); + } + strcpy(real_devname, devname); + + // All ioctl() operations need a socket. We might as well create the + // raw socket immediately and use that. + ether_fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); + if (ether_fd < 0) { + snprintf(msg, MSG_SIZE, "Unable to create a raw socket for accessing network device\n" + " Error %s (errno %d)\n", (errno < sys_nerr) ? sys_errlist[errno] : "unknown", errno); + report_error(msg); + } + + strncpy(request.ifr_name, real_devname, IFNAMSIZ); + if (ioctl(ether_fd, SIOCGIFINDEX, &request) < 0) { + snprintf(msg, MSG_SIZE, "Device %s does not correspond to a valid interface.\n" + " Error %s (errno %d)\n", real_devname, (errno < sys_nerr) ? sys_errlist[errno] : "unknown", errno); + report_error(msg); + } + real_ifindex = request.ifr_ifindex; + + // The interface exists. Now check that it is usable. + strncpy(request.ifr_name, real_devname, IFNAMSIZ); + if (ioctl(ether_fd, SIOCGIFFLAGS, &request) < 0) { + snprintf(msg, MSG_SIZE, "Failed to get current interface flags for %s\n" + " Error %s (errno %d)\n", real_devname, (errno < sys_nerr) ? sys_errlist[errno] : "unknown", errno); + report_error(msg); + } + + if (request.ifr_flags & (IFF_UP | IFF_RUNNING)) { + snprintf(msg, MSG_SIZE, "Network device %s is already up and running.\n" + " Exclusive access is required\n", real_devname); + report_error(msg); + } + if (request.ifr_flags & IFF_LOOPBACK) { + report_error("Loopback devices cannot be used for synthetic target ethernet emulation.\n"); + } + if (request.ifr_flags & IFF_POINTOPOINT) { + report_error("Point-to-point devices cannot be used for synthetic target ethernet emulation.\n"); + } + if (request.ifr_flags & IFF_MULTICAST) { + multicast_supported = 1; + } + + // Make sure the interface is down. There is no point in receiving packets just yet. + real_update_ifflags(0, IFF_UP | IFF_PROMISC); + + // The flags look ok. Now get hold of the hardware address. + strncpy(request.ifr_name, real_devname, IFNAMSIZ); + if (ioctl(ether_fd, SIOCGIFHWADDR, &request) < 0) { + snprintf(msg, MSG_SIZE, "Failed to get hardware address for %s\n" + " Error %s (errno %d)\n", real_devname, (errno < sys_nerr) ? sys_errlist[errno] : "unknown", errno); + report_error(msg); + } + if (ARPHRD_ETHER != request.ifr_hwaddr.sa_family) { + snprintf(msg, MSG_SIZE, "Device %s is not an ethernet device.\n", real_devname); + report_error(msg); + } + memcpy(MAC, request.ifr_hwaddr.sa_data, 6); + + // The device is useable. Now just bind the socket to the appropriate address. + addr.sll_family = AF_PACKET; + addr.sll_protocol = htons(ETH_P_ALL); + addr.sll_ifindex = real_ifindex; + if (bind(ether_fd, (struct sockaddr*) &addr, sizeof(addr)) < 0) { + snprintf(msg, MSG_SIZE, "Failed to bind socket for direct hardware address to %s\n" + " Error %s (errno %d)\n", real_devname, (errno < sys_nerr) ? sys_errlist[errno] : "unknown", errno); + report_error(msg); + } + + // Make sure the interface gets shut down when rawether exits. + atexit(real_atexit); + + // And that should be it. +} + +// ---------------------------------------------------------------------------- +// Ethertap device. +// +// See /usr/src/linux-2.x.y/Documentation/networking/tuntap.txt for more +// information on the tun/tap driver. +// +// Basically during initialization this code opens /dev/net/tun, then +// performs a TUNSETIFF ioctl() to initialize it. This causes a +// new network device tap?? to appear. Any ethernet frames written +// by the Linux kernel to this device can be read from the +// dev/net/tun file descriptor, and ethernet frames can be written to +// the same descriptor. The net effect is a virtual ethernet segment +// with one interface managed by the Linux kernel and another +// interface (or, theoretically, several) accessible via the file +// descriptor. +// +// The Linux kernel will invent a MAC address for its interface. An +// additional one is needed for eCos. This is either invented or +// specified in the target definition file. + +static void +tap_handle_tx(unsigned char* buffer, int size) +{ + int result; + + result = write(ether_fd, buffer, size); +#if (DEBUG > 0) + fprintf(stderr, "rawether dbg: tx %d bytes -> %d\n", size, result); +#endif +#if (DEBUG > 1) + fprintf(stderr, " %x:%x:%x:%x:%x:%x %x:%x:%x:%x:%x:%x %x:%x\n", + buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5], + buffer[6], buffer[7], buffer[8], buffer[9], buffer[10], buffer[11], + buffer[12], buffer[13]); +#endif +} + +// Receive a single packet from the socket. It is assumed that the +// tuntap code inside the kernel will preserve packet boundaries. +// +// For now it is assumed that all incoming packets are intended for +// eCos. That may not be accurate, and additional filtering in +// software might be appropriate. In promiscuous mode all packets +// should be accepted, obviously. Otherwise all broadcasts should +// be accepted, as should all messages intended for this specific +// interface's MAC address. Multicasts should be accepted only if +// enabled. +static void +tap_handle_rx(void) +{ + int size; + int result; + + // select() has succeeded so this read() should never block. + size = read(ether_fd, rx_buffer + 4, MTU); +#if (DEBUG > 0) + fprintf(stderr, "rawether dbg: rx returned %d, errno %s (%d)\n", size, (errno < sys_nerr) ? sys_errlist[errno] : "<unknown>", errno); +#endif + + if (size < 0) { + return; // Ignore errors, just go around the main loop again. + } + if ((size < 14) || (size > MTU)) { + return; // Invalid packet size. Discard the packet. + } + +#if (DEBUG > 1) + fprintf(stderr, " %x:%x:%x:%x:%x:%x %x:%x:%x:%x:%x:%x %x:%x\n", + rx_buffer[4], rx_buffer[5], rx_buffer[6], rx_buffer[7], rx_buffer[8], rx_buffer[9], + rx_buffer[10], rx_buffer[11], rx_buffer[12], rx_buffer[13], rx_buffer[14], rx_buffer[15], + rx_buffer[16], rx_buffer[17]); +#endif + + if (!up) { + // eCos is not currently expecting packets, so discard them. + return; + } + + // It looks this packet should get forwarded to eCos. + rx_buffer[0] = SYNTH_ETH_RX; + rx_buffer[1] = 0; + rx_buffer[2] = size & 0x00FF; + rx_buffer[3] = (size >> 8) & 0x00FF; + do { + result = write(1, rx_buffer, 4 + size); + } while ((-1 == result) && (EINTR == errno)); + + if (result != (size + 4)) { + fprintf(stderr, "rawether(%s): failed to send ethernet packet to I/O auxiliary, exiting.\n", real_devname); + exit(1); + } +} + +// Nothing much can be done for start or stop. Just set the flag and +// let the rx and tx code discard packets when appropriate. +// +// For now the device is implicitly promiscuous and accepts all +// multicasts. Given the nature of a tap device it is unlikely that +// any packets will arrive which are not destined here. +// FIXME: this may have to change if bridging is enabled. +static void +tap_handle_start(int promiscuous) +{ + up = 1; +} + +static void +tap_handle_stop(void) +{ + up = 0; +} + +static void +tap_handle_multiall(int on) +{ +} + +static void tap_init(int argc, char** argv) +{ + char* devname = NULL; + struct ifreq ifr; + + // Which device? By default let the system pick one, but the user + // can override this. + if (0 != argc) { + devname = argv[0]; + } + + // Work out the MAC address. By default a random one is generated, + // but the user can specify one to avoid a source of randomness. + // This MAC address is not actually needed by any of the code here, + // but should be returned to eCos. + if (2 == argc) { + unsigned int mac_data[6]; // sscanf() needs unsigned ints + int result = sscanf(argv[1], "%x:%x:%x:%x:%x:%x", + &(mac_data[0]), &(mac_data[1]), &(mac_data[2]), + &(mac_data[3]), &(mac_data[4]), &(mac_data[5])); + if (6 != result) { + snprintf(msg, MSG_SIZE, "Invalid MAC address %s\n", argv[1]); + report_error(msg); + } + MAC[0] = mac_data[0]; + MAC[1] = mac_data[1]; + MAC[2] = mac_data[2]; + MAC[3] = mac_data[3]; + MAC[4] = mac_data[4]; + MAC[5] = mac_data[5]; + } else { + srand(time(NULL)); + MAC[0] = 0; + MAC[1] = 0x0FF; + MAC[2] = rand() & 0x0FF; + MAC[3] = rand() & 0x0FF; + MAC[4] = rand() & 0x0FF; + MAC[5] = rand() & 0x0FF; + } + + ether_fd = open("/dev/net/tun", O_RDWR); + if (ether_fd < 0) { + snprintf(msg, MSG_SIZE, "Failed to open /dev/net/tun, errno %s (%d)\n", (errno < sys_nerr) ? sys_errlist[errno] : "<unknown>", errno); + report_error(msg); + } + + memset(&ifr, 0, sizeof(ifr)); + ifr.ifr_flags = IFF_TAP | IFF_NO_PI; + if (NULL != devname) { + strncpy(ifr.ifr_name, devname, IFNAMSIZ - 1); + } + if (ioctl(ether_fd, TUNSETIFF, (void*)&ifr) < 0) { + snprintf(msg, MSG_SIZE, "Failed to initialize /dev/net/tun, errno %s (%d)\n", (errno < sys_nerr) ? sys_errlist[errno] : "<unknown>", errno); + report_error(msg); + } + + // Supporting multicasts is a no-op + multicast_supported = 1; + + // All done. +} + +// ---------------------------------------------------------------------------- +// Receive a single request from ecosynth. This consists of a four-byte +// header, optionally followed by a tx packet. EOF indicates that +// ecosynth has exited, so this process should just exit immediately +// as well. Any problems should be reported to stderr, followed by +// termination. +// +// Currently rawether is single-threaded. Theoretically this could +// cause a deadlock situation where the I/O auxiliary is trying to send +// rawether a request and is blocked on the write, while rawether is trying +// to send data to the I/O auxiliary. In practice the pipes should do +// enough buffering to avoid complications, especially since rawether +// gives priority to requests from the auxiliary. + +static void +handle_ecosynth_request(void) +{ + unsigned char req[4]; + int result; + int code, arg, size; + + result = read(0, req, 4); + if (result == 0) { + // select() succeeded but no data. EOF. So exit + exit(0); + } + if (result < 0) { + // EINTR? EAGAIN? The latter should not happen since the pipe + // has not been put into non-blocking mode. + if ((EINTR == errno) || (EAGAIN == errno)) { + return; + } else { + fprintf(stderr, "rawether: unexpected error reading request from ecosynth\n"); + if (errno < sys_nerr) { + fprintf(stderr, " %s\n", sys_errlist[errno]); + } + exit(1); + } + } + if (result < 4) { + fprintf(stderr, "rawether: unexpected error reading request from ecosynth\n Expected 4 bytes, only received %d\n", result); + exit(1); + } + + code = req[0]; + arg = req[1]; + size = req[2] + (req[3] << 8); + +#if (DEBUG > 1) + fprintf(stderr, "rawether dbg: request %x from auxiliary\n", code); +#endif + + switch(code) { + case SYNTH_ETH_TX: + { + if (size < 14) { + fprintf(stderr, "rawether: attempt to send invalid ethernet packet of only %d bytes\n" + "Ethernet packets should be at least 14 bytes.\n", size); + exit(1); + } + if (size > MTU) { + fprintf(stderr, "rawether: attempt to send invalid ethernet packet of %d bytes\n" + "Only packets of up to %d bytes are supported.\n", size, MTU); + exit(1); + } + do { + result = read(0, tx_buffer, size); + } while ((-1 == result) && (EINTR == errno)); + if (0 == result) { + // EOF, at an inopportune moment + exit(0); + } + if (result < size) { + fprintf(stderr, "rawether: error reading ethernet packet from I/O auxiliary\n" + "Expected %d bytes but only read %d\n", size, result); + exit(1); + } + + if (real_ether) { + real_handle_tx(tx_buffer, size); + } else if (ethertap) { + tap_handle_tx(tx_buffer, size); + } + break; + } + case SYNTH_ETH_START: + { + if (real_ether) { + real_handle_start(arg); + } else if (ethertap) { + tap_handle_start(arg); + } + break; + } + + case SYNTH_ETH_STOP: + { + if (real_ether) { + real_handle_stop(); + } else if (ethertap) { + tap_handle_stop(); + } + break; + } + + case SYNTH_ETH_MULTIALL: + { + if (real_ether) { + real_handle_multiall(arg); + } else if (ethertap) { + tap_handle_multiall(arg); + } + break; + } + + // SYNTH_ETH_RX and SYNTH_ETH_GETPARAMS are handled inside ethernet.tcl + + default: + fprintf(stderr, "rawether: protocol violation, received unknown request %d\n", code); + exit(1); + } +} + +// The main loop. This waits for an event either from ecosynth or from +// the underlying ethernet device, using select. Requests from +// ecosynth are handled, and take priority to prevent the connecting +// pipe from filling up and ecosynth blocking. Incoming ethernet +// frames are forwarded to ecosynth. + +static void +mainloop(void) +{ + fd_set read_set; + struct timeval timeout; + int result; + + for ( ; ; ) { + FD_ZERO(&read_set); + FD_SET(0, &read_set); + FD_SET(ether_fd, &read_set); + timeout.tv_sec = 24 * 60 * 60; + timeout.tv_usec = 0; + + result = select(ether_fd + 1, &read_set, NULL, NULL, &timeout); + if (result <= 0) { + continue; + } + + if (FD_ISSET(0, &read_set)) { + handle_ecosynth_request(); + } else if (FD_ISSET(ether_fd, &read_set)) { + if (real_ether) { + real_handle_rx(); + } else { + tap_handle_rx(); + } + } + } +} + +// ---------------------------------------------------------------------------- + +int +main(int argc, char**argv) +{ + // Ignore incoming ctrl-C's. We are in the same process group as the + // eCos application which may sensibly be ctrl-C'd, but that should + // result in the auxiliary detecting EOF and closing the pipe to + // this process, which in turn causes this process to exit completely. + signal(SIGINT, SIG_IGN); + + if (2 > argc ) { + report_error("Expected at least one argument, \"real\" or \"ethertap\"\n"); + } + if (0 == strcmp("real", argv[1])) { + real_ether = 1; + real_init(argv[2]); + } else if (0 == strcmp("ethertap", argv[1])) { + ethertap = 1; + tap_init(argc - 2, argv + 2); + } else { + snprintf(msg, MSG_SIZE, "Invalid argument %s, expected \"real\" or \"ethertap\"\n", argv[1]); + report_error(msg); + } + + // If the device-specific initialization succeeded we must be set. + report_success(); + + mainloop(); + + return 0; +} +
new file mode 100644 --- /dev/null +++ b/packages/devs/eth/synth/ecosynth/current/host/tonet.xbm @@ -0,0 +1,4 @@ +#define tonet_width 8 +#define tonet_height 8 +static unsigned char tonet_bits[] = { + 0x00, 0x87, 0x95, 0xa5, 0xfd, 0xa5, 0x95, 0x87};
new file mode 100644 --- /dev/null +++ b/packages/devs/eth/synth/ecosynth/current/src/protocol.h @@ -0,0 +1,72 @@ +#ifndef CYGONCE_DEVS_ETH_ECOSYNTH_PROTOCOL_H +#define CYGONCE_DEVS_ETH_ECOSYNTH_PROTOCOL_H + +//============================================================================= +// +// protocol.h +// +// Protocol between target-side and host-side ethernet support. +// +//============================================================================= +//####ECOSGPLCOPYRIGHTBEGIN#### +// ------------------------------------------- +// This file is part of eCos, the Embedded Configurable Operating System. +// Copyright (C) 2002 Bart Veer +// +// eCos is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 or (at your option) any later version. +// +// eCos is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License along +// with eCos; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. +// +// As a special exception, if other files instantiate templates or use macros +// or inline functions from this file, or you compile this file and link it +// with other works to produce a work based on this file, this file does not +// by itself cause the resulting work to be covered by the GNU General Public +// License. However the source code for this file must still be made available +// in accordance with section (3) of the GNU General Public License. +// +// This exception does not invalidate any other reasons why a work based on +// this file might be covered by the GNU General Public License. +// +// Alternative licenses for eCos may be arranged by contacting the +// copyright holder(s). +// ------------------------------------------- +//####ECOSGPLCOPYRIGHTEND#### +//============================================================================= +//#####DESCRIPTIONBEGIN#### +// +// Author(s): bartv +// Contributors:bartv +// Date: 2002-08-08 +// Purpose: Protocol definitions. +// Usage: #include "protocol.h" +// +//####DESCRIPTIONEND#### +// +//============================================================================= + +// Transmit: no arguments, up to 1514 bytes of outgoing data, no reply expected. +#define SYNTH_ETH_TX 0x01 +// Receive: no arguments or data, the return code indicates whether or not +// there are more packets to follow, and the return data is up to 1514 bytes. +#define SYNTH_ETH_RX 0x02 +// Start: one argument, non-zero -> promiscuous mode. No reply. +#define SYNTH_ETH_START 0x03 +// Stop: no arguments or reply. +#define SYNTH_ETH_STOP 0x04 +// Settings: no arguments or data. The return code holds the interrupt vector. +// The return data is six bytes of MAC address, plus a single byte indicating +// whether or not multicasting is supported. +#define SYNTH_ETH_GETPARAMS 0x05 +// Enable/disable multicasting. One argument, enable/disable. +#define SYNTH_ETH_MULTIALL 0x06 + +#endif // CYGONCE_DEVS_ETH_ECOSYNTH_PROTOCOL.H
new file mode 100644 --- /dev/null +++ b/packages/devs/eth/synth/ecosynth/current/src/syntheth.c @@ -0,0 +1,453 @@ +//========================================================================== +// +// syntheth.c +// +// Network device driver for the synthetic target +// +//========================================================================== +//####ECOSGPLCOPYRIGHTBEGIN#### +// ------------------------------------------- +// This file is part of eCos, the Embedded Configurable Operating System. +// Copyright (C) 2002 Bart Veer +// +// eCos is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 or (at your option) any later version. +// +// eCos is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License along +// with eCos; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. +// +// As a special exception, if other files instantiate templates or use macros +// or inline functions from this file, or you compile this file and link it +// with other works to produce a work based on this file, this file does not +// by itself cause the resulting work to be covered by the GNU General Public +// License. However the source code for this file must still be made available +// in accordance with section (3) of the GNU General Public License. +// +// This exception does not invalidate any other reasons why a work based on +// this file might be covered by the GNU General Public License. +// +// Alternative licenses for eCos may be arranged by contacting the +// copyright holder(s). +// ------------------------------------------- +//####ECOSGPLCOPYRIGHTEND#### +//========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): bartv +// Contributors: bartv +// Date: 2002-08-07 +// +//####DESCRIPTIONEND#### +//========================================================================== + +#include <pkgconf/devs_eth_ecosynth.h> + +#include <cyg/infra/cyg_type.h> +#include <cyg/infra/cyg_ass.h> +#include <cyg/hal/hal_arch.h> +#include <cyg/infra/diag.h> +#include <cyg/hal/drv_api.h> + +#define __ECOS 1 +#include <sys/types.h> +#include <cyg/io/eth/netdev.h> +#include <cyg/io/eth/eth_drv.h> +#include <cyg/io/eth/eth_drv_stats.h> + +#ifdef CYGPKG_NET +# include <net/if.h> +#else +# define IFF_PROMISC 0 +#endif + +#include <cyg/hal/hal_io.h> +#include "protocol.h" + +// ---------------------------------------------------------------------------- +// Device instances. The synthetic target ethernet package can support +// up to four ethernet devices, eth0 to eth3. A synth_eth structure +// holds the data that is specific to a given device. Each device +// needs an instance of this structure, followed by ETH_DRV_SC and +// NETDEVTAB_ENTRY macros. Another macro SYNTH_ETH_INSTANCE takes +// care of all that, to avoid unnecessary duplication of code here. +// +// NOTE: unfortunately this involves duplicating the eth_hwr_funs +// structure. This could be eliminated but it would require bypassing +// the ETH_DRV_SC macro. + +#define ETHERNET_MINTU 14 +#define ETHERNET_MAXTU 1514 + + +typedef struct synth_eth { + int synth_id; // Device id within the auxiliary + int up; // Has there been a call to start()? + int in_send; // Detect recursive calls + int tx_done; + unsigned long tx_key; // Allow mbuf's to be freed + volatile int rx_pending; // There is pending data. + int rx_len; // Length of buffered data. + unsigned char MAC[6]; // Obtained from the underlying ethernet device + cyg_vector_t interrupt; // Interrupt number allocated by the auxiliary + int multi_supported; // Does the driver support multicasting? + cyg_handle_t interrupt_handle; // Allow the ISR and DSR to be installed. + cyg_interrupt interrupt_data; + unsigned char tx_data[ETHERNET_MAXTU]; + unsigned char rx_data[ETHERNET_MAXTU]; +} synth_eth; + +#define SYNTH_ETH_INSTANCE( _number_) \ +static synth_eth synth_eth##_number_ = { \ + synth_id: -1, \ + up: 1, \ + in_send: 0, \ + tx_done: 0, \ + tx_key: 0L, \ + rx_pending: 0, \ + rx_len: 0, \ + MAC: { 0, 0, 0, 0, 0, 0 }, \ + interrupt: 0, \ + interrupt_handle: 0 \ +}; \ +ETH_DRV_SC(synth_eth_sc##_number_, \ + (void*) &synth_eth##_number_, \ + "eth" #_number_, \ + synth_eth_start, \ + synth_eth_stop, \ + synth_eth_ioctl, \ + synth_eth_can_send, \ + synth_eth_send, \ + synth_eth_recv, \ + synth_eth_deliver, \ + synth_eth_poll, \ + synth_eth_intvector); \ +NETDEVTAB_ENTRY(synth_eth_netdev##_number_, \ + "synth_eth" #_number_, \ + synth_eth_init, \ + &synth_eth_sc##_number_); + +#ifdef CYGVAR_DEVS_ETH_ECOSYNTH_ETH0 +SYNTH_ETH_INSTANCE(0); +#endif +#ifdef CYGVAR_DEVS_ETH_ECOSYNTH_ETH1 +SYNTH_ETH_INSTANCE(1); +#endif +#ifdef CYGVAR_DEVS_ETH_ECOSYNTH_ETH2 +SYNTH_ETH_INSTANCE(2); +#endif +#ifdef CYGVAR_DEVS_ETH_ECOSYNTH_ETH3 +SYNTH_ETH_INSTANCE(3); +#endif + +// ---------------------------------------------------------------------------- +// Data transmits. +// +// The eCos application will just send the data to the auxiliary, +// which will in turn pass it on to the rawether utility. There is no +// need for any response. Flow control is implicit: if the eCos +// application tries to send ethernet packets too quickly then those +// get passed on to the auxiliary, which in turn will pass them on to +// the rawether process. If rawether is still busy with the previous +// packet then the auxiliary will block on a pipe write, and in turn +// the eCos application will block. As long as rawether manages to +// complete its operations reasonably quickly these blocks should not +// be noticeable to the user. +// +// So can_send() should always return true for an interface that is up +// and running. The send operation needs to take the sg list, turn it +// into a single buffer, and transmit it to the auxiliary. At that +// point the transmission is already complete so eth_drv_dsr() should +// be called to call deliver() and release the buffer. +// +// However there are some complications. The first is polled operation, +// where eth_drv_dsr() is a no-op and should not really be called at +// all because there are no interrupts going off. The second is that +// calling eth_drv_dsr() directly will cause recursive operation: +// send() -> dsr -> can_send()/send() -> ... +// This is a bad idea, so can_send() has to check that we are not +// already inside a send(). Data transmission will proceed merrily +// once the send has returned. + +static int +synth_eth_can_send(struct eth_drv_sc* sc) +{ + synth_eth* eth = (synth_eth*)(sc->driver_private); + return synth_auxiliary_running && eth->up && !eth->in_send && !eth->tx_done; +} + +static void +synth_eth_send(struct eth_drv_sc* sc, + struct eth_drv_sg* sg_list, int sg_len, int total_len, + unsigned long key) +{ + synth_eth* eth = (synth_eth*)(sc->driver_private); + + CYG_PRECONDITION((total_len >= ETHERNET_MINTU) && (total_len <= ETHERNET_MAXTU), "Only normal-sized ethernet packets are supported"); + CYG_PRECONDITION(!eth->in_send && !eth->tx_done, "Ethernet device must not still be in use for transmits"); + + eth->in_send = 1; + eth->tx_key = key; + if (synth_auxiliary_running && eth->up) { + int i; + unsigned char* buf = eth->tx_data; + for (i = 0; i < sg_len; i++) { + memcpy(buf, (void*) sg_list[i].buf, sg_list[i].len); + buf += sg_list[i].len; + CYG_LOOP_INVARIANT(buf <= &(eth->tx_data[ETHERNET_MAXTU]), "sg list must not exceed ethernet MTU"); + } + CYG_POSTCONDITION(buf == &(eth->tx_data[total_len]), "sg list lengths should match total_len"); + + synth_auxiliary_xchgmsg(eth->synth_id, SYNTH_ETH_TX, 0, 0, eth->tx_data, total_len, + (void*) 0, (unsigned char*)0, (int*)0, 0); + } + + // The transfer has now completed, one way or another, so inform + // the higher-level code immediately. + eth->tx_done = 1; + eth_drv_dsr(eth->interrupt, 0, (cyg_addrword_t) sc); + eth->in_send = 0; +} + +// ---------------------------------------------------------------------------- +// Receives. +// +// These are rather more complicated because there are real interrupts +// involved, and polling needs to be supported as well. The actual +// transfer of data from auxiliary to eCos happens inside deliver(), +// and the data is buffered up in the synth_eth structure. All that +// needs to be done here is scatter the existing data into the +// sg_list. If higher-level code has run out of space then the +// sg_list may contain null pointers. + +static void +synth_eth_recv(struct eth_drv_sc* sc, struct eth_drv_sg* sg_list, int sg_len) +{ + synth_eth* eth = (synth_eth*)(sc->driver_private); + unsigned char* buf = eth->rx_data; + int len = eth->rx_len; + int i; + + for (i = 0; i < sg_len; i++) { + if (0 == sg_list[i].buf) { + break; + } else if (len <= sg_list[i].len) { + memcpy((void*)sg_list[i].buf, buf, len); + break; + } else { + memcpy((void*)sg_list[i].buf, buf, sg_list[i].len); + buf += sg_list[i].len; + len -= sg_list[i].len; + } + } +} + +// The ISR does not have to do anything, the DSR does the real work. +static cyg_uint32 +synth_eth_isr(cyg_vector_t vector, cyg_addrword_t data) +{ + cyg_drv_interrupt_acknowledge(vector); + return CYG_ISR_CALL_DSR; +} + +// The DSR also does not have to do very much. The data argument is +// actually the eth_drv_sc structure, which must match the vector. +// Interrupts only go off when there are pending receives, so set the +// rx_pending flag and call the generic DSR to do the real work. +static void +synth_eth_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data) +{ + struct eth_drv_sc* sc = (struct eth_drv_sc*) data; + synth_eth* eth = (synth_eth*)(sc->driver_private); + CYG_ASSERT(eth->interrupt == vector, "Interrupt vectors cannot change during a run"); + + eth->rx_pending = 1; + eth_drv_dsr(vector, count, data); +} + +// ---------------------------------------------------------------------------- +// Delivery. This is invoked by a thread inside the TCP/IP stack, or by +// the poll function. +static void +synth_eth_deliver(struct eth_drv_sc* sc) +{ + synth_eth* eth = (synth_eth*)(sc->driver_private); + + if (eth->tx_done) { + eth->tx_done = 0; + (*sc->funs->eth_drv->tx_done)(sc, eth->tx_key, 1); + } + while (eth->rx_pending) { + int more = 1; + eth->rx_pending = 0; + + while (more && eth->up && synth_auxiliary_running) { + synth_auxiliary_xchgmsg(eth->synth_id, SYNTH_ETH_RX, 0, 0, (void*) 0, 0, + &more, eth->rx_data, &(eth->rx_len), ETHERNET_MAXTU); + CYG_LOOP_INVARIANT(!more || (0 != eth->rx_len), "Auxiliary must send at least one packet if several are available"); + if (eth->rx_len > 0) { + CYG_ASSERT((eth->rx_len >= ETHERNET_MINTU) && (eth->rx_len <= ETHERNET_MAXTU), "Only normal-sized ethernet packets are supported"); + // Inform higher-level code that data is available. + // This should result in a call to recv() with a + // suitable sg_list. If out of memory, recv() + // will see a null pointer. + (*sc->funs->eth_drv->recv)(sc, eth->rx_len); + } + }; + } +} + + +// ---------------------------------------------------------------------------- +// Polling support. Transmits are relatively straightforward because +// all the hard work is handled by send(). Receives are rather more +// complicated because interrupts are disabled so we never know when +// there is really pending data. However deliver() will do the right +// thing even if there is no data, so simply faking up an interrupt +// is enough. This does mean extra traffic between application and +// auxiliary, but polling does rather imply that. +static void +synth_eth_poll(struct eth_drv_sc* sc) +{ + synth_eth* eth = (synth_eth*)(sc->driver_private); + if (synth_auxiliary_running && eth->up) { + eth->rx_pending = 1; + } + synth_eth_deliver(sc); +} + +static int +synth_eth_intvector(struct eth_drv_sc* sc) +{ + synth_eth* eth = (synth_eth*)(sc->driver_private); + return eth->interrupt; +} + +// ---------------------------------------------------------------------------- +// ioctl()'s. +// +// SET_MAC_ADDRESS is not currently implemented, and probably should +// not be implemented because the underlying ethernet device may not +// support it. +// +// SET_MC_ALL is supported if the underlying hardware does. This is +// needed for IPV6 support. More selective multicasting via +// SET_MC_LIST is not supported, because it imposes too heavy a +// requirement on the underlying Linux device. SET_MC_LIST can be +// used to disable multicast support. +// +// GET_IF_STATS_UD and GET_IF_STATS are not currently implemented +static int +synth_eth_ioctl(struct eth_drv_sc* sc, unsigned long key, void* data, int data_length) +{ + synth_eth* eth = (synth_eth*)(sc->driver_private); + int result = EINVAL; + + switch(key) { + case ETH_DRV_SET_MC_ALL: + { + if (eth->multi_supported) { + synth_auxiliary_xchgmsg(eth->synth_id, SYNTH_ETH_MULTIALL, 1, 0, (unsigned char*) 0, 0, + (void*)0, (unsigned char*)0, (int*)0, 0); + result = 0; + } + break; + } + case ETH_DRV_SET_MC_LIST: + { + struct eth_drv_mc_list* mcl = (struct eth_drv_mc_list*) data; + if (eth->multi_supported && (0 == mcl->len)) { + synth_auxiliary_xchgmsg(eth->synth_id, SYNTH_ETH_MULTIALL, 0, 0, (unsigned char*) 0, 0, + (void*)0, (unsigned char*)0, (int*)0, 0); + result = 0; + } + break; + } + default: + break; + } + + return result; +} + +// ---------------------------------------------------------------------------- +// Starting and stopping an interface. This includes restarting in +// promiscuous mode. +static void +synth_eth_start(struct eth_drv_sc* sc, unsigned char* enaddr, int flags) +{ + synth_eth* eth = (synth_eth*)(sc->driver_private); + + eth->up = 0; + eth->rx_pending = 0; + + if ((-1 != eth->synth_id) && synth_auxiliary_running) { + synth_auxiliary_xchgmsg(eth->synth_id, SYNTH_ETH_START, flags & IFF_PROMISC, 0, (void*) 0, 0, + (int*)0, (void*) 0, (int*) 0, 0); + } + eth->up = 1; + if (enaddr != (unsigned char*)0) { + memcpy(enaddr, eth->MAC, 6); + } +} + +static void +synth_eth_stop(struct eth_drv_sc* sc) +{ + synth_eth* eth = (synth_eth*)(sc->driver_private); + + eth->up = 0; + if ((-1 != eth->synth_id) && synth_auxiliary_running) { + synth_auxiliary_xchgmsg(eth->synth_id, SYNTH_ETH_STOP, 0, 0, (void*) 0, 0, + (int*) 0, (void*) 0, (int*) 0, 0); + } + eth->rx_pending = 0; +} + + +// ---------------------------------------------------------------------------- +// Initialization. +// +// This requires instantiating a device of class ethernet with a specific +// device name held in the eth_drv_sc structure. No additional device data +// is needed. If a device can be instantiated then the interrupt vector +// and the MAC address can be obtained, and an interrupt handler can be +// installed. +static bool +synth_eth_init(struct cyg_netdevtab_entry* ndp) +{ + bool result = false; + struct eth_drv_sc* sc = (struct eth_drv_sc*)(ndp->device_instance); + struct synth_eth* eth = (struct synth_eth*)(sc->driver_private); + + if (synth_auxiliary_running) { + eth->synth_id = synth_auxiliary_instantiate("devs/eth/synth/ecosynth", SYNTH_MAKESTRING(CYGPKG_DEVS_ETH_ECOSYNTH), "ethernet", + sc->dev_name, (const char*) 0); + + if (-1 != eth->synth_id) { + unsigned char data[7]; + result = true; + synth_auxiliary_xchgmsg(eth->synth_id, SYNTH_ETH_GETPARAMS, 0, 0, (const unsigned char*) 0, 0, + &(eth->interrupt), data, 0, 7); + memcpy(eth->MAC, data, 6); + eth->multi_supported = data[6]; + cyg_drv_interrupt_create(eth->interrupt, + 0, + (CYG_ADDRWORD) sc, + &synth_eth_isr, + &synth_eth_dsr, + &(eth->interrupt_handle), + &(eth->interrupt_data)); + cyg_drv_interrupt_attach(eth->interrupt_handle); + cyg_drv_interrupt_unmask(eth->interrupt); + } + } + (*sc->funs->eth_drv->init)(sc, eth->MAC); + return result; +}
new file mode 100644 --- /dev/null +++ b/packages/devs/watchdog/synth/current/ChangeLog @@ -0,0 +1,36 @@ +2002-09-04 Bart Veer <bartv@ecoscentric.com> + + * Synthetic target watchdog package created + +//=========================================================================== +//####ECOSGPLCOPYRIGHTBEGIN#### +// ------------------------------------------- +// This file is part of eCos, the Embedded Configurable Operating System. +// Copyright (C) 2002 Bart Veer +// +// eCos is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 or (at your option) any later version. +// +// eCos is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License along +// with eCos; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. +// +// As a special exception, if other files instantiate templates or use macros +// or inline functions from this file, or you compile this file and link it +// with other works to produce a work based on this file, this file does not +// by itself cause the resulting work to be covered by the GNU General Public +// License. However the source code for this file must still be made available +// in accordance with section (3) of the GNU General Public License. +// +// This exception does not invalidate any other reasons why a work based on +// this file might be covered by the GNU General Public License. +// ------------------------------------------- +//####ECOSGPLCOPYRIGHTEND#### +//=========================================================================== +
new file mode 100644 --- /dev/null +++ b/packages/devs/watchdog/synth/current/cdl/synth_watchdog.cdl @@ -0,0 +1,108 @@ +# ==================================================================== +# +# synth_watchdog.cdl +# +# Synthetic target watchdog package. +# +# ==================================================================== +#####ECOSGPLCOPYRIGHTBEGIN#### +## ------------------------------------------- +## This file is part of eCos, the Embedded Configurable Operating System. +## Copyright (C) 2002 Bart Veer +## +## eCos is free software; you can redistribute it and/or modify it under +## the terms of the GNU General Public License as published by the Free +## Software Foundation; either version 2 or (at your option) any later version. +## +## eCos is distributed in the hope that it will be useful, but WITHOUT ANY +## WARRANTY; without even the implied warranty of MERCHANTABILITY or +## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +## for more details. +## +## You should have received a copy of the GNU General Public License along +## with eCos; if not, write to the Free Software Foundation, Inc., +## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. +## +## As a special exception, if other files instantiate templates or use macros +## or inline functions from this file, or you compile this file and link it +## with other works to produce a work based on this file, this file does not +## by itself cause the resulting work to be covered by the GNU General Public +## License. However the source code for this file must still be made available +## in accordance with section (3) of the GNU General Public License. +## +## This exception does not invalidate any other reasons why a work based on +## this file might be covered by the GNU General Public License. +## +## Alternative licenses for eCos may be arranged by contacting the +## copyright holder(s). +## ------------------------------------------- +#####ECOSGPLCOPYRIGHTEND#### +# ==================================================================== +######DESCRIPTIONBEGIN#### +# +# Author(s): bartv +# Original data: bartv +# Contributors: +# Date: 2002-08-07 +# +#####DESCRIPTIONEND#### +# ==================================================================== + +cdl_package CYGPKG_DEVS_WATCHDOG_SYNTH { + display "Synthetic target watchdog support" + description " + The watchdog driver for the eCos synthetic target provides + emulation of a watchdog device: if the eCos application starts + the watchdog and fails to reset it regularly then the host-side + support will detect this and kill the eCos application with a + SIGPWR signal." + + parent CYGPKG_IO_WATCHDOG + implements CYGINT_WATCHDOG_HW_IMPLEMENTATIONS + implements CYGINT_WATCHDOG_RESETS_ON_TIMEOUT + + cdl_option CYGIMP_WATCHDOG_HARDWARE { + parent CYGPKG_IO_WATCHDOG_IMPLEMENTATION + display "use \"hardware\" watchdog" + default_value 1 + implements CYGINT_WATCHDOG_IMPLEMENTATIONS + compile synth_watchdog.cxx + description " + eCos provides several implementations of a watchdog device. + The default is to use the \"hardware\" implementation, which + for the synthetic target involves interacting with a + watchdog.tcl script running inside the I/O auxiliary." + } + + cdl_component CYGPKG_DEVS_WATCHDOG_SYNTH_OPTIONS { + display "Build options" + active_if CYGIMP_WATCHDOG_HARDWARE + flavor none + + description " + Package-specific build options including control over compiler + flags used only in building this package." + + cdl_option CYGPKG_DEVS_WATCHDOG_SYNTH_CFLAGS_ADD { + display "Additional compiler flags" + flavor data + no_define + default_value { "" } + description " + This option modifies the set of compiler flags for + building this package. These flags are used in addition + to the set of global flags." + } + cdl_option CYGPKG_DEVS_WATCHDOG_SYNTH_CFLAGS_REMOVE { + display "Suppressed compiler flags" + flavor data + no_define + default_value { "" } + description " + This option modifies the set of compiler flags for + building this package. These flags are removed from + the set of global flags if present." + } + } +} +
new file mode 100644 index 0000000000000000000000000000000000000000..738290f78f857fe3c8af532d77fb8953216e334f GIT binary patch literal 19131 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 X+v4lb&Z2wLfBW(O_Bli%w(kD{-TV-w
new file mode 100644 index 0000000000000000000000000000000000000000..c3820843539183c6caa6fb62c9f37cb253aa42f9 GIT binary patch literal 18699 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 W(}p||jI>)VVj6ziI)y^Ug8m;qr8Ud|
new file mode 100644 --- /dev/null +++ b/packages/devs/watchdog/synth/current/doc/devs-watchdog-synth.html @@ -0,0 +1,526 @@ +<!-- Copyright (C) 2002 Red Hat, Inc. --> +<!-- This material may be distributed only subject to the terms --> +<!-- and conditions set forth in the Open Publication License, v1.0 --> +<!-- or later (the latest version is presently available at --> +<!-- http://www.opencontent.org/openpub/). --> +<!-- Distribution of the work or derivative of the work in any --> +<!-- standard (paper) book form is prohibited unless prior --> +<!-- permission is obtained from the copyright holder. --> +<HTML +><HEAD +><TITLE +>Synthetic Target Watchdog Device</TITLE +><meta name="MSSmartTagsPreventParsing" content="TRUE"> +<META +NAME="GENERATOR" +CONTENT="Modular DocBook HTML Stylesheet Version 1.76b+ +"></HEAD +><BODY +CLASS="REFENTRY" +BGCOLOR="#FFFFFF" +TEXT="#000000" +LINK="#0000FF" +VLINK="#840084" +ALINK="#0000FF" +><H1 +><A +NAME="DEVS-WATCHDOG-SYNTH">Synthetic Target Watchdog Device</H1 +><DIV +CLASS="REFNAMEDIV" +><A +NAME="AEN4" +></A +><H2 +>Name</H2 +>Synthetic Target Watchdog Device -- Emulate watchdog hardware in the synthetic target</DIV +><DIV +CLASS="REFSECT1" +><A +NAME="AEN7" +></A +><H2 +>Overview</H2 +><P +>Some target hardware comes equipped with a watchdog timer. Application +code can start this timer and after a certain period of time, +typically a second, the watchdog will trigger. Usually this causes the +hardware to reboot. The application can prevent this by regularly +resetting the watchdog. An automatic reboot can be very useful when +deploying hardware in the field: a hardware glitch could cause the +unit to hang; or the software could receive an unexpected sequence of +inputs, never seen in the laboratory, causing the system to lock up. +Often the hardware is still functional, and a reboot sorts out the +problem with only a brief interruption in service. + </P +><P +>The synthetic target watchdog package emulates watchdog hardware. +During system initialization watchdog device will be instantiated, +and the <TT +CLASS="FILENAME" +>watchdog.tcl</TT +> script will be loaded by the +I/O auxiliary. When the eCos application starts the watchdog device, +the <TT +CLASS="FILENAME" +>watchdog.tcl</TT +> script will start checking the +state of the eCos application at one second intervals. A watchdog +reset call simply involves a message to the I/O auxiliary. If the +<TT +CLASS="FILENAME" +>watchdog.tcl</TT +> script detects that a second has +<A +HREF="devs-watchdog-synth.html#SYNTH-WATCHDOG-WALLCLOCK-ELAPSED" +>elapsed</A +> +without a reset then it will send a <TT +CLASS="LITERAL" +>SIGPWR</TT +> signal +to the eCos application, causing the latter to terminate. If gdb is +being used to run the application, the user will get a chance to +investigate what is happening. This behaviour is different from real +hardware in that there is no automatic reboot, but the synthetic +target is used only for development purposes, not deployment in the +field: if a reboot is desired then this can be achieved very easily +by using gdb commands to run another instance of the application. + </P +></DIV +><DIV +CLASS="REFSECT1" +><A +NAME="DEVS-WATCHDOG-SYNTH-INSTALL" +></A +><H2 +>Installation</H2 +><P +>Before a synthetic target eCos application can use a watchdog device +it is necessary to build and install host-side support. The relevant +code resides in the <TT +CLASS="FILENAME" +>host</TT +> +subdirectory of the synthetic target watchdog package, and building it +involves the standard <B +CLASS="COMMAND" +>configure</B +>, +<B +CLASS="COMMAND" +>make</B +> and <B +CLASS="COMMAND" +>make install</B +> steps. The +implementation of the watchdog support does not require any +executables, just a Tcl script <TT +CLASS="FILENAME" +>watchdog.tcl</TT +> and +some support files, so the <B +CLASS="COMMAND" +>make</B +> step is a no-op. + </P +><P +>There are two main ways of building the host-side software. It is +possible to build both the generic host-side software and all +package-specific host-side software, including the watchdog support, +in a single build tree. This involves using the +<B +CLASS="COMMAND" +>configure</B +> script at the toplevel of the eCos +repository. For more information on this, see the +<TT +CLASS="FILENAME" +>README.host</TT +> file at the top of the repository. +Note that if you have an existing build tree which does not include +the synthetic target watchdog support then it will be necessary to +rerun the toplevel configure script: the search for appropriate +packages happens at configure time. + </P +><P +>The alternative is to build just the host-side for this package. +This requires a separate build directory, building directly in the +source tree is disallowed. The <B +CLASS="COMMAND" +>configure</B +> options +are much the same as for a build from the toplevel, and the +<TT +CLASS="FILENAME" +>README.host</TT +> file can be consulted for more +details. It is essential that the watchdog support be configured with +the same <TT +CLASS="OPTION" +>--prefix</TT +> option as other eCos host-side +software, especially the I/O auxiliary provided by the architectural +synthetic target HAL package, otherwise the I/O auxiliary will be +unable to locate the watchdog support. + </P +></DIV +><DIV +CLASS="REFSECT1" +><A +NAME="SYNTH-WATCHDOG-TARGET-CONFIG" +></A +><H2 +>Target-side +Configuration</H2 +><P +>The watchdog device depends on the generic watchdog support, +<TT +CLASS="VARNAME" +>CYGPKG_IO_WATCHDOG</TT +>: if the generic support is +absent then the watchdog device will be inactive. Some templates +include this generic package by default, but not all. If the +configuration does not include the generic package then it can be +added using the eCos configuration tools, for example: + </P +><TABLE +BORDER="5" +BGCOLOR="#E0E0F0" +WIDTH="70%" +><TR +><TD +><PRE +CLASS="SCREEN" +>$ ecosconfig add CYGPKG_IO_WATCHDOG</PRE +></TD +></TR +></TABLE +><P +>By default the configuration will use the hardware-specific support, +i.e. this package. However the generic watchdog package contains an +alternative implementation using the kernel alarm facility, and that +implementation can be selected if desired. However usually it will be +better to rely on an external watchdog facility as provided by the I/O +auxiliary and the <TT +CLASS="FILENAME" +>watchdog.tcl</TT +> script: if there +are serious problems within the application, for example memory +corruption, then an internal software-only implementation will not be +reliable. + </P +><P +>The watchdog resolution is currently fixed to one second: if the +device does not receive a reset signal at least once a second then +the watchdog will trigger and the eCos application will be terminated +with a <TT +CLASS="LITERAL" +>SIGPWR</TT +> signal. The current implementation +does not allow this resolution to be changed. + </P +><P +>On some targets the watchdog device does not perform a hard reset. +Instead the device works more or less via the interrupt subsystem, +allowing application code to install action routines that will be +called when the watchdog triggers. The synthetic target watchdog +support effectively does perform a hard reset, by sending a +<TT +CLASS="LITERAL" +>SIGPWR</TT +> signal to the eCos application, and there is +no support for action routines. + </P +><P +>The synthetic target watchdog package provides some configuration +options for manipulating the compiler flags used for building the +target-side code. That code is fairly simple, so for nearly all +applications the default flags will suffice. + </P +><P +>It should be noted that the watchdog device is subject to selective +linking. Unless some code explicitly references the device, for +example by calling the start and reset functions, the watchdog support +will not appear in the final executable. This is desirable because a +watchdog device has no effect until started. + </P +></DIV +><DIV +CLASS="REFSECT1" +><A +NAME="SYNTH-WATCHDOG-WALLCLOCK-ELAPSED" +></A +><H2 +>Wallclock versus Elapsed Time</H2 +><P +>On real hardware the watchdog device uses wallclock time: if the +device does not receive a reset signal within a set period of time +then the watchdog will trigger. When developing for the synthetic +target this is not always appropriate. There may be other processes +running, using up some or most of the cpu time. For example, the +application may be written such that it will issue a reset after some +calculations which are known to complete within half a second, well +within the one-second resolution of the watchdog device. However if +other Linux processes are running then the synthetic target +application may get timesliced, and half a second of computation may +take several seconds of wallclock time. + </P +><P +>Another problem with using wallclock time is that it interferes with +debugging: if the application hits a breakpoint then it is unlikely +that the user will manage to restart it in less than a second, and the +watchdog will not get reset in time. + </P +><P +>To avoid these problems the synthetic target watchdog normally uses +consumed cpu time rather than wallclock time. If the application is +timesliced or if it is halted inside gdb then it does not consume any +cpu time. The application actually has to spend a whole second's worth +of cpu cycles without issuing a reset before the watchdog triggers. + </P +><P +>However using consumed cpu time is not a perfect solution either. If +the application makes blocking system calls then it is not using cpu +time. Interaction with the I/O auxiliary involves system calls, but +these should take only a short amount of time so their effects can be +ignored. If the application makes direct system calls such as +<TT +CLASS="FUNCTION" +>cyg_hal_sys_read</TT +> then the system behaviour +becomes undefined. In addition by default the idle thread will make +blocking <TT +CLASS="FUNCTION" +>select</TT +> system calls, effectively waiting +until an interrupt occurs. If an application spends much of its time +idle then the watchdog device may take much longer to trigger than +expected. It may be desirable to enable the synthetic target HAL +configuration option <TT +CLASS="VARNAME" +>CYGIMP_HAL_IDLE_THREAD_SPIN</TT +>, +causing the idle thread to spin rather than block, at the cost of +wasted cpu cycles. + </P +><P +>The default is to use consumed cpu time, but this can be changed in +the target definition file: + </P +><TABLE +BORDER="5" +BGCOLOR="#E0E0F0" +WIDTH="70%" +><TR +><TD +><PRE +CLASS="PROGRAMLISTING" +>synth_device watchdog { + use wallclock_time + … +}</PRE +></TD +></TR +></TABLE +></DIV +><DIV +CLASS="REFSECT1" +><A +NAME="SYNTH-WATCHDOG-GUI" +></A +><H2 +>User Interface</H2 +><P +>When the synthetic target is run in graphical mode the watchdog device +extends the user interface in two ways. The <SPAN +CLASS="GUIMENU" +>Help</SPAN +> +menu is extended with an entry for the watchdog-specific +documentation. There is also a graphical display of the current state +of the watchdog. Initially the watchdog is asleep: + </P +><DIV +CLASS="INFORMALFIGURE" +><A +NAME="AEN60"><P +></P +><DIV +CLASS="MEDIAOBJECT" +><P +><IMG +SRC="asleep.gif" +ALIGN="CENTER"></P +></DIV +><P +></P +></DIV +><P +>When application code starts the device the watchdog will begin to +keep an eye on things (or occasionally both eyes). + </P +><DIV +CLASS="INFORMALFIGURE" +><A +NAME="AEN65"><P +></P +><DIV +CLASS="MEDIAOBJECT" +><P +><IMG +SRC="awake.gif" +ALIGN="CENTER"></P +></DIV +><P +></P +></DIV +><P +>If the watchdog triggers the display will change again, and optionally +the user can receive an audible alert. The location of the watchdog +display within the I/O auxiliary's window can be controlled via +a <B +CLASS="COMMAND" +>watchdog_pack</B +> entry in the target definition +file. For example the following can be used to put the watchdog +display to the right of the central text window: + </P +><TABLE +BORDER="5" +BGCOLOR="#E0E0F0" +WIDTH="70%" +><TR +><TD +><PRE +CLASS="PROGRAMLISTING" +>synth_device watchdog { + watchdog_pack -in .main.e -side top + … +}</PRE +></TD +></TR +></TABLE +><P +>The user interface section of the generic synthetic target HAL +documentation can be consulted for more information on window packing. + </P +><P +>By default the watchdog support will not generate an audible alert +when the watchdog triggers, to avoid annoying colleagues. Sound can be +enabled in the target definition file, and two suitable files +<TT +CLASS="FILENAME" +>sound1.au</TT +> and <TT +CLASS="FILENAME" +>sound2.au</TT +> are +supplied as standard: + </P +><TABLE +BORDER="5" +BGCOLOR="#E0E0F0" +WIDTH="70%" +><TR +><TD +><PRE +CLASS="PROGRAMLISTING" +>synth_device watchdog { + sound sound1.au + … +}</PRE +></TD +></TR +></TABLE +><P +>An absolute path can be specified if desired: + </P +><TABLE +BORDER="5" +BGCOLOR="#E0E0F0" +WIDTH="70%" +><TR +><TD +><PRE +CLASS="PROGRAMLISTING" +>synth_device watchdog { + sound /usr/share/emacs/site-lisp/emacspeak/sounds/default-8k/alarm.au + … +}</PRE +></TD +></TR +></TABLE +><P +>Sound facilities are not built into the I/O auxiliary itself, instead +an external program is used. The default player is +<B +CLASS="COMMAND" +>play</B +>, a front-end to the +<SPAN +CLASS="APPLICATION" +>sox</SPAN +> application shipped with some Linux +distributions. If another player should be used then this can be +specified in the target definition file: + </P +><TABLE +BORDER="5" +BGCOLOR="#E0E0F0" +WIDTH="70%" +><TR +><TD +><PRE +CLASS="PROGRAMLISTING" +>synth_device watchdog { + … + sound_player my_sound_player</PRE +></TD +></TR +></TABLE +><P +>The specified program will be run in the background with a single +argument, the sound file. + </P +></DIV +><DIV +CLASS="REFSECT1" +><A +NAME="DEVS-WATCHDOG-SYNTH-ARGS" +></A +><H2 +>Command Line Arguments</H2 +><P +>The watchdog support does not use any command line arguments. All +configuration is handled through the target definition file. + </P +></DIV +><DIV +CLASS="REFSECT1" +><A +NAME="DEVS-WATCHDOG-SYNTH-HOOKS" +></A +><H2 +>Hooks</H2 +><P +>The watchdog support does not provide any hooks for use by other +scripts. There is rarely any need for customizing the system's +behaviour when a watchdog triggers because those should be rare +events, even during application development. + </P +></DIV +><DIV +CLASS="REFSECT1" +><A +NAME="DEVS-WATCHDOG-SYNTH-TCL" +></A +><H2 +>Additional Tcl Procedures</H2 +><P +>The watchdog support does not provide any additional Tcl procedures or +variables for use by other scripts. + </P +></DIV +></BODY +></HTML +> \ No newline at end of file
new file mode 100644 --- /dev/null +++ b/packages/devs/watchdog/synth/current/doc/makefile @@ -0,0 +1,34 @@ +#============================================================================= +# +# makefile +# +# For building the synthetic target watchdog package documentation +# +#============================================================================= +#####COPYRIGHTBEGIN#### +# +# =============================================================== +# Copyright (C) 2002 Bart Veer +# This material may be distributed only subject to the terms +# and conditions set forth in the Open Publication License, v1.0 +# or later (the latest version is presently available at +# http://www.opencontent.org/openpub/) +# =============================================================== +# +#####COPYRIGHTEND#### +#============================================================================= +#####DESCRIPTIONBEGIN#### +# +# Author(s): bartv +# Date: 2002-09-09 +#####DESCRIPTIONEND#### +#============================================================================= + +TOPLEVEL := ../../../../.. +MAIN_SGML := synth_watchdog.sgml +MAIN_HTML := devs-watchdog-synth.html +MAIN_PDF := devs-watchdog-synth.pdf +OTHER_SGML := +PICTURES := + +include $(TOPLEVEL)/pkgconf/rules.doc
new file mode 100644 --- /dev/null +++ b/packages/devs/watchdog/synth/current/doc/synth_watchdog.sgml @@ -0,0 +1,336 @@ +<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V3.1//EN"> + +<!-- {{{ Banner --> + +<!-- =============================================================== --> +<!-- --> +<!-- synth_watchdog.sgml --> +<!-- --> +<!-- Synthetic target watchdog device --> +<!-- --> +<!-- =============================================================== --> +<!-- ####COPYRIGHTBEGIN#### --> +<!-- --> +<!-- =============================================================== --> +<!-- Copyright (C) 2002 Bart Veer --> +<!-- This material may be distributed only subject to the terms --> +<!-- and conditions set forth in the Open Publication License, v1.0 --> +<!-- or later (the latest version is presently available at --> +<!-- http://www.opencontent.org/openpub/) --> +<!-- =============================================================== --> +<!-- --> +<!-- ####COPYRIGHTEND#### --> +<!-- =============================================================== --> +<!-- #####DESCRIPTIONBEGIN#### --> +<!-- --> +<!-- Author(s): bartv --> +<!-- Contact(s): bartv --> +<!-- Date: 2002/09/09 --> +<!-- Version: 0.01 --> +<!-- --> +<!-- ####DESCRIPTIONEND#### --> +<!-- =============================================================== --> + +<!-- }}} --> + +<refentry id="devs-watchdog-synth"> + <refmeta> + <refentrytitle>Synthetic Target Watchdog Device</refentrytitle> + </refmeta> + <refnamediv> + <refname>Synthetic Target Watchdog Device</refname> + <refpurpose>Emulate watchdog hardware in the synthetic target</refpurpose> + </refnamediv> + + <refsect1><title>Overview</title> + <para> +Some target hardware comes equipped with a watchdog timer. Application +code can start this timer and after a certain period of time, +typically a second, the watchdog will trigger. Usually this causes the +hardware to reboot. The application can prevent this by regularly +resetting the watchdog. An automatic reboot can be very useful when +deploying hardware in the field: a hardware glitch could cause the +unit to hang; or the software could receive an unexpected sequence of +inputs, never seen in the laboratory, causing the system to lock up. +Often the hardware is still functional, and a reboot sorts out the +problem with only a brief interruption in service. + </para> + <para> +The synthetic target watchdog package emulates watchdog hardware. +During system initialization watchdog device will be instantiated, +and the <filename>watchdog.tcl</filename> script will be loaded by the +I/O auxiliary. When the eCos application starts the watchdog device, +the <filename>watchdog.tcl</filename> script will start checking the +state of the eCos application at one second intervals. A watchdog +reset call simply involves a message to the I/O auxiliary. If the +<filename>watchdog.tcl</filename> script detects that a second has +<link linkend="synth-watchdog-wallclock-elapsed">elapsed</link> +without a reset then it will send a <literal>SIGPWR</literal> signal +to the eCos application, causing the latter to terminate. If gdb is +being used to run the application, the user will get a chance to +investigate what is happening. This behaviour is different from real +hardware in that there is no automatic reboot, but the synthetic +target is used only for development purposes, not deployment in the +field: if a reboot is desired then this can be achieved very easily +by using gdb commands to run another instance of the application. + </para> + </refsect1> + + <refsect1 id="devs-watchdog-synth-install"><title>Installation</title> + <para> +Before a synthetic target eCos application can use a watchdog device +it is necessary to build and install host-side support. The relevant +code resides in the <filename class="directory">host</filename> +subdirectory of the synthetic target watchdog package, and building it +involves the standard <command>configure</command>, +<command>make</command> and <command>make install</command> steps. The +implementation of the watchdog support does not require any +executables, just a Tcl script <filename>watchdog.tcl</filename> and +some support files, so the <command>make</command> step is a no-op. + </para> + <para> +There are two main ways of building the host-side software. It is +possible to build both the generic host-side software and all +package-specific host-side software, including the watchdog support, +in a single build tree. This involves using the +<command>configure</command> script at the toplevel of the eCos +repository. For more information on this, see the +<filename>README.host</filename> file at the top of the repository. +Note that if you have an existing build tree which does not include +the synthetic target watchdog support then it will be necessary to +rerun the toplevel configure script: the search for appropriate +packages happens at configure time. + </para> + <para> +The alternative is to build just the host-side for this package. +This requires a separate build directory, building directly in the +source tree is disallowed. The <command>configure</command> options +are much the same as for a build from the toplevel, and the +<filename>README.host</filename> file can be consulted for more +details. It is essential that the watchdog support be configured with +the same <option>--prefix</option> option as other eCos host-side +software, especially the I/O auxiliary provided by the architectural +synthetic target HAL package, otherwise the I/O auxiliary will be +unable to locate the watchdog support. + </para> + </refsect1> + + <refsect1 id="synth-watchdog-target-config"><title>Target-side +Configuration</title> + <para> +The watchdog device depends on the generic watchdog support, +<varname>CYGPKG_IO_WATCHDOG</varname>: if the generic support is +absent then the watchdog device will be inactive. Some templates +include this generic package by default, but not all. If the +configuration does not include the generic package then it can be +added using the eCos configuration tools, for example: + </para> + <screen> +$ ecosconfig add CYGPKG_IO_WATCHDOG +</screen> + <para> +By default the configuration will use the hardware-specific support, +i.e. this package. However the generic watchdog package contains an +alternative implementation using the kernel alarm facility, and that +implementation can be selected if desired. However usually it will be +better to rely on an external watchdog facility as provided by the I/O +auxiliary and the <filename>watchdog.tcl</filename> script: if there +are serious problems within the application, for example memory +corruption, then an internal software-only implementation will not be +reliable. + </para> + <para> +The watchdog resolution is currently fixed to one second: if the +device does not receive a reset signal at least once a second then +the watchdog will trigger and the eCos application will be terminated +with a <literal>SIGPWR</literal> signal. The current implementation +does not allow this resolution to be changed. + </para> + <para> +On some targets the watchdog device does not perform a hard reset. +Instead the device works more or less via the interrupt subsystem, +allowing application code to install action routines that will be +called when the watchdog triggers. The synthetic target watchdog +support effectively does perform a hard reset, by sending a +<literal>SIGPWR</literal> signal to the eCos application, and there is +no support for action routines. + </para> + <para> +The synthetic target watchdog package provides some configuration +options for manipulating the compiler flags used for building the +target-side code. That code is fairly simple, so for nearly all +applications the default flags will suffice. + </para> + <para> +It should be noted that the watchdog device is subject to selective +linking. Unless some code explicitly references the device, for +example by calling the start and reset functions, the watchdog support +will not appear in the final executable. This is desirable because a +watchdog device has no effect until started. + </para> + </refsect1> + + <refsect1 id="synth-watchdog-wallclock-elapsed"><title>Wallclock versus Elapsed Time</title> + <para> +On real hardware the watchdog device uses wallclock time: if the +device does not receive a reset signal within a set period of time +then the watchdog will trigger. When developing for the synthetic +target this is not always appropriate. There may be other processes +running, using up some or most of the cpu time. For example, the +application may be written such that it will issue a reset after some +calculations which are known to complete within half a second, well +within the one-second resolution of the watchdog device. However if +other Linux processes are running then the synthetic target +application may get timesliced, and half a second of computation may +take several seconds of wallclock time. + </para> + <para> +Another problem with using wallclock time is that it interferes with +debugging: if the application hits a breakpoint then it is unlikely +that the user will manage to restart it in less than a second, and the +watchdog will not get reset in time. + </para> + <para> +To avoid these problems the synthetic target watchdog normally uses +consumed cpu time rather than wallclock time. If the application is +timesliced or if it is halted inside gdb then it does not consume any +cpu time. The application actually has to spend a whole second's worth +of cpu cycles without issuing a reset before the watchdog triggers. + </para> + <para> +However using consumed cpu time is not a perfect solution either. If +the application makes blocking system calls then it is not using cpu +time. Interaction with the I/O auxiliary involves system calls, but +these should take only a short amount of time so their effects can be +ignored. If the application makes direct system calls such as +<function>cyg_hal_sys_read</function> then the system behaviour +becomes undefined. In addition by default the idle thread will make +blocking <function>select</function> system calls, effectively waiting +until an interrupt occurs. If an application spends much of its time +idle then the watchdog device may take much longer to trigger than +expected. It may be desirable to enable the synthetic target HAL +configuration option <varname>CYGIMP_HAL_IDLE_THREAD_SPIN</varname>, +causing the idle thread to spin rather than block, at the cost of +wasted cpu cycles. + </para> + <para> +The default is to use consumed cpu time, but this can be changed in +the target definition file: + </para> + <programlisting> +synth_device watchdog { + use wallclock_time + … +} +</programlisting> + </refsect1> + + <refsect1 id="synth-watchdog-gui"><title>User Interface</title> + <para> +When the synthetic target is run in graphical mode the watchdog device +extends the user interface in two ways. The <guimenu>Help</guimenu> +menu is extended with an entry for the watchdog-specific +documentation. There is also a graphical display of the current state +of the watchdog. Initially the watchdog is asleep: + </para> + <informalfigure PgWide=1> + <mediaobject> + <imageobject> + <imagedata fileref="asleep.gif" format="gif" Scalefit=1 Align="Center"> + </imageobject> + </mediaobject> + </informalfigure> + <para> +When application code starts the device the watchdog will begin to +keep an eye on things (or occasionally both eyes). + </para> + <informalfigure PgWide=1> + <mediaobject> + <imageobject> + <imagedata fileref="awake.gif" format="gif" Scalefit=1 Align="Center"> + </imageobject> + </mediaobject> + </informalfigure> + <para> +If the watchdog triggers the display will change again, and optionally +the user can receive an audible alert. The location of the watchdog +display within the I/O auxiliary's window can be controlled via +a <command>watchdog_pack</command> entry in the target definition +file. For example the following can be used to put the watchdog +display to the right of the central text window: + </para> + <programlisting> +synth_device watchdog { + watchdog_pack -in .main.e -side top + … +} +</programlisting> + <para> +The user interface section of the generic synthetic target HAL +documentation can be consulted for more information on window packing. + </para> + <para> +By default the watchdog support will not generate an audible alert +when the watchdog triggers, to avoid annoying colleagues. Sound can be +enabled in the target definition file, and two suitable files +<filename>sound1.au</filename> and <filename>sound2.au</filename> are +supplied as standard: + </para> + <programlisting> +synth_device watchdog { + sound sound1.au + … +} +</programlisting> + <para> +An absolute path can be specified if desired: + </para> + <programlisting> +synth_device watchdog { + sound /usr/share/emacs/site-lisp/emacspeak/sounds/default-8k/alarm.au + … +} +</programlisting> + <para> +Sound facilities are not built into the I/O auxiliary itself, instead +an external program is used. The default player is +<command>play</command>, a front-end to the +<application>sox</application> application shipped with some Linux +distributions. If another player should be used then this can be +specified in the target definition file: + </para> + <programlisting> +synth_device watchdog { + … + sound_player my_sound_player +</programlisting> + <para> +The specified program will be run in the background with a single +argument, the sound file. + </para> + </refsect1> + + <refsect1 id="devs-watchdog-synth-args"><title>Command Line Arguments</title> + <para> +The watchdog support does not use any command line arguments. All +configuration is handled through the target definition file. + </para> + </refsect1> + + <refsect1 id="devs-watchdog-synth-hooks"><title>Hooks</title> + <para> +The watchdog support does not provide any hooks for use by other +scripts. There is rarely any need for customizing the system's +behaviour when a watchdog triggers because those should be rare +events, even during application development. + </para> + </refsect1> + + <refsect1 id="devs-watchdog-synth-tcl"><title>Additional Tcl Procedures</title> + <para> +The watchdog support does not provide any additional Tcl procedures or +variables for use by other scripts. + </para> + </refsect1> + +</refentry>
new file mode 100644 --- /dev/null +++ b/packages/devs/watchdog/synth/current/host/Makefile.am @@ -0,0 +1,61 @@ +## Process this file with automake to produce Makefile.in +## ===================================================================== +## +## Makefile.am +## +## Build support for the host-side synthetic target support, +## the watchdog package +## +## ===================================================================== +######COPYRIGHTBEGIN#### +# +# ---------------------------------------------------------------------------- +# Copyright (C) 2002 Bart Veer +# +# This file is part of the eCos synthetic target ethernet support. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the Free +# Software Foundation; either version 2 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, write to the Free Software Foundation, Inc., +# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# ---------------------------------------------------------------------------- +# +######COPYRIGHTEND#### +## ===================================================================== +#######DESCRIPTIONBEGIN#### +## +## Author(s): bartv +## Contact(s): bartv +## Date: 2002/09/04 +## Version: 0.01 +## +######DESCRIPTIONEND#### +## ===================================================================== + +AUTOMAKE_OPTIONS = 1.3 foreign + +## Only some platforms are supported. Having the configure script throw +## an error when attempting to configure on an unsupported platform +## would be a mistake, since that would prevent any configury from +## the toplevel on unsupported platforms. Instead an automake conditional +## is used, leading to null makefiles on unsupported platforms. + +if SUPPORTED + +## The only thing that needs to be installed is a Tcl script and some +## data files. +watchdogdir = $(libexecdir)/ecos/@PACKAGE_INSTALL@ +watchdog_DATA = watchdog.tcl \ + watchdog.tdf \ + alarm.gif doghouse.gif eye.gif asleep.gif \ + sound1.au sound2.au +endif
new file mode 100644 --- /dev/null +++ b/packages/devs/watchdog/synth/current/host/Makefile.in @@ -0,0 +1,288 @@ +# Makefile.in generated automatically by automake 1.4-p5 from Makefile.am + +# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +######COPYRIGHTBEGIN#### +# +# ---------------------------------------------------------------------------- +# Copyright (C) 2002 Bart Veer +# +# This file is part of the eCos synthetic target ethernet support. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the Free +# Software Foundation; either version 2 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, write to the Free Software Foundation, Inc., +# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# ---------------------------------------------------------------------------- +# +######COPYRIGHTEND#### +#######DESCRIPTIONBEGIN#### +######DESCRIPTIONEND#### + + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DESTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = . + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_alias = @host_alias@ +host_triplet = @host@ +CC = @CC@ +CXX = @CXX@ +ECOS_REPOSITORY = @ECOS_REPOSITORY@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MSVC_SRCDIR = @MSVC_SRCDIR@ +PACKAGE = @PACKAGE@ +PACKAGE_DIR = @PACKAGE_DIR@ +PACKAGE_INSTALL = @PACKAGE_INSTALL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +VERSION = @VERSION@ +ecos_CFLAGS = @ecos_CFLAGS@ +ecos_CXXFLAGS = @ecos_CXXFLAGS@ +ecos_INCLUDES = @ecos_INCLUDES@ +ecos_LDADD = @ecos_LDADD@ +ecos_LIBS = @ecos_LIBS@ +ecos_infra_incdir = @ecos_infra_incdir@ +ecos_infra_libdir = @ecos_infra_libdir@ +ecos_libcdl_incdir = @ecos_libcdl_incdir@ +ecos_libcdl_libdir = @ecos_libcdl_libdir@ +ecos_tk_libs = @ecos_tk_libs@ + +AUTOMAKE_OPTIONS = 1.3 foreign + +@SUPPORTED_TRUE@watchdogdir = @SUPPORTED_TRUE@$(libexecdir)/ecos/@PACKAGE_INSTALL@ +@SUPPORTED_TRUE@watchdog_DATA = @SUPPORTED_TRUE@watchdog.tcl \ +@SUPPORTED_TRUE@ watchdog.tdf \ +@SUPPORTED_TRUE@ alarm.gif doghouse.gif eye.gif asleep.gif \ +@SUPPORTED_TRUE@ sound1.au sound2.au +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +mkinstalldirs = $(SHELL) $(top_srcdir)/../../../../../../acsupport/mkinstalldirs +CONFIG_CLEAN_FILES = +DATA = $(watchdog_DATA) + +DIST_COMMON = Makefile.am Makefile.in acinclude.m4 aclocal.m4 configure \ +configure.in + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = gtar +GZIP_ENV = --best +all: all-redirect +.SUFFIXES: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES) + cd $(top_builddir) \ + && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status + +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ configure.in acinclude.m4 + cd $(srcdir) && $(ACLOCAL) + +config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck +$(srcdir)/configure: @MAINTAINER_MODE_TRUE@$(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES) + cd $(srcdir) && $(AUTOCONF) + +install-watchdogDATA: $(watchdog_DATA) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(watchdogdir) + @list='$(watchdog_DATA)'; for p in $$list; do \ + if test -f $(srcdir)/$$p; then \ + echo " $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(watchdogdir)/$$p"; \ + $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(watchdogdir)/$$p; \ + else if test -f $$p; then \ + echo " $(INSTALL_DATA) $$p $(DESTDIR)$(watchdogdir)/$$p"; \ + $(INSTALL_DATA) $$p $(DESTDIR)$(watchdogdir)/$$p; \ + fi; fi; \ + done + +uninstall-watchdogDATA: + @$(NORMAL_UNINSTALL) + list='$(watchdog_DATA)'; for p in $$list; do \ + rm -f $(DESTDIR)$(watchdogdir)/$$p; \ + done +tags: TAGS +TAGS: + + +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + -rm -rf $(distdir) + GZIP=$(GZIP_ENV) $(TAR) zxf $(distdir).tar.gz + mkdir $(distdir)/=build + mkdir $(distdir)/=inst + dc_install_base=`cd $(distdir)/=inst && pwd`; \ + cd $(distdir)/=build \ + && ../configure --srcdir=.. --prefix=$$dc_install_base \ + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) dvi \ + && $(MAKE) $(AM_MAKEFLAGS) check \ + && $(MAKE) $(AM_MAKEFLAGS) install \ + && $(MAKE) $(AM_MAKEFLAGS) installcheck \ + && $(MAKE) $(AM_MAKEFLAGS) dist + -rm -rf $(distdir) + @banner="$(distdir).tar.gz is ready for distribution"; \ + dashes=`echo "$$banner" | sed s/./=/g`; \ + echo "$$dashes"; \ + echo "$$banner"; \ + echo "$$dashes" +dist: distdir + -chmod -R a+r $(distdir) + GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir) + -rm -rf $(distdir) +dist-all: distdir + -chmod -R a+r $(distdir) + GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir) + -rm -rf $(distdir) +distdir: $(DISTFILES) + -rm -rf $(distdir) + mkdir $(distdir) + -chmod 777 $(distdir) + here=`cd $(top_builddir) && pwd`; \ + top_distdir=`cd $(distdir) && pwd`; \ + distdir=`cd $(distdir) && pwd`; \ + cd $(top_srcdir) \ + && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --foreign Makefile + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + if test -d $$d/$$file; then \ + cp -pr $$d/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ + done +info-am: +info: info-am +dvi-am: +dvi: dvi-am +check-am: all-am +check: check-am +installcheck-am: +installcheck: installcheck-am +install-exec-am: +install-exec: install-exec-am + +install-data-am: install-watchdogDATA +install-data: install-data-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-am +uninstall-am: uninstall-watchdogDATA +uninstall: uninstall-am +all-am: Makefile $(DATA) +all-redirect: all-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install +installdirs: + $(mkinstalldirs) $(DESTDIR)$(watchdogdir) + + +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + +maintainer-clean-generic: +mostlyclean-am: mostlyclean-generic + +mostlyclean: mostlyclean-am + +clean-am: clean-generic mostlyclean-am + +clean: clean-am + +distclean-am: distclean-generic clean-am + +distclean: distclean-am + -rm -f config.status + +maintainer-clean-am: maintainer-clean-generic distclean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +maintainer-clean: maintainer-clean-am + -rm -f config.status + +.PHONY: uninstall-watchdogDATA install-watchdogDATA tags distdir info-am \ +info dvi-am dvi check check-am installcheck-am installcheck \ +install-exec-am install-exec install-data-am install-data install-am \ +install uninstall-am uninstall all-redirect all-am all installdirs \ +mostlyclean-generic distclean-generic clean-generic \ +maintainer-clean-generic clean mostlyclean distclean maintainer-clean + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT:
new file mode 100644 --- /dev/null +++ b/packages/devs/watchdog/synth/current/host/acinclude.m4 @@ -0,0 +1,45 @@ +dnl Process this file with aclocal to get an aclocal.m4 file. Then +dnl process that with autoconf. +dnl ==================================================================== +dnl +dnl acinclude.m4 +dnl +dnl ==================================================================== +dnl####COPYRIGHTBEGIN#### +dnl +dnl ---------------------------------------------------------------------------- +dnl Copyright (C) 2002 Bart Veer +dnl +dnl This file is part of the eCos host tools. +dnl +dnl This program is free software; you can redistribute it and/or modify it +dnl under the terms of the GNU General Public License as published by the Free +dnl Software Foundation; either version 2 of the License, or (at your option) +dnl any later version. +dnl +dnl This program is distributed in the hope that it will be useful, but WITHOUT +dnl ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +dnl FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +dnl more details. +dnl +dnl You should have received a copy of the GNU General Public License along with +dnl this program; if not, write to the Free Software Foundation, Inc., +dnl 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +dnl ---------------------------------------------------------------------------- +dnl +dnl####COPYRIGHTEND#### +dnl ==================================================================== +dnl#####DESCRIPTIONBEGIN#### +dnl +dnl Author(s): bartv +dnl Contact(s): bartv +dnl Date: 2002/09/04 +dnl Version: 0.01 +dnl +dnl####DESCRIPTIONEND#### +dnl ==================================================================== + +dnl Access shared macros. +dnl AM_CONDITIONAL needs to be mentioned here or else aclocal does not +dnl incorporate the macro into aclocal.m4 +sinclude(../../../../../../acsupport/acinclude.m4)
new file mode 100644 --- /dev/null +++ b/packages/devs/watchdog/synth/current/host/aclocal.m4 @@ -0,0 +1,183 @@ +dnl aclocal.m4 generated automatically by aclocal 1.4-p5 + +dnl Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl This program is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without +dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A +dnl PARTICULAR PURPOSE. + +dnl Process this file with aclocal to get an aclocal.m4 file. Then +dnl process that with autoconf. +dnl ==================================================================== +dnl +dnl acinclude.m4 +dnl +dnl ==================================================================== +dnl####COPYRIGHTBEGIN#### +dnl +dnl ---------------------------------------------------------------------------- +dnl Copyright (C) 2002 Bart Veer +dnl +dnl This file is part of the eCos host tools. +dnl +dnl This program is free software; you can redistribute it and/or modify it +dnl under the terms of the GNU General Public License as published by the Free +dnl Software Foundation; either version 2 of the License, or (at your option) +dnl any later version. +dnl +dnl This program is distributed in the hope that it will be useful, but WITHOUT +dnl ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +dnl FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +dnl more details. +dnl +dnl You should have received a copy of the GNU General Public License along with +dnl this program; if not, write to the Free Software Foundation, Inc., +dnl 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +dnl ---------------------------------------------------------------------------- +dnl +dnl####COPYRIGHTEND#### +dnl ==================================================================== +dnl#####DESCRIPTIONBEGIN#### +dnl +dnl Author(s): bartv +dnl Contact(s): bartv +dnl Date: 2002/09/04 +dnl Version: 0.01 +dnl +dnl####DESCRIPTIONEND#### +dnl ==================================================================== + +dnl Access shared macros. +dnl AM_CONDITIONAL needs to be mentioned here or else aclocal does not +dnl incorporate the macro into aclocal.m4 +sinclude(../../../../../../acsupport/acinclude.m4) + +# Define a conditional. + +AC_DEFUN([AM_CONDITIONAL], +[AC_SUBST($1_TRUE) +AC_SUBST($1_FALSE) +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi]) + +# Do all the work for Automake. This macro actually does too much -- +# some checks are only needed if your package does certain things. +# But this isn't really a big deal. + +# serial 1 + +dnl Usage: +dnl AM_INIT_AUTOMAKE(package,version, [no-define]) + +AC_DEFUN([AM_INIT_AUTOMAKE], +[AC_REQUIRE([AC_PROG_INSTALL]) +PACKAGE=[$1] +AC_SUBST(PACKAGE) +VERSION=[$2] +AC_SUBST(VERSION) +dnl test to see if srcdir already configured +if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) +fi +ifelse([$3],, +AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) +AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])) +AC_REQUIRE([AM_SANITY_CHECK]) +AC_REQUIRE([AC_ARG_PROGRAM]) +dnl FIXME This is truly gross. +missing_dir=`cd $ac_aux_dir && pwd` +AM_MISSING_PROG(ACLOCAL, aclocal, $missing_dir) +AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir) +AM_MISSING_PROG(AUTOMAKE, automake, $missing_dir) +AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir) +AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir) +AC_REQUIRE([AC_PROG_MAKE_SET])]) + +# +# Check to make sure that the build environment is sane. +# + +AC_DEFUN([AM_SANITY_CHECK], +[AC_MSG_CHECKING([whether build environment is sane]) +# Just in case +sleep 1 +echo timestamp > conftestfile +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null` + if test "[$]*" = "X"; then + # -L didn't work. + set X `ls -t $srcdir/configure conftestfile` + fi + if test "[$]*" != "X $srcdir/configure conftestfile" \ + && test "[$]*" != "X conftestfile $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken +alias in your environment]) + fi + + test "[$]2" = conftestfile + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +rm -f conftest* +AC_MSG_RESULT(yes)]) + +dnl AM_MISSING_PROG(NAME, PROGRAM, DIRECTORY) +dnl The program must properly implement --version. +AC_DEFUN([AM_MISSING_PROG], +[AC_MSG_CHECKING(for working $2) +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if ($2 --version) < /dev/null > /dev/null 2>&1; then + $1=$2 + AC_MSG_RESULT(found) +else + $1="$3/missing $2" + AC_MSG_RESULT(missing) +fi +AC_SUBST($1)]) + +# Add --enable-maintainer-mode option to configure. +# From Jim Meyering + +# serial 1 + +AC_DEFUN([AM_MAINTAINER_MODE], +[AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) + dnl maintainer-mode is disabled by default + AC_ARG_ENABLE(maintainer-mode, +[ --enable-maintainer-mode enable make rules and dependencies not useful + (and sometimes confusing) to the casual installer], + USE_MAINTAINER_MODE=$enableval, + USE_MAINTAINER_MODE=no) + AC_MSG_RESULT($USE_MAINTAINER_MODE) + AM_CONDITIONAL(MAINTAINER_MODE, test $USE_MAINTAINER_MODE = yes) + MAINT=$MAINTAINER_MODE_TRUE + AC_SUBST(MAINT)dnl +] +) +
new file mode 100644 index 0000000000000000000000000000000000000000..2c8c318b2c41a65e390e5dea1ff5d35fbb875f65 GIT binary patch literal 5083 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 Ir#yT92hmnM(f|Me
new file mode 100644 index 0000000000000000000000000000000000000000..24f4382d3bbea37fc4b6c8270e9a153519fa42cb GIT binary patch literal 283 zc${<hbhEHb6k`x(_{hir1pmPR$WZ*r0u*3k&;f~p<QbUWOwkBj<kBg`%EZDE0Ai?m ziF6nw9%>O#^#V#M9ctkeR%-#PVG>qj;Sfl40I6}A0aVk#$qZ7H08*pmBLULRA*|*j z0g@6@<?;clacW=?bef_e2ozxuRP&i3u*jtmXdurFh#DoJ8by$Hpc(^3hXzJQh&hcQ s13}t5Kx#k+wt(#t1Q`glf+G-W7f?IGJuM7yH#0IJ`~_hErMMWZ0a7haQ2+n{
new file mode 100644 --- /dev/null +++ b/packages/devs/watchdog/synth/current/host/configure @@ -0,0 +1,1171 @@ +#! /bin/sh + +# Guess values for system-dependent variables and create Makefiles. +# Generated automatically using autoconf version 2.13 +# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. + +# Defaults: +ac_help= +ac_default_prefix=/usr/local +# Any additions from configure.in: +ac_help="$ac_help + --enable-maintainer-mode enable make rules and dependencies not useful + (and sometimes confusing) to the casual installer" + +# Initialize some variables set by options. +# The variables have the same names as the options, with +# dashes changed to underlines. +build=NONE +cache_file=./config.cache +exec_prefix=NONE +host=NONE +no_create= +nonopt=NONE +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +target=NONE +verbose= +x_includes=NONE +x_libraries=NONE +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datadir='${prefix}/share' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +libdir='${exec_prefix}/lib' +includedir='${prefix}/include' +oldincludedir='/usr/include' +infodir='${prefix}/info' +mandir='${prefix}/man' + +# Initialize some other variables. +subdirs= +MFLAGS= MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} +# Maximum number of lines to put in a shell here document. +ac_max_here_lines=12 + +ac_prev= +for ac_option +do + + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + + case "$ac_option" in + -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) ac_optarg= ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case "$ac_option" in + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir="$ac_optarg" ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build="$ac_optarg" ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file="$ac_optarg" ;; + + -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir="$ac_optarg" ;; + + -disable-* | --disable-*) + ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + eval "enable_${ac_feature}=no" ;; + + -enable-* | --enable-*) + ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "enable_${ac_feature}='$ac_optarg'" ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix="$ac_optarg" ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he) + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat << EOF +Usage: configure [options] [host] +Options: [defaults in brackets after descriptions] +Configuration: + --cache-file=FILE cache test results in FILE + --help print this message + --no-create do not create output files + --quiet, --silent do not print \`checking...' messages + --version print the version of autoconf that created configure +Directory and file names: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [same as prefix] + --bindir=DIR user executables in DIR [EPREFIX/bin] + --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] + --libexecdir=DIR program executables in DIR [EPREFIX/libexec] + --datadir=DIR read-only architecture-independent data in DIR + [PREFIX/share] + --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data in DIR + [PREFIX/com] + --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] + --libdir=DIR object code libraries in DIR [EPREFIX/lib] + --includedir=DIR C header files in DIR [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] + --infodir=DIR info documentation in DIR [PREFIX/info] + --mandir=DIR man documentation in DIR [PREFIX/man] + --srcdir=DIR find the sources in DIR [configure dir or ..] + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM + run sed PROGRAM on installed program names +EOF + cat << EOF +Host type: + --build=BUILD configure for building on BUILD [BUILD=HOST] + --host=HOST configure for HOST [guessed] + --target=TARGET configure for TARGET [TARGET=HOST] +Features and packages: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --x-includes=DIR X include files are in DIR + --x-libraries=DIR X library files are in DIR +EOF + if test -n "$ac_help"; then + echo "--enable and --with options recognized:$ac_help" + fi + exit 0 ;; + + -host | --host | --hos | --ho) + ac_prev=host ;; + -host=* | --host=* | --hos=* | --ho=*) + host="$ac_optarg" ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir="$ac_optarg" ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir="$ac_optarg" ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir="$ac_optarg" ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir="$ac_optarg" ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst \ + | --locals | --local | --loca | --loc | --lo) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* \ + | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + localstatedir="$ac_optarg" ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir="$ac_optarg" ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir="$ac_optarg" ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix="$ac_optarg" ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix="$ac_optarg" ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix="$ac_optarg" ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name="$ac_optarg" ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir="$ac_optarg" ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir="$ac_optarg" ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site="$ac_optarg" ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir="$ac_optarg" ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir="$ac_optarg" ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target="$ac_optarg" ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers) + echo "configure generated by autoconf version 2.13" + exit 0 ;; + + -with-* | --with-*) + ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "with_${ac_package}='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`echo $ac_option|sed -e 's/-*without-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + eval "with_${ac_package}=no" ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes="$ac_optarg" ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries="$ac_optarg" ;; + + -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } + ;; + + *) + if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then + echo "configure: warning: $ac_option: invalid host type" 1>&2 + fi + if test "x$nonopt" != xNONE; then + { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } + fi + nonopt="$ac_option" + ;; + + esac +done + +if test -n "$ac_prev"; then + { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } +fi + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +# File descriptor usage: +# 0 standard input +# 1 file creation +# 2 errors and warnings +# 3 some systems may open it to /dev/tty +# 4 used on the Kubota Titan +# 6 checking for... messages and results +# 5 compiler messages saved in config.log +if test "$silent" = yes; then + exec 6>/dev/null +else + exec 6>&1 +fi +exec 5>./config.log + +echo "\ +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. +" 1>&5 + +# Strip out --no-create and --no-recursion so they do not pile up. +# Also quote any args containing shell metacharacters. +ac_configure_args= +for ac_arg +do + case "$ac_arg" in + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) ;; + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) + ac_configure_args="$ac_configure_args '$ac_arg'" ;; + *) ac_configure_args="$ac_configure_args $ac_arg" ;; + esac +done + +# NLS nuisances. +# Only set these to C if already set. These must not be set unconditionally +# because not all systems understand e.g. LANG=C (notably SCO). +# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! +# Non-C LC_CTYPE values break the ctype check. +if test "${LANG+set}" = set; then LANG=C; export LANG; fi +if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi +if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi +if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo > confdefs.h + +# A filename unique to this package, relative to the directory that +# configure is in, which we can look for to find out if srcdir is correct. +ac_unique_file=watchdog.tcl + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then its parent. + ac_prog=$0 + ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` + test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r $srcdir/$ac_unique_file; then + if test "$ac_srcdir_defaulted" = yes; then + { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } + else + { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } + fi +fi +srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` + +# Prefer explicitly selected file to automatically selected ones. +if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi +fi +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + echo "loading site script $ac_site_file" + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + echo "loading cache $cache_file" + . $cache_file +else + echo "creating cache $cache_file" + > $cache_file +fi + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +ac_exeext= +ac_objext=o +if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then + # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. + if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then + ac_n= ac_c=' +' ac_t=' ' + else + ac_n=-n ac_c= ac_t= + fi +else + ac_n= ac_c='\c' ac_t= +fi + + + +ac_aux_dir= +for ac_dir in ../../../../../../acsupport $srcdir/../../../../../../acsupport; do + if test -f $ac_dir/install-sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f $ac_dir/install.sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { echo "configure: error: can not find install-sh or install.sh in ../../../../../../acsupport $srcdir/../../../../../../acsupport" 1>&2; exit 1; } +fi +ac_config_guess=$ac_aux_dir/config.guess +ac_config_sub=$ac_aux_dir/config.sub +ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. + + + + echo $ac_n "checking that a separate build tree is being used""... $ac_c" 1>&6 +echo "configure:551: checking that a separate build tree is being used" >&5 + ecos_cwd=`/bin/pwd` + if test "${srcdir}" = "." ; then + srcdir=${ecos_cwd} + fi + if test "${ecos_cwd}" = "${srcdir}" ; then + echo "$ac_t""no" 1>&6 + { echo "configure: error: This configure script should not be run inside the source tree. Instead please use a separate build tree" 1>&2; exit 1; } + else + echo "$ac_t""yes" 1>&6 + fi + + +# Make sure we can run config.sub. +if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then : +else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; } +fi + +echo $ac_n "checking host system type""... $ac_c" 1>&6 +echo "configure:570: checking host system type" >&5 + +host_alias=$host +case "$host_alias" in +NONE) + case $nonopt in + NONE) + if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then : + else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; } + fi ;; + *) host_alias=$nonopt ;; + esac ;; +esac + +host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias` +host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$host" 1>&6 + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# ./install, which can be erroneously created by make from ./install.sh. +echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 +echo "configure:602: checking for a BSD compatible install" >&5 +if test -z "$INSTALL"; then +if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":" + for ac_dir in $PATH; do + # Account for people who put trailing slashes in PATH elements. + case "$ac_dir/" in + /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + if test -f $ac_dir/$ac_prog; then + if test $ac_prog = install && + grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + else + ac_cv_path_install="$ac_dir/$ac_prog -c" + break 2 + fi + fi + done + ;; + esac + done + IFS="$ac_save_IFS" + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL="$ac_cv_path_install" + else + # As a last resort, use the slow shell script. We don't cache a + # path for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the path is relative. + INSTALL="$ac_install_sh" + fi +fi +echo "$ac_t""$INSTALL" 1>&6 + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +echo $ac_n "checking whether build environment is sane""... $ac_c" 1>&6 +echo "configure:655: checking whether build environment is sane" >&5 +# Just in case +sleep 1 +echo timestamp > conftestfile +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t $srcdir/configure conftestfile` + fi + if test "$*" != "X $srcdir/configure conftestfile" \ + && test "$*" != "X conftestfile $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + { echo "configure: error: ls -t appears to fail. Make sure there is not a broken +alias in your environment" 1>&2; exit 1; } + fi + + test "$2" = conftestfile + ) +then + # Ok. + : +else + { echo "configure: error: newly created file is older than distributed files! +Check your system clock" 1>&2; exit 1; } +fi +rm -f conftest* +echo "$ac_t""yes" 1>&6 +if test "$program_transform_name" = s,x,x,; then + program_transform_name= +else + # Double any \ or $. echo might interpret backslashes. + cat <<\EOF_SED > conftestsed +s,\\,\\\\,g; s,\$,$$,g +EOF_SED + program_transform_name="`echo $program_transform_name|sed -f conftestsed`" + rm -f conftestsed +fi +test "$program_prefix" != NONE && + program_transform_name="s,^,${program_prefix},; $program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s,\$\$,${program_suffix},; $program_transform_name" + +# sed with no file args requires a program. +test "$program_transform_name" = "" && program_transform_name="s,x,x," + +echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6 +echo "configure:712: checking whether ${MAKE-make} sets \${MAKE}" >&5 +set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftestmake <<\EOF +all: + @echo 'ac_maketemp="${MAKE}"' +EOF +# GNU make sometimes prints "make[1]: Entering...", which would confuse us. +eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=` +if test -n "$ac_maketemp"; then + eval ac_cv_prog_make_${ac_make}_set=yes +else + eval ac_cv_prog_make_${ac_make}_set=no +fi +rm -f conftestmake +fi +if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then + echo "$ac_t""yes" 1>&6 + SET_MAKE= +else + echo "$ac_t""no" 1>&6 + SET_MAKE="MAKE=${MAKE-make}" +fi + + +PACKAGE=eCos_synthetic_target_watchdog + +VERSION=0.1 + +if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then + { echo "configure: error: source directory already configured; run "make distclean" there first" 1>&2; exit 1; } +fi + + + +missing_dir=`cd $ac_aux_dir && pwd` +echo $ac_n "checking for working aclocal""... $ac_c" 1>&6 +echo "configure:751: checking for working aclocal" >&5 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (aclocal --version) < /dev/null > /dev/null 2>&1; then + ACLOCAL=aclocal + echo "$ac_t""found" 1>&6 +else + ACLOCAL="$missing_dir/missing aclocal" + echo "$ac_t""missing" 1>&6 +fi + +echo $ac_n "checking for working autoconf""... $ac_c" 1>&6 +echo "configure:764: checking for working autoconf" >&5 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (autoconf --version) < /dev/null > /dev/null 2>&1; then + AUTOCONF=autoconf + echo "$ac_t""found" 1>&6 +else + AUTOCONF="$missing_dir/missing autoconf" + echo "$ac_t""missing" 1>&6 +fi + +echo $ac_n "checking for working automake""... $ac_c" 1>&6 +echo "configure:777: checking for working automake" >&5 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (automake --version) < /dev/null > /dev/null 2>&1; then + AUTOMAKE=automake + echo "$ac_t""found" 1>&6 +else + AUTOMAKE="$missing_dir/missing automake" + echo "$ac_t""missing" 1>&6 +fi + +echo $ac_n "checking for working autoheader""... $ac_c" 1>&6 +echo "configure:790: checking for working autoheader" >&5 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (autoheader --version) < /dev/null > /dev/null 2>&1; then + AUTOHEADER=autoheader + echo "$ac_t""found" 1>&6 +else + AUTOHEADER="$missing_dir/missing autoheader" + echo "$ac_t""missing" 1>&6 +fi + +echo $ac_n "checking for working makeinfo""... $ac_c" 1>&6 +echo "configure:803: checking for working makeinfo" >&5 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (makeinfo --version) < /dev/null > /dev/null 2>&1; then + MAKEINFO=makeinfo + echo "$ac_t""found" 1>&6 +else + MAKEINFO="$missing_dir/missing makeinfo" + echo "$ac_t""missing" 1>&6 +fi + + +echo $ac_n "checking whether to enable maintainer-specific portions of Makefiles""... $ac_c" 1>&6 +echo "configure:817: checking whether to enable maintainer-specific portions of Makefiles" >&5 + # Check whether --enable-maintainer-mode or --disable-maintainer-mode was given. +if test "${enable_maintainer_mode+set}" = set; then + enableval="$enable_maintainer_mode" + USE_MAINTAINER_MODE=$enableval +else + USE_MAINTAINER_MODE=no +fi + + echo "$ac_t""$USE_MAINTAINER_MODE" 1>&6 + + +if test $USE_MAINTAINER_MODE = yes; then + MAINTAINER_MODE_TRUE= + MAINTAINER_MODE_FALSE='#' +else + MAINTAINER_MODE_TRUE='#' + MAINTAINER_MODE_FALSE= +fi + MAINT=$MAINTAINER_MODE_TRUE + + + +case "${host}" in + i[34567]86-*-linux-gnu* ) SUPPORTED="yes";; + * ) SUPPORTED="no" +esac + + +if test "${SUPPORTED}" = "yes"; then + SUPPORTED_TRUE= + SUPPORTED_FALSE='#' +else + SUPPORTED_TRUE='#' + SUPPORTED_FALSE= +fi + +if test "${SUPPORTED}" = "yes" ; then + + + package_dir=`cd ${srcdir} && /bin/pwd` + PACKAGE_VERSION=`dirname ${package_dir}` + PACKAGE_VERSION=`basename ${PACKAGE_VERSION}` + + package_dir=`dirname ${package_dir}` + package_dir=`dirname ${package_dir}` + + possibles="${package_dir}/.. ${package_dir}/../.. ${package_dir}/../../.. ${package_dir}/../../../.." + possibles="${possibles} ${package_dir}/../../../../.. ${package_dir}/../../../../../.." + + repository_root="" + for i in ${possibles}; do + if test -d "$i/"acsupport""; then + repository_root=$i + break + fi + done + + if test "${repository_root}" = "" ; then + { echo "configure: error: Failed to identify this package's position within the eCos repository" 1>&2; exit 1; } + fi + ECOS_REPOSITORY=`cd "${repository_root}/packages/pkgconf/.." && /bin/pwd` + + PACKAGE_DIR=`echo ${package_dir} | sed -e "s:${ECOS_REPOSITORY}/::"` + + PACKAGE_INSTALL="${PACKAGE_DIR}/${PACKAGE_VERSION}" + + + + + + +fi + +trap '' 1 2 15 +cat > confcache <<\EOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs. It is not useful on other systems. +# If it contains results you don't want to keep, you may remove or edit it. +# +# By default, configure uses ./config.cache as the cache file, +# creating it if it does not exist already. You can give configure +# the --cache-file=FILE option to use a different cache file; that is +# what configure does when it calls configure scripts in +# subdirectories, so they share the cache. +# Giving --cache-file=/dev/null disables caching, for debugging configure. +# config.status only pays attention to the cache file if you give it the +# --recheck option to rerun configure. +# +EOF +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +(set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote substitution + # turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + -e "s/'/'\\\\''/g" \ + -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' + ;; + esac >> confcache +if cmp -s $cache_file confcache; then + : +else + if test -w $cache_file; then + echo "updating cache $cache_file" + cat confcache > $cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# Any assignment to VPATH causes Sun make to only execute +# the first set of double-colon rules, so remove it if not needed. +# If there is a colon in the path, we need to keep it. +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' +fi + +trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 + +# Transform confdefs.h into DEFS. +# Protect against shell expansion while executing Makefile rules. +# Protect against Makefile macro expansion. +cat > conftest.defs <<\EOF +s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g +s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g +s%\[%\\&%g +s%\]%\\&%g +s%\$%$$%g +EOF +DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '` +rm -f conftest.defs + + +# Without the "./", some shells look in PATH for config.status. +: ${CONFIG_STATUS=./config.status} + +echo creating $CONFIG_STATUS +rm -f $CONFIG_STATUS +cat > $CONFIG_STATUS <<EOF +#! /bin/sh +# Generated automatically by configure. +# Run this file to recreate the current configuration. +# This directory was configured as follows, +# on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# +# $0 $ac_configure_args +# +# Compiler output produced by configure, useful for debugging +# configure, is in ./config.log if it exists. + +ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" +for ac_option +do + case "\$ac_option" in + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" + exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; + -version | --version | --versio | --versi | --vers | --ver | --ve | --v) + echo "$CONFIG_STATUS generated by autoconf version 2.13" + exit 0 ;; + -help | --help | --hel | --he | --h) + echo "\$ac_cs_usage"; exit 0 ;; + *) echo "\$ac_cs_usage"; exit 1 ;; + esac +done + +ac_given_srcdir=$srcdir +ac_given_INSTALL="$INSTALL" + +trap 'rm -fr `echo "Makefile:Makefile.in" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 +EOF +cat >> $CONFIG_STATUS <<EOF + +# Protect against being on the right side of a sed subst in config.status. +sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g; + s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF +$ac_vpsub +$extrasub +s%@SHELL@%$SHELL%g +s%@CFLAGS@%$CFLAGS%g +s%@CPPFLAGS@%$CPPFLAGS%g +s%@CXXFLAGS@%$CXXFLAGS%g +s%@FFLAGS@%$FFLAGS%g +s%@DEFS@%$DEFS%g +s%@LDFLAGS@%$LDFLAGS%g +s%@LIBS@%$LIBS%g +s%@exec_prefix@%$exec_prefix%g +s%@prefix@%$prefix%g +s%@program_transform_name@%$program_transform_name%g +s%@bindir@%$bindir%g +s%@sbindir@%$sbindir%g +s%@libexecdir@%$libexecdir%g +s%@datadir@%$datadir%g +s%@sysconfdir@%$sysconfdir%g +s%@sharedstatedir@%$sharedstatedir%g +s%@localstatedir@%$localstatedir%g +s%@libdir@%$libdir%g +s%@includedir@%$includedir%g +s%@oldincludedir@%$oldincludedir%g +s%@infodir@%$infodir%g +s%@mandir@%$mandir%g +s%@host@%$host%g +s%@host_alias@%$host_alias%g +s%@host_cpu@%$host_cpu%g +s%@host_vendor@%$host_vendor%g +s%@host_os@%$host_os%g +s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g +s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g +s%@INSTALL_DATA@%$INSTALL_DATA%g +s%@PACKAGE@%$PACKAGE%g +s%@VERSION@%$VERSION%g +s%@ACLOCAL@%$ACLOCAL%g +s%@AUTOCONF@%$AUTOCONF%g +s%@AUTOMAKE@%$AUTOMAKE%g +s%@AUTOHEADER@%$AUTOHEADER%g +s%@MAKEINFO@%$MAKEINFO%g +s%@SET_MAKE@%$SET_MAKE%g +s%@MAINTAINER_MODE_TRUE@%$MAINTAINER_MODE_TRUE%g +s%@MAINTAINER_MODE_FALSE@%$MAINTAINER_MODE_FALSE%g +s%@MAINT@%$MAINT%g +s%@SUPPORTED_TRUE@%$SUPPORTED_TRUE%g +s%@SUPPORTED_FALSE@%$SUPPORTED_FALSE%g +s%@ECOS_REPOSITORY@%$ECOS_REPOSITORY%g +s%@PACKAGE_DIR@%$PACKAGE_DIR%g +s%@PACKAGE_VERSION@%$PACKAGE_VERSION%g +s%@PACKAGE_INSTALL@%$PACKAGE_INSTALL%g + +CEOF +EOF + +cat >> $CONFIG_STATUS <<\EOF + +# Split the substitutions into bite-sized pieces for seds with +# small command number limits, like on Digital OSF/1 and HP-UX. +ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. +ac_file=1 # Number of current file. +ac_beg=1 # First line for current file. +ac_end=$ac_max_sed_cmds # Line after last line for current file. +ac_more_lines=: +ac_sed_cmds="" +while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file + else + sed "${ac_end}q" conftest.subs > conftest.s$ac_file + fi + if test ! -s conftest.s$ac_file; then + ac_more_lines=false + rm -f conftest.s$ac_file + else + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f conftest.s$ac_file" + else + ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" + fi + ac_file=`expr $ac_file + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_cmds` + fi +done +if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat +fi +EOF + +cat >> $CONFIG_STATUS <<EOF + +CONFIG_FILES=\${CONFIG_FILES-"Makefile:Makefile.in"} +EOF +cat >> $CONFIG_STATUS <<\EOF +for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. + + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" + # A "../" for each directory in $ac_dir_suffix. + ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` + else + ac_dir_suffix= ac_dots= + fi + + case "$ac_given_srcdir" in + .) srcdir=. + if test -z "$ac_dots"; then top_srcdir=. + else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; + /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; + *) # Relative path. + srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" + top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + + case "$ac_given_INSTALL" in + [/$]*) INSTALL="$ac_given_INSTALL" ;; + *) INSTALL="$ac_dots$ac_given_INSTALL" ;; + esac + + echo creating "$ac_file" + rm -f "$ac_file" + configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." + case "$ac_file" in + *Makefile*) ac_comsub="1i\\ +# $configure_input" ;; + *) ac_comsub= ;; + esac + + ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` + sed -e "$ac_comsub +s%@configure_input@%$configure_input%g +s%@srcdir@%$srcdir%g +s%@top_srcdir@%$top_srcdir%g +s%@INSTALL@%$INSTALL%g +" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file +fi; done +rm -f conftest.s* + +EOF +cat >> $CONFIG_STATUS <<EOF + +EOF +cat >> $CONFIG_STATUS <<\EOF + +exit 0 +EOF +chmod +x $CONFIG_STATUS +rm -fr confdefs* $ac_clean_files +test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 +
new file mode 100644 --- /dev/null +++ b/packages/devs/watchdog/synth/current/host/configure.in @@ -0,0 +1,73 @@ +dnl Process this file with autoconf to produce a configure script. +dnl ==================================================================== +dnl +dnl configure.in +dnl +dnl configure script for eCos synthetic target watchdog +dnl host-side support +dnl +dnl ==================================================================== +dnl####COPYRIGHTBEGIN#### +dnl +dnl ---------------------------------------------------------------------------- +dnl Copyright (C) 2002 Bart Veer +dnl +dnl This file is part of the eCos synthetic target support. +dnl +dnl This program is free software; you can redistribute it and/or modify it +dnl under the terms of the GNU General Public License as published by the Free +dnl Software Foundation; either version 2 of the License, or (at your option) +dnl any later version. +dnl +dnl This program is distributed in the hope that it will be useful, but WITHOUT +dnl ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +dnl FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +dnl more details. +dnl +dnl You should have received a copy of the GNU General Public License along with +dnl this program; if not, write to the Free Software Foundation, Inc., +dnl 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +dnl ---------------------------------------------------------------------------- +dnl +dnl####COPYRIGHTEND#### +dnl ==================================================================== +dnl#####DESCRIPTIONBEGIN#### +dnl +dnl Author(s): bartv +dnl Contact(s): bartv +dnl Date: 2002/09/04 +dnl Version: 0.01 +dnl +dnl####DESCRIPTIONEND#### +dnl ==================================================================== + + +AC_INIT(watchdog.tcl) + +dnl Pick up the support files from the top-level acsupport directory. +AC_CONFIG_AUX_DIR(../../../../../../acsupport) + +ECOS_CHECK_BUILD_ne_SRC +AC_CANONICAL_HOST +AM_INIT_AUTOMAKE(eCos_synthetic_target_watchdog,0.1,0) +AM_MAINTAINER_MODE + +dnl The current version of the synthetic target is implemented only for +dnl x86 Linux platforms, so a test is appropriate here. However +dnl it is not a good idea for the configure script to report an error: +dnl that would prevent any top-level configury working for other +dnl platforms. Instead an automake conditional is used to suppress adding +dnl targets to the build. +case "${host}" in + i[[34567]]86-*-linux-gnu* ) SUPPORTED="yes";; + * ) SUPPORTED="no" +esac +AM_CONDITIONAL(SUPPORTED, test "${SUPPORTED}" = "yes") + +dnl The watchdog host-side support only involves a Tcl +dnl script and data files, so nothing needs to be compiled +if test "${SUPPORTED}" = "yes" ; then + ECOS_PACKAGE_DIRS +fi + +AC_OUTPUT(Makefile:Makefile.in)
new file mode 100644 index 0000000000000000000000000000000000000000..a9ba8a6ef4628fdc1a0f5efb93fa6d471743082a GIT binary patch literal 14853 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
new file mode 100644 --- /dev/null +++ b/packages/devs/watchdog/synth/current/host/doghouse.pov @@ -0,0 +1,161 @@ +// A simple "doghouse" picture, used for the synthetic target +// watchdog device host-side. +// +// This file is normally built using the following command line: +// +// x-povray +Idoghouse.pov +W128 +H128 +D +Q9 +AM2 +A0.9 +FP + +#include "consts.inc" +#include "colors.inc" +#include "shapes.inc" +#include "textures.inc" +#include "skies.inc" +#include "woods.inc" + +camera { + location <4.5, 2.2, -5> + look_at <2, 2, 2> +} + +light_source { + <7, 4, -1.5> + color White +} + +sky_sphere { S_Cloud2 scale 2 } +background { colour LightBlue } + +plane { + y 0 + texture { + pigment { color red 0.5 green 0.98 blue 0 turbulence 0.5} + normal { bumps 0.4 scale 0.1 } + } +} + +fog { + distance 40 + fog_type Ground_Fog + fog_offset 1 + fog_alt 1 + colour rgbf<0, 0.2, 0.2, 0.3> + turbulence 0.2 +} + +// A plank is a 1x1x0.1 block with a corner at the origin. The edges are +// slightly rounded, to make sure that the plank boundaries are just +// about visible. +#declare Plank = + superellipsoid { <0.03,0.03> scale <0.5,0.5,0.05> translate <0.5,0.5,0.05> texture { T_Wood10 } } + +// A variant, for the roof +#declare RoofPlank = + superellipsoid { <0.05,0.05> scale <0.5,0.5,0.05> translate <0.5,0.5,0.05> texture { T_Wood14 } } + +// The front and back, a rectangle with a triangle on top. +// Going clockwise from the bottom left, the coordinates are: +// <0,0> <0,3.2>, <2.4.5>, <4,3.2>, <4.0> +// Each is made from five horizontal planks. +// +// Note: this doghouse is not intended to be an example of good +// woodworking. For example, butt joints for the walls are a bad idea. +// Most importantly the roof should involve lapped joints with a +// sensible ridge, the current construction is not going to keep the +// rain out. +#declare RoofAngle = degrees(atan2(1.3,2)); +#declare RoofAngleR = atan2(1.3,2); + +#declare FrontBack = + difference { + union { + object { Plank scale <4,1,1> translate <0,0,0> } + object { Plank scale <4,1,1> translate <0,1,0> } + object { Plank scale <4,1,1> translate <0,2,0> } + object { Plank scale <4,1,1> translate <0,3,0> } + object { Plank scale <4,1,1> translate <0,4,0> } + } + union { + box { <0,0,0> <4,4,1> rotate <0,0,RoofAngle> translate <0,3.2,-0.5> } + box { <0,0,0> <4,4,1> rotate <0,0, -1 * RoofAngle> translate <2,4.5,-0.5> } + pigment { Black } + } + } + +// The front also has some text to name the dog, and a +// cutout for the opening. +object { + difference { + object { FrontBack } + union { + text { + ttf "cyrvetic.ttf" "FIFI" 0.1 0 + translate <1.2, 2.8, -0.05> + } + box { <1,0,-0.5> <3,2.2,0.5> } + object { + cylinder { <0,0,0> <0,0,1> 1 } + scale <1,0.33,1> + translate <2,2.2,-0.5> + } + pigment { Black } + } + } +} + +// The back, nothing fancy needed here. The doghouse is twice +// as deep as it is wide. +object { FrontBack translate <0,0,8> } + +// A floor, to prevent any bright grass showing inside +box { <0.05,0,0.05> <3.95,0.05,7.95> texture { T_Wood3 } } + +// LHS +object { Plank scale <8,1,1> rotate <0,-90,0> translate <0,0,0.1> } +object { Plank scale <8,1,1> rotate <0,-90,0> translate <0,1,0.1> } +object { Plank scale <8,1,1> rotate <0,-90,0> translate <0,2,0.1> } + +// RHS +object { Plank scale <8,1,1> rotate <0,-90,0> translate <4,0,0.1> } +object { Plank scale <8,1,1> rotate <0,-90,0> translate <4,1,0.1> } +object { Plank scale <8,1,1> rotate <0,-90,0> translate <4,2,0.1> } + +// Now for the roof. The top of the roof is at <2,4.5,0>, and the +// corners are at <0,3.2,0> and <4,3.2,0>. The planks are 0.1 units +// thick. + +#declare RoofPlank = + superellipsoid { <0.05,0.05> scale <0.5,0.5,0.05> translate <0.5,0.5,0.05> texture { T_Wood14 } } + +#declare RoofPlank_L = object { + RoofPlank + rotate <0, -90, RoofAngle - 90> + scale<1,1,8.5> +} + +#declare RoofPlank_R = object { + RoofPlank + rotate <0, -90, -90 - RoofAngle> + scale<1,1,8.5> +} + +object { RoofPlank_L translate<2 - (1 * cos(RoofAngleR)), 4.5 - (1 * sin(RoofAngleR)), -0.25> } +object { RoofPlank_L translate<2 - (2 * cos(RoofAngleR)), 4.5 - (2 * sin(RoofAngleR)), -0.25> } +object { RoofPlank_L translate<2 - (3 * cos(RoofAngleR)), 4.5 - (3 * sin(RoofAngleR)), -0.25> } + +object { RoofPlank_R translate<2 + (-0.1 * cos(RoofAngleR)), 4.5 - (-0.1 * sin(RoofAngleR)), -0.25> } +object { RoofPlank_R translate<2 + (0.9 * cos(RoofAngleR)), 4.5 - (0.9 * sin(RoofAngleR)), -0.25> } +object { RoofPlank_R translate<2 + (1.9 * cos(RoofAngleR)), 4.5 - (1.9 * sin(RoofAngleR)), -0.25> } + +// And just for fun, a dog bowl. +object { + merge { + difference { + torus { 1.0 0.5 } + box { <-1,-1,-1> <1,0,1> pigment { Black } } + } + cylinder { <0,0,0> <0,0.2,0> 0.9 } + } + scale <0.5,0.5,0.5> + translate <-0.5,0,-0.7> + pigment { Yellow } +}
new file mode 100644 index 0000000000000000000000000000000000000000..520f5eabc40df6b37eaaf51e48d422ed743c6da9 GIT binary patch literal 93 zc${<hbhEHb<Y3@p_{hir1pmPR$WZ*r0u*3k&;f~p<QbUsrmQen<kHD0>=iP@An`~G Vr?8q2kZ}lu;nd10?8eGq4FIMp8CC!Q
new file mode 100644 index 0000000000000000000000000000000000000000..156af9a52f4a7c717f5f0dc75ee3c3b59877e43a GIT binary patch literal 4464 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 GknmsjH~?D!
new file mode 100644 index 0000000000000000000000000000000000000000..f1885819377fadcad8d9c630d84227a90902df82 GIT binary patch literal 11691 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 G_kRJVoC1UZ
new file mode 100644 --- /dev/null +++ b/packages/devs/watchdog/synth/current/host/watchdog.tcl @@ -0,0 +1,425 @@ +# {{{ Banner + +# ============================================================================ +# +# watchdog.tcl +# +# Watchdog support for the eCos synthetic target I/O auxiliary +# +# ============================================================================ +# ####COPYRIGHTBEGIN#### +# +# ---------------------------------------------------------------------------- +# Copyright (C) 2002 Bart Veer +# +# This file is part of the eCos host tools. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the Free +# Software Foundation; either version 2 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, write to the Free Software Foundation, Inc., +# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# ---------------------------------------------------------------------------- +# +# ####COPYRIGHTEND#### +# ============================================================================ +# #####DESCRIPTIONBEGIN#### +# +# Author(s): bartv +# Contact(s): bartv +# Date: 2002/09/04 +# Version: 0.01 +# Description: +# Implementation of the watchdog device. This script should only ever +# be run from inside the ecosynth auxiliary. +# +# ####DESCRIPTIONEND#### +# ============================================================================ + +# }}} + +namespace eval watchdog { + + # Was initialization successful? + variable init_ok 1 + + # Has the alarm triggered? + variable alarm_triggered 0 + + # The eCos application process id. This is needed to send a SIGPWR signal + # if the watchdog triggers, and to access /proc/<pid>/stat to obtain + # timing information. Strictly speaking _ppid is not exported by + # the I/O auxiliary. + if { ! [info exists synth::_ppid] } { + synth::report_error "Watchdog initialization failed, _ppid variable required" + return "" + } + variable ecos_pid $synth::_ppid + + # Resolution, i.e. how long to go between checks. Currently this is hard-wired + # to one second, or 1000 ms. This may become configurable, either on the + # target-side via CDL or on the host-side via the target definition file. + # Note that currently the watchdog device and the GUI get updated via the + # same timer. If the resolution is changed to e.g. 10 seconds then it might + # be a good idea to update the GUI more frequently, although there are + # arguments for keeping the animation in step with the real work. + variable resolution 1000 + + # Options from the target definition file + variable use_wallclock 0 + variable window_pack "-in .main.n -side right" + variable sound_file "" + variable sound_player "play" + + if { [synth::tdf_has_device "watchdog"] } { + if { [synth::tdf_has_option "watchdog" "use"] } { + set _use [synth::tdf_get_option "watchdog" "use"] + if { "wallclock_time" == $_use } { + set watchdog::use_wallclock 1 + } elseif { "consumed_cpu_time" == $_use } { + set watchdog::use_wallclock 0 + } else { + synth::report_error "Invalid entry in target definition file $synth::target_definition\n\ + \ Device watchdog, option \"use\" should be \"wallclock_time\" or \"consumed_cpu_time\"\n" + } + unset _use + } + if { [synth::tdf_has_option "watchdog" "watchdog_pack"] } { + set watchdog::window_pack [synth::tdf_get_option "watchdog" "watchdog_pack"] + # Too complicated to validate here, instead leave it to a catch statement + # when the window actually gets packed + } + if { [synth::tdf_has_option "watchdog" "sound"] } { + set _sound_file [synth::tdf_get_option "watchdog" "sound"] + # Look for this sound file in the install tree first, then absolute or relative + if { [file exists [file join $synth::device_install_dir $_sound_file] ] } { + set _sound_file [file join $synth::device_install_dir $_sound_file] + } + if { ![file exists $_sound_file] } { + synth::report_error "Invalid entry in target definition file $synth::target_definition\n\ + \ Device watchdog, option \"sound\", failed to find $_sound_file\n" + } elseif { ! [file readable $_sound_file] } { + synth::report_error "Invalid entry in target definition file $synth::target_definition\n\ + \ Device watchdog, option \"sound\", no read access to file $_sound_file\n" + } else { + set watchdog::sound_file $_sound_file + } + unset _sound_file + } + if { [synth::tdf_has_option "watchdog" "sound_player"] } { + set watchdog::sound_player [synth::tdf_get_option "watchdog" "sound_player"] + } + } + + # There is no point in creating the watchdog window if any of the image files are missing + if { $synth::flag_gui } { + foreach _image [list "doghouse.gif" "alarm.gif" "eye.gif" "asleep.gif"] { + variable image_[file rootname $_image] + if { ! [synth::load_image "watchdog::image_[file rootname $_image]" [file join $synth::device_install_dir $_image]] } { + synth::report_error "Watchdog device, unable to load image $_image\n\ + \ This file should have been installed in $synth::device_install_dir\n" + set watchdog::init_ok 0 + } + } + } + if { $synth::flag_gui && $watchdog::init_ok } { + canvas .watchdog -width [image width $image_doghouse] -height [image height $image_doghouse] \ + -borderwidth 0 + variable background [.watchdog create image 0 0 -anchor nw -image $image_doghouse] + + # Eye positions inside the doghouse. The eye is an 8x10 gif, + # mostly white but transparent around the corners + variable left_eye_x 48 + variable left_eye_y 70 + variable right_eye_x 58 + variable right_eye_y 70 + + # Pupil positions relative to the eye. The pupils are 3x3 rectangles. + # The dog can look in one of nine different directions, with both eyes + # looking in the same direction (if visible) + variable pupil_positions { { 1 6 } { 1 5 } { 1 3 } { 3 1 } { 3 4 } { 3 6 } { 4 3 } { 4 5 } { 4 6 } } + + # Which eyes are currently visible: none, left, right or both + variable eyes "none" + # What is the current pupil position? + variable pupils 4 + + variable left_eye [.watchdog create image $left_eye_x $left_eye_y -anchor nw -image $image_eye] + variable right_eye [.watchdog create image $right_eye_x $right_eye_y -anchor nw -image $image_eye] + + variable left_pupil \ + [.watchdog create rectangle \ + [expr $left_eye_x + [lindex [lindex $pupil_positions $pupils] 0]] \ + [expr $left_eye_y + [lindex [lindex $pupil_positions $pupils] 1]] \ + [expr $left_eye_x + [lindex [lindex $pupil_positions $pupils] 0] + 2] \ + [expr $left_eye_y + [lindex [lindex $pupil_positions $pupils] 1] + 2] \ + -fill black] + variable right_pupil \ + [.watchdog create rectangle \ + [expr $right_eye_x + [lindex [lindex $pupil_positions $pupils] 0]] \ + [expr $right_eye_y + [lindex [lindex $pupil_positions $pupils] 1]] \ + [expr $right_eye_x + [lindex [lindex $pupil_positions $pupils] 0] + 2] \ + [expr $right_eye_y + [lindex [lindex $pupil_positions $pupils] 1] + 2] \ + -fill black] + + + # The dog is asleep until the eCos application activates the watchdog device + .watchdog lower $left_eye $background + .watchdog lower $right_eye $background + .watchdog lower $left_pupil $background + .watchdog lower $right_pupil $background + + # Prepare for an alarm, but obviously the alarm picture should be hidden for now. + variable alarm [.watchdog create image 30 56 -anchor nw -image $image_alarm] + .watchdog lower $alarm $background + + # Start asleep + variable asleep [.watchdog create image 48 70 -anchor nw -image $image_asleep] + + # Now try to pack the watchdog window using the option provided by the + # user. If that fails, report the error and pack in a default window. + if { [catch { eval pack .watchdog $watchdog::window_pack } message] } { + synth::report_error "Watchdog device, failed to pack window in $watchdog::window_pack\n $message" + pack .watchdog -in .main.n -side right + } + + # Updating the display. This happens once a second. + # If neither eye is visible, choose randomly between + # left-only, right-only or both. Otherwise there is + # a one in eight chance of blinking, probably switching + # to one of the other eye modes + # + # Also, the visible pupil(s) will move every second, to one + # of nine positions + proc gui_update { } { + + if { "none" == $watchdog::eyes} { + set rand [expr int(3 * rand())] + if { 0 == $rand } { + set watchdog::eyes "left" + .watchdog raise $watchdog::left_eye $watchdog::background + .watchdog raise $watchdog::left_pupil $watchdog::left_eye + } elseif { 1 == $rand } { + set watchdog::eyes "right" + .watchdog raise $watchdog::right_eye $watchdog::background + .watchdog raise $watchdog::right_pupil $watchdog::right_eye + } else { + set watchdog::eyes "both" + .watchdog raise $watchdog::left_eye $watchdog::background + .watchdog raise $watchdog::left_pupil $watchdog::left_eye + .watchdog raise $watchdog::right_eye $watchdog::background + .watchdog raise $watchdog::right_pupil $watchdog::right_eye + } + } else { + if { 0 == [expr int(8 * rand())] } { + set watchdog::eyes "none" + .watchdog lower $watchdog::left_eye $watchdog::background + .watchdog lower $watchdog::right_eye $watchdog::background + .watchdog lower $watchdog::left_pupil $watchdog::background + .watchdog lower $watchdog::right_pupil $watchdog::background + + # There is no point in moving the pupils if both eyes are shut + return + } + } + + set watchdog::pupils [expr int(9 * rand())] + set new_pupil_x [lindex [lindex $watchdog::pupil_positions $watchdog::pupils] 0] + set new_pupil_y [lindex [lindex $watchdog::pupil_positions $watchdog::pupils] 1] + + if { ("left" == $watchdog::eyes) || ("both" == $watchdog::eyes) } { + .watchdog coords $watchdog::left_pupil \ + [expr $watchdog::left_eye_x + $new_pupil_x] \ + [expr $watchdog::left_eye_y + $new_pupil_y] \ + [expr $watchdog::left_eye_x + $new_pupil_x + 2] \ + [expr $watchdog::left_eye_y + $new_pupil_y + 2] + } + if { ("right" == $watchdog::eyes) || ("both" == $watchdog::eyes) } { + .watchdog coords $watchdog::right_pupil \ + [expr $watchdog::right_eye_x + $new_pupil_x] \ + [expr $watchdog::right_eye_y + $new_pupil_y] \ + [expr $watchdog::right_eye_x + $new_pupil_x + 2] \ + [expr $watchdog::right_eye_y + $new_pupil_y + 2] + } + } + + # Cancel the gui display when the eCos application has exited. + # The watchdog is allowed to go back to sleep. If the application + # exited because of the watchdog then of course the alarm picture + # should remain visible, otherwise it would be just a flash. + proc gui_cancel { } { + .watchdog lower $watchdog::left_eye $watchdog::background + .watchdog lower $watchdog::right_eye $watchdog::background + .watchdog lower $watchdog::left_pupil $watchdog::background + .watchdog lower $watchdog::right_pupil $watchdog::background + if { ! $watchdog::alarm_triggered } { + .watchdog raise $watchdog::asleep $watchdog::background + } + } + + # Raise the alarm. This involves hiding the eyes and raising + # the alarm picture. If sound is enabled, the sound player + # should be invoked + proc gui_alarm { } { + .watchdog lower $watchdog::asleep $watchdog::background + .watchdog lower $watchdog::left_eye $watchdog::background + .watchdog lower $watchdog::right_eye $watchdog::background + .watchdog lower $watchdog::left_pupil $watchdog::background + .watchdog lower $watchdog::right_pupil $watchdog::background + .watchdog raise $watchdog::alarm $watchdog::background + + if { "" != $watchdog::sound_file } { + # Catch errors on the actual exec, e.g. if the sound player is + # invalid, but play the sound in the background. If there are + # problems actually playing the sound then the user should + # still see a message on stderr. Blocking the entire auxiliary + # for a few seconds is not acceptable. + if { [catch { eval exec -- $watchdog::sound_player $watchdog::sound_file & } message] } { + synth::report_warning "Watchdog device, failed to play alarm sound file\n $message\n" + } + } + } + + set _watchdog_help [file join $synth::device_src_dir "doc" "devs-watchdog-synth.html"] + if { ![file readable $_watchdog_help] } { + synth::report_warning "Failed to locate synthetic watchdog documentation $_watchdog_help\n\ + \ Help->Watchdog target menu option disabled.\n" + set _watchdog_help "" + } + if { "" == $_watchdog_help } { + .menubar.help add command -label "Watchdog" -state disabled + } else { + .menubar.help add command -label "Watchdog" -command [list synth::handle_help "file://$_watchdog_help"] + } + } + + # Now for the real work. By default the watchdog is asleep. The eCos + # application can activate it with a start message, which results + # in an "after" timer. That runs once a second to check whether or not + # the watchdog should trigger, and also updates the GUI. + # + # The target-side code should perform a watchdog reset at least once + # a second, which involves another message to this script and the + # setting of the reset_received flag. + # + # The update handler gets information about the eCos application using + # /proc/<pid>/stat (see man 5 proc). The "state" field is important: + # a state of T indicates that the application is stopped, probably + # inside gdb, so cannot reset the watchdog. The other important field + # is utime, the total number of jiffies (0.01 seconds) executed in + # user space. The code maintains an open file handle to the /proc file. + + variable reset_received 0 + variable after_id "" + variable proc_stat "" + variable last_jiffies 0 + + set _filename "/proc/[set watchdog::ecos_pid]/stat" + if { [catch { open $_filename "r" } proc_stat ] } { + synth::report_error "Watchdog device, failed to open $_filename\n $proc_stat\n" + set watchdog::init_ok 0 + } + unset _filename + + proc update { } { + set watchdog::after_id [after $watchdog::resolution watchdog::update] + if { $synth::flag_gui } { + watchdog::gui_update + } + seek $watchdog::proc_stat 0 "start" + set line [gets $watchdog::proc_stat] + scan $line "%*d %*s %s %*d %*d %*d %*d %*d %*lu %*lu %*lu %*lu %*lu %lu" state jiffies + + # In theory it is possible to examine the state field (the third argument). + # If set to T then that indicates the eCos application is traced or + # stopped, probably inside gdb, and it would make sense to act as if + # the application had sent a reset. Unfortunately the state also appears + # to be set to T if the application is blocked in a system call while + # being debugged - including the idle select(), making the test useless. + # FIXME: figure out how to distinguish between being blocked inside gdb + # and being in a system call. + #if { "T" == $state } { + # set watchdog::reset_received 1 + # return + #} + + # If there has been a recent reset the eCos application can continue to run for a bit longer. + if { $watchdog::reset_received } { + set watchdog::last_jiffies $jiffies + set watchdog::reset_received 0 + return + } + + # We have not received a reset. If the watchdog is using wallclock time then + # that is serious. If the watchdog is using elapsed cpu time then the eCos + # application may not actually have consumed a whole second of cpu time yet. + if { $watchdog::use_wallclock || (($jiffies - $watchdog::last_jiffies) > ($watchdog::resolution / 10)) } { + set watchdog::alarm_triggered 1 + # Report the situation via the main text window + synth::report "Watchdog device: the eCos application has not sent a recent reset\n Raising SIGPWR signal.\n" + # Then kill off the eCos application + exec kill -PWR $watchdog::ecos_pid + # There is no point in another run of the timer + after cancel $watchdog::after_id + # And if the GUI is running, raise the alarm visually + if { $synth::flag_gui } { + watchdog::gui_alarm + } + } + } + + # When the eCos application has exited, cancel the timer and + # clean-up the GUI. Also get rid of the open file since the + # /proc/<pid>/stat file is no longer meaningful + proc exit_hook { arg_list } { + if { "" != $watchdog::after_id } { + after cancel $watchdog::after_id + } + if { $synth::flag_gui } { + watchdog::gui_cancel + } + close $watchdog::proc_stat + } + synth::hook_add "ecos_exit" watchdog::exit_hook + + proc handle_request { id reqcode arg1 arg2 reqdata reqlen reply_len } { + if { 0x01 == $reqcode } { + # A "start" request. If the watchdog has already started, + # this request is a no-op. Otherwise a timer is enabled. + # This is made to run almost immediately, so that the + # GUI gets a quick update. Setting the reset_received flag + # ensures that the watchdog will not trigger immediately + set watchdog::reset_received 1 + if { "" == $watchdog::after_id } { + set watchdog::after_id [after 1 watchdog::update] + } + if { $synth::flag_gui } { + .watchdog lower $watchdog::asleep $watchdog::background + } + } elseif { 0x02 == $reqcode } { + # A "reset" request. Just set a flag, the update handler + # will detect this next time it runs. + set watchdog::reset_received 1 + } + } + + proc instantiate { id name data } { + return watchdog::handle_request + } +} + +if { $watchdog::init_ok } { + return watchdog::instantiate +} else { + synth::report "Watchdog cannot be instantiated, initialization failed.\n" + return "" +}
new file mode 100644 --- /dev/null +++ b/packages/devs/watchdog/synth/current/host/watchdog.tdf @@ -0,0 +1,63 @@ +synth_device watchdog { + + ## How should the watchdog device decide that the watchdog has + ## triggered, assuming the eCos application has failed to + ## reset the device in time. There are two options: wallclock + ## time, where the watchdog will trigger after a second + ## irrespective of what the eCos application has been doing; + ## or consumed cpu time, where the watchdog will only trigger + ## if the eCos application has actually run for a whole second. + ## + ## Using wallclock time matches most real hardware, + ## but can give spurious results if there are other processes + ## running and consuming cpu cycles. Also, if the user has + ## halted the application in gdb then the watchdog will trigger + ## even though the application has no chance to reset the + ## watchdog. + ## + ## Using consumed cpu cycles avoids these problems. + ## However the default implementation of the idle thread action + ## is to block in a select() system call, so if the eCos + ## application spends most of its time idling but not resetting + ## the watchdog then the device will not trigger. The + ## configuration option CYGIMP_HAL_IDLE_THREAD_SPIN can be used + ## to change the synthetic target HAL's implementation of the + ## idle thread action. + ## + ## The default is to use consumed_cpu_time. Wallclock time can + ## be selected by uncommenting the next line. + # use wallclock_time + # use consumed_cpu_time + + ## When running in GUI mode there will be a small window showing + ## the current state of the watchdog: asleep, watching, or giving + ## the alarm. This window can be packed as desired, using one + ## of the container frames .main.nw .main.n .main.ne .main.w + ## .main.e .main.sw .main.s or .main.se, and with a position of + ## left, right, top or bottom. The default is to pack inside the + ## .main.n frame, on the right, thus causing the watchdog to + ## appear above the central text window. + # watchdog_pack -in .main.n -side right + + ## If running in GUI mode, when the watchdog triggers and resets + ## the eCos application this will be shown in the display. + ## Optionally the watchdog device can also give an audible alert + ## when this happens. This is disabled by default to avoid + ## annoying co-workers, but can be enabled by specifying a suitable + ## sound file. Two such files, sound1.au and sound2.au, are supplied + ## with the watchdog device itself. Alternatively the user can + ## specify a different sound file using a suitable path + # sound sound1.au + # sound sound2.au + # sound ~/sounds/my_watchdog_alert.au + + ## If sound is enabled then the watchdog device needs some way to + ## access the host's sound hardware. Rather than accessing + ## /dev/audio or /dev/dsp directly the watchdog.tcl script will + ## run an external program. This can avoid complications with + ## different sound file formats etc. The default program is + ## "play", a front-end to the sox utility, but a different + ## program or script can be specified if desired. It will be run + ## simply as "<program> <sound file> &" + # sound_player play +}
new file mode 100644 --- /dev/null +++ b/packages/devs/watchdog/synth/current/src/synth_watchdog.cxx @@ -0,0 +1,159 @@ +//========================================================================== +// +// synth_watchdog.cxx +// +// Watchdog driver for the synthetic target +// +//========================================================================== +//####ECOSGPLCOPYRIGHTBEGIN#### +// ------------------------------------------- +// This file is part of eCos, the Embedded Configurable Operating System. +// Copyright (C) 2002 Bart Veer +// +// eCos is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 or (at your option) any later version. +// +// eCos is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License along +// with eCos; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. +// +// As a special exception, if other files instantiate templates or use macros +// or inline functions from this file, or you compile this file and link it +// with other works to produce a work based on this file, this file does not +// by itself cause the resulting work to be covered by the GNU General Public +// License. However the source code for this file must still be made available +// in accordance with section (3) of the GNU General Public License. +// +// This exception does not invalidate any other reasons why a work based on +// this file might be covered by the GNU General Public License. +// +// Alternative licenses for eCos may be arranged by contacting the +// copyright holder(s). +// ------------------------------------------- +//####ECOSGPLCOPYRIGHTEND#### +//========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): bartv +// Contributors: bartv +// Date: 2002-09-04 +// +//####DESCRIPTIONEND#### +//========================================================================== + +#include <pkgconf/system.h> +#include <pkgconf/devs_watchdog_synth.h> + +#ifdef CYGIMP_WATCHDOG_HARDWARE + +#include <cyg/hal/hal_arch.h> +#include <cyg/infra/cyg_type.h> +#include <cyg/infra/cyg_ass.h> +#include <cyg/infra/diag.h> +#include <cyg/hal/hal_io.h> + +// FIXME: right now the generic watchdog header depends on the +// kernel. That should be fixed in the watchdog code, but will +// affect some device drivers as well +#include <pkgconf/kernel.h> +#include <cyg/io/watchdog.hxx> + +// Protocol between host and target +#define SYNTH_WATCHDOG_START 0x01 +#define SYNTH_WATCHDOG_RESET 0x02 + +// The synthetic target's watchdog implementation involves interaction +// with a watchdog.tcl script running in the I/O auxiliary. The device +// must be instantiated during system initialization, preferably via +// a prioritized C++ static constructor. The generic watchdog package +// does have a static object, but it is not prioritized. If +// CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG is enabled then that object's +// constructor would get called too late. +// +// Instead a private class is defined here, and once instance is created. +// That instance gets referenced by the Cyg_Watchdog members, so +// selective linking does not get in the way. Instantiation happens inside +// the constructor, and the main Cyg_Watchdog::start() and reset() functions +// involve passing a message to the host-side. +// +// There is an open issue re. resolution. Usually the hardware imposes +// limits on what resolutions are valid, in fact there may be only one. +// With the synthetic target it would be possible to configure the +// desired resolution either on the target-side using a CDL option, or +// on the host-side using the target definition file. The resolution +// would have to be fairly coarse, probably at least 0.1 seconds, +// to allow for communication overheads. It is not clear whether +// target-side or host-side configuration is more appropriate, so for +// now a fixed resolution of one second is used. + +class _Synth_Watchdog { + public: + _Synth_Watchdog(); + ~_Synth_Watchdog() { } + + cyg_uint64 resolution; +}; + +// A static instance of the _Synth_Watchdog class, whose constructor will +// be called at the right time to instantiate host-side support. +static _Synth_Watchdog _synth_watchdog_object CYGBLD_ATTRIB_INIT_PRI(CYG_INIT_DRIVERS); + +// Id for communicating with the watchdog instance in the auxiliary +static int aux_id = -1; + +_Synth_Watchdog::_Synth_Watchdog() +{ + // SIGPWR is disabled by default. It has to be reenabled. + struct cyg_hal_sys_sigset_t blocked; + CYG_HAL_SYS_SIGEMPTYSET(&blocked); + CYG_HAL_SYS_SIGADDSET(&blocked, CYG_HAL_SYS_SIGPWR); + cyg_hal_sys_sigprocmask(CYG_HAL_SYS_SIG_UNBLOCK, &blocked, (cyg_hal_sys_sigset_t*) 0); + + resolution = 1000000000LL; + if (synth_auxiliary_running) { + aux_id = synth_auxiliary_instantiate("devs/watchdog/synth", + SYNTH_MAKESTRING(CYGPKG_DEVS_WATCHDOG_SYNTH), + "watchdog", + (const char*) 0, + (const char*) 0); + } +} + +// Hardware initialization. This has already happened in the +// _Synth_Watchdog constructor, all that is needed here is to +// propagate the resolution. +void +Cyg_Watchdog::init_hw(void) +{ + resolution = _synth_watchdog_object.resolution; +} + +void +Cyg_Watchdog::start(void) +{ + if (synth_auxiliary_running && (-1 != aux_id)) { + synth_auxiliary_xchgmsg(aux_id, SYNTH_WATCHDOG_START, 0, 0, + (const unsigned char*)0, 0, + (int *) 0, + (unsigned char*) 0, (int*) 0, 0); + } +} + +void +Cyg_Watchdog::reset() +{ + if (synth_auxiliary_running && (-1 != aux_id)) { + synth_auxiliary_xchgmsg(aux_id, SYNTH_WATCHDOG_RESET, 0, 0, + (const unsigned char*)0, 0, + (int *) 0, + (unsigned char*) 0, (int*) 0, 0); + } +} + +#endif // CYGIMP_WATCHDOG_HARDWARE
--- a/packages/ecos.db +++ b/packages/ecos.db @@ -1321,6 +1321,14 @@ package CYGPKG_DEVS_ETH_MCF5272 { } +package CYGPKG_DEVS_ETH_ECOSYNTH { + alias { "Synthetic target ethernet driver" ecosyntheth ecosynth_eth_driver } + directory devs/eth/synth/ecosynth + script syntheth.cdl + hardware + description "Ethernet driver for the synthetic target" +} + package CYGPKG_IO_PCI { alias { "PCI configuration library" io_pci } directory io/pci @@ -1479,6 +1487,16 @@ package CYGPKG_DEVICES_WATCHDOG_H8300_H8 Hitachi H8/300H chip." } +package CYGPKG_DEVS_WATCHDOG_SYNTH { + alias { "Watchdog driver for the synthetic target" devices_watchdog_synth device_watchdog_synth } + directory devs/watchdog/synth + script synth_watchdog.cdl + hardware + description " + This package provides a watchdog driver for the eCos + synthetic target." +} + package CYGPKG_IO_WATCHDOG { alias { "Watchdog IO device" watchdog io_watchdog } directory io/watchdog @@ -3460,6 +3478,8 @@ target linux { packages { CYGPKG_HAL_SYNTH CYGPKG_HAL_SYNTH_I386 CYGPKG_DEVS_FLASH_SYNTH + CYGPKG_DEVS_ETH_ECOSYNTH + CYGPKG_DEVS_WATCHDOG_SYNTH } description " The linux target provides the
--- a/packages/hal/synth/arch/current/ChangeLog +++ b/packages/hal/synth/arch/current/ChangeLog @@ -1,3 +1,13 @@ +2002-09-15 Bart Veer <bartv@ecoscentric.com> + + * include/hal_io.h + cdl/hal_synth.cdl + src/synth_entry.c, src/synth_intr.c, src/synth_diag.c, + src/synth_protocol.h + doc/* + host/* + Add support for I/O via an I/O auxiliary + 2002-08-04 Bart Veer <bartv@tymora.demon.co.uk> * include/hal_io.h: added argv/argv/environ definitions
--- a/packages/hal/synth/arch/current/cdl/hal_synth.cdl +++ b/packages/hal/synth/arch/current/cdl/hal_synth.cdl @@ -98,9 +98,29 @@ cdl_package CYGPKG_HAL_SYNTH { cdl_option CYGNUM_HAL_RTC_PERIOD { display "Real-time clock period" flavor data - calculated 10000 + calculated 10000 } } + # What to do when idling + cdl_option CYGIMP_HAL_IDLE_THREAD_SPIN { + display "Spin when idle" + default_value CYGIMP_IDLE_THREAD_YIELD + description " + By default, whenever the eCos application enters the idle thread + the synthetic target HAL will make a select() system call. Effectively + this causes the application to block until an interrupt occurs, + without consuming any cpu resources, as if the hardware supported + some sort of IDLE instruction. Usually this behaviour is desirable. + However it interferes with the emulation of some hardware. For + example the synthetic watchdog timer device can use consumed cpu time + rather than wallclock time to determine whether or not the watchdog + has triggered, and if the process is spending nearly all its time + blocked in select() then the watchdog will not trigger when it should. + There are also some kernel configurations which require that the idle + thread does not block." + } + requires { CYGIMP_IDLE_THREAD_YIELD implies CYGIMP_HAL_IDLE_THREAD_SPIN } + cdl_option CYGBLD_LINKER_SCRIPT { display "Linker script" flavor data
new file mode 100644 index 0000000000000000000000000000000000000000..ff5d88faeae05276e75a29294bcc9add4af9db06 GIT binary patch literal 21329 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
--- a/packages/hal/synth/arch/current/doc/hal-synth-arch.html +++ b/packages/hal/synth/arch/current/doc/hal-synth-arch.html @@ -3,9 +3,6 @@ <!-- and conditions set forth in the Open Publication License, v1.0 --> <!-- or later (the latest version is presently available at --> <!-- http://www.opencontent.org/openpub/). --> -<!-- Distribution of substantively modified versions of this --> -<!-- document is prohibited without the explicit permission of the --> -<!-- copyright holder. --> <!-- Distribution of the work or derivative of the work in any --> <!-- standard (paper) book form is prohibited unless prior --> <!-- permission is obtained from the copyright holder. --> @@ -16,7 +13,7 @@ ><meta name="MSSmartTagsPreventParsing" content="TRUE"> <META NAME="GENERATOR" -CONTENT="Modular DocBook HTML Stylesheet Version 1.64 +CONTENT="Modular DocBook HTML Stylesheet Version 1.76b+ "><LINK REL="NEXT" TITLE="Overview" @@ -31,6 +28,7 @@ ALINK="#0000FF" ><DIV CLASS="NAVHEADER" ><TABLE +SUMMARY="Header navigation table" WIDTH="100%" BORDER="0" CELLPADDING="0" @@ -52,6 +50,7 @@ ALIGN="right" VALIGN="bottom" ><A HREF="synth.html" +ACCESSKEY="N" >Next</A ></TD ></TR @@ -62,9 +61,7 @@ WIDTH="100%"></DIV ><DIV CLASS="PART" ><A -NAME="HAL-SYNTH-ARCH" -></A -><DIV +NAME="HAL-SYNTH-ARCH"><DIV CLASS="TITLEPAGE" ><H1 CLASS="TITLE" @@ -80,17 +77,47 @@ CLASS="TOC" ><A HREF="synth.html" >Overview</A -> — The eCos synthetic target</DT +> -- Overview</DT +><DT +><A +HREF="synth-install.html" +>Installation</A +> -- Preparing to use the synthetic target</DT +><DT +><A +HREF="synth-running.html" +>Running a Synthetic Target Application</A +> -- Arguments and configuration files</DT +><DT +><A +HREF="synth-gui.html" +>The I/O Auxiliary's User Interface</A +> -- Controlling the I/O Auxiliary</DT +><DT +><A +HREF="synth-console.html" +>The Console Device</A +> -- Show output from the eCos application</DT ><DT ><A HREF="synth-syscalls.html" >System Calls</A -> — Access Linux system facilities</DT +> -- Access Linux system facilities</DT +><DT +><A +HREF="synth-new-target.html" +>Writing New Devices - target</A +> -- extending the synthetic target, target-side</DT +><DT +><A +HREF="synth-new-host.html" +>Writing New Devices - host</A +> -- extending the synthetic target, host-side</DT ><DT ><A HREF="synth-porting.html" >Porting</A -> — The eCos synthetic target</DT +> -- Adding support for other hosts</DT ></DL ></DIV ></DIV @@ -100,6 +127,7 @@ CLASS="NAVFOOTER" ><HR ALIGN="LEFT" WIDTH="100%"><TABLE +SUMMARY="Footer navigation table" WIDTH="100%" BORDER="0" CELLPADDING="0" @@ -121,6 +149,7 @@ ALIGN="right" VALIGN="top" ><A HREF="synth.html" +ACCESSKEY="N" >Next</A ></TD ></TR
new file mode 100644 --- /dev/null +++ b/packages/hal/synth/arch/current/doc/layout.fig @@ -0,0 +1,57 @@ +#FIG 3.2 +Landscape +Center +Inches +Letter +100.00 +Single +-2 +1200 2 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2 + 0 600 8100 600 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2 + 0 900 8100 900 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2 + 0 1800 8100 1800 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2 + 0 3900 8100 3900 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2 + 600 4800 600 5100 +2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5 + 0 0 8100 0 8100 5100 0 5100 0 0 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2 + 5400 300 5400 600 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2 + 3600 300 3600 600 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2 + 1800 300 1800 600 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2 + 6300 900 6300 4800 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2 + 6300 300 6300 600 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2 + 1800 4800 1800 900 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2 + 6000 1800 6000 3900 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2 + 1800 3600 6300 3600 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2 + 2100 4800 2100 5100 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2 + 0 4800 8100 4800 +4 0 0 50 0 0 16 0.0000 4 165 810 6825 4425 .main.se\001 +4 0 0 50 0 0 16 0.0000 4 165 720 6825 2700 .main.e\001 +4 0 0 50 0 0 16 0.0000 4 165 840 6825 1425 .main.ne\001 +4 0 0 50 0 0 16 0.0000 4 225 1395 6375 525 .menubar.help\001 +4 0 0 50 0 0 16 0.0000 4 165 915 3450 225 .menubar\001 +4 0 0 50 0 0 16 0.0000 4 165 1455 3600 525 .menubar.view\001 +4 0 0 50 0 0 16 0.0000 4 165 765 3525 825 .toolbar\001 +4 0 0 50 0 0 16 0.0000 4 165 735 3525 1350 .main.n\001 +4 0 0 50 0 0 16 0.0000 4 165 1650 3150 2700 .main.centre.text\001 +4 0 0 50 0 0 16 0.0000 4 165 705 3525 4425 .main.s\001 +4 0 0 50 0 0 16 0.0000 4 150 1050 3300 5025 .status.text\001 +4 0 0 50 0 0 16 0.0000 4 165 885 150 4425 .main.sw\001 +4 0 0 50 0 0 16 0.0000 4 165 795 150 2700 .main.w\001 +4 0 0 50 0 0 16 0.0000 4 165 915 150 1425 .main.nw\001 +4 0 0 50 0 0 16 0.0000 4 165 1320 0 525 .menubar.file\001 +4 0 0 50 0 0 16 0.0000 4 165 1350 1875 525 .menubar.edit\001
new file mode 100644 index 0000000000000000000000000000000000000000..c9f14803cb1f3e2fa75317100431a2529fb788eb GIT binary patch literal 3658 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
new file mode 100644 index 0000000000000000000000000000000000000000..7aec6fe169d72b18790b60def42cdf99432285fe GIT binary patch literal 6168 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 AwEzGB
new file mode 100644 index 0000000000000000000000000000000000000000..988cd22a811dcc8ca6bbadc0ac0bd448ff06c25d GIT binary patch literal 2437 zc$@)+33~QNNk%w1VSfO70Hpu`000092?-Js5*r&EBqSs&D=RZIGdnvwLqkJMOiWTz zQd?VFV`F1%Y;1FLb9;Mx1O<W#422F6h!Pfx8zPV@G?*+nnl(b7JWHcYU#w1Iu32xi zV0gH4kHdk1fsKuglarI1o13GfqpYl~va+(ey1Id(%!jGajIYv@x7M4&+o#dus?_AI z*yXa`=(OSLx##V>>h8Yn@WaEy%*@Qw)6?16*~0Sj+yDRL<Kye=>+<sQ{{H^||NsC0 z|NsC0EC2ui0Dk~`000L5K%Q_&EE<o<q;kn@I-f?*&_=CVuh^`1%k6r<;4sxA6^hU3 zw0hkoPucLed~WkR-t@eFkA0MRe1U><Zf1jrh+>624}N4GS2d1yA6GP!4<I>KGngTp zR5>J=A~`joBbXzgHaQ}gC002hm@~2;m^4?oj}NC=i$_*SzcxoZRXNAM%0@a=H9AK+ zztTpmJ4dEAHAvXPz<-J3<XVg6=;-I^?1<~_@O<y_^n~K|_;JBd{Qds_0F~GYNU)&6 zgG501DWapH!-o(fN}NcsqQ#3CGh+PkVV}m2AVZ2Axv}FPAtY0(T$y8~LyjIF+5kWk zfB+sXUFyuJ3<3Ut002htH~^po4~NPM0GM$U>5c(40od395rj#GI&$pD0bsz<nO<}5 z94k>-0sta-_@r^xC{i9uX;5{@1M1YL0K_(gd9tYvWHzaS<w2t+0Uk2|6yUL=1b_oP zM*Mt?lPpHFL60gU3bck#8$@Z&n47h(RB1q`KIDtFAz+(0chmrIII)45i+3bOFcY$5 z1eGmU#4NOB&&*0|0+stvD^#hZS9iQaMB>b@!3opm;rPHz1Cc39P7qx9MB+_110VsH zrqQ_38!CIQS~?kHLnOYwS=cb*$KQn)6=Zsu2az%gWM<q@>oGW5dp0Q5*<4x)KvR7U zS#=)~IsR=0+cUIr<yB(2C8ii-jsYiDd<MRCmQeDkl^IbpNCV$ncKrpFR`x+sooh1* zAXtdok;s^dxpfzwiY=bU!&zzhRKr=IxtGn2G3LlaYSHn9A4)Ps<&_To6@VLKB!ndm z36l}nBt^#oH9|H-+2GTIN-@<O4;I#h;a(<v>DQYYu}J7hFg+kBQc;On-l34Hq@j=b zMVgYKmPX{|kC}EV+@y<oD(YA!Q7QySsB&ags;su^>Z`4;8Y`@{)@tjmv~DPb2e!(} zs;{czD(tYq3JWZ;sp^`~vTG>I?6Znc3hlICI7{ud;oyhuwpZApEf)RJG{81<=<opm z{tC#(Eg05vlS5$vY?9cx<$^F-0?4fEMY~iKCV;$M>EM{SJ4jYQR+51yLYvf7QNs=o zEY`pQTX`_q0_y6^O&!vLOVhun%-fh^BqIEnk|6+qzz(|Dpo6{SS=_+F3orrz0}X4; z@wZsyU?RPtICdDD2iV5L!jPp*@hQ>3%)_}2qznMY#pt}V5LL_av%paiQ1D|$E<B*R zO*g7QLl4kIwbfSxVu?)v4=|h8Y!YCyVkR$r#mfNT8_l^3piL748LxW^zcwWHZ{oDg zHo(Ys+rTE?Hb|DV$}GDKGt1^qrhv^1@ZbOd4e-za01oiL000jZUeDnjzg-jly#o_a znB6&yAmk}Ji2WFuROpa0zBF_m^~HjRetPMvdyumjS?i%|^lamUxFCE36;-;`cS|Yt z-N)mtA>l83efjX5k3KrE^SnMi>N5*Iv+=)APW|>D(mwh5w}XHGf!Lqhu3(~%kxLGI zJ6jIU<$#poY<|}o-vAxfmAD;n4S%~A4=nZo2f9vQ(|g<EL^iOleC=S8qm0xZ<2r~f z#sT25SOahN!F64)KOke=;~Zmv!l2M{iMgEK$`&)yEv$n#d!EM5=QDA!A_qd_0nv<x zG#;dEWx9yQ@SbKw)Oiqs&=TMlni#MW(&lSLJCW~bGDN;bg#kzWBHR8#XocCtONWkw z+%qJDx7__MYkVV~4lD+g;}NcU?K*|O0A@QA)-5ZO`=JU|Mhz|YjdSNJWXftbI^~g0 zb*y`a{?LH9cSU7{G->1yg%mvBwQ+L~%OvSG2|Ck#a&-?-Vm|%{z&(f&9?`Ja)N07B zU-mK`yga7#6ooZqsv~w;0HZV0kj!byp_<mjVB4}e4mxsk5EA^RJD@2}d63fvi^L;s zeCR`6Mq(C|!D25F=Pw=13lvaPOgkYcJeBbPmH<SY;~dAx!WbYic4Gz~f9DF!wJdw+ z5*$zhH^*~^D~BXvC*DrsM}<vtWxR8m%xGq_2Dq~v()1pFs{Uq51J<C41ei?$Zr3nB z3ek#~s{s)==tZ>=lUs@8Mpp>RxJDjyqpesdO~7+S+3eI}fzv_ShMCfQ7_$nCB%xwt zy3dzdE@!=?WJvqQMT`}1s)Va*B>Z>I*`RU&Gf^c?IcmA1G4zUD1PX9uNYb>KRIS#t zDBP$}K%<r{84EQ)O;e`Vyhbz!giIn}*^#wymQxV?3Rk1XHQ91{Q(v7;1U4_L2xd-@ zw0RgUYOD3V)k^Q2u7$&AV=G(O(pC+sz3o~ptJ~VTkFbqeoGhYfu#>_=E}Q{C2pF^q zhv|R-MPUUra?mFLv<wUM9IO{a0RY8@Hh??u2?!We{sNz@;uq0SN-XM_1E|!<LNt)> z7|3bL9O`gnGwp6-fO4?w#^YgU3BfZS7Mi8dsK6zVZhMzv3hG)HyMh&N6CcN>{2r#b z-~9q$qu~<)Gi?V%NlS8Q0+a+hY{9m8DSRRPTXY6@WCW{lc)Xhrxda##axnl}+7px= zsFxMdaBnCA5P<lqlz-6p$pz<?6``HbxaoLUhZ`1+5VwZ}F3S^i-J=8d>Hq*W5I~VP zRs{)W&8<%?AceP+FetNc2LTpkm3OS;RXjJkvhcEnmP6+GwisTl&}x1QfJPGR4j)oh zE_v@18ape61k!z}o*&F&B)eEld34O6_xQ)MWf6EXrO<(nXFwE3<C(qHrHOy3(1?}x zR<;~yanA}kJ2zi8x34a<ZF9}8UGsWht^GAAeJ$)QY-k6MNVc+<&Fp47``OTrwzQ{B zZDt!|64lPOwztjgZa;fxEeN-`Ti^l}KmZ0TXu%6o5P=x1AlxrF!31vL0u#*p-Q&); zzW2@V7Oda~7|1{jZg2q&;J^YK7<dIZ5QBWP;06@vK*RaXf`3N<1ux*Y3;HeYAOHY6 DyNH3Y
new file mode 100644 index 0000000000000000000000000000000000000000..067b750eb6a418e65e4b1af225c9a6af4865e2fc GIT binary patch literal 2726 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 KN}_EE!1}+>KJXj>
new file mode 100644 index 0000000000000000000000000000000000000000..5661f6e272020af8e519c42a22b438484689a8f4 GIT binary patch literal 1446 zc$@*I1zGw>Nk%w1VQ~N?0E7Sl0RaIF3=9$y5*r&EBO@a#D=RZIGdnvwLqkJLOG{Ex zQd?VFVq#)zYio0Jb9;Mxf`WpKjEs|$lbV{Eqobp%tE;oKv%9;y!^6YO%*@o()Y;kD z<>lq;>+AIN^#1<-EC2ui0C4~$000I4;3tk`X`X1Ru59b3owm)hOxtv==Ns<lKi&=p zycKJ~-m#a&Jw7p^bV{vSuh^_M2Z0i|;IMd%m35<ErE#q`rr&D#m6&Ev>)elL!@2YS zRDFOveS%VjQZj;uhksv)J2@PTQe7Mu7?~IuJQ|pp7o0g6pBNWkq?)HZ8K9Y8rmC>6 z7_g<aJfEL<T^bP*5)%;?95Nc0zrhg~#XZQt!pz1T7ReG37|q8O))5)a8yytDz~0&% z<IoXA924ZgK<)1meRLaLCukfe=lsSU{(1m3abq9}584cp$l>7xLx-L2LCK(@qD3GU zGv3Ik5lKdhL_l`j$gvYgIv@TodMsJV3z?T?tk|=Y1rLogHtN`10<)*gmuGwm9ZED0 z8YUMjGC``;Skt6Wol1pDHLBIANV8VG%Crl@Nnpc@9ZR;X*|TWVs$Cnl1HKn<<I0^& zmxPA5dOYae%eSxJzkmY^9!$8fVGI!7e&x`i!`Q}*Axm!T*fChiku5`JoS8Cbv6ew= z_B@$0>B^^1Ly(}Dvg3v$5W1dCd!X#vxNGktVS8Zi-@tKSYYq7Wh6M@|EU@t5a_G>L zI(VSa;DQI}rZqcvy-z}d?+G+WXrRF@`RkygtKS~{dgI}|Ut=&pz`=t91eoh#44VUN zJsW(`000ww5MXTk82+SSX8TM4Km&<I&_MwJRPX@-00g+32#txb+lI{rN82yN?c)Fd z5{Ll7gBdVDfnF52_(25;AfUhnA4D)f00me$L5&Gu@PPvvNN|7x97KRXcp>_CA^-_^ zP=Ny+AOJuH4hRsy0T~R5fQ=?D@WBHN40!+oW!~oAZydlU!kQgykN}hww4=d^PmBq` z0~ZjGzyt$SXn_GxVlaUK2t+_Y0U97+zylHtaKHmP8h`<M(-jcF0vu47!JHUW5GVs2 zoX9`~03g6Ypb7v0K&ud-T0mzaMi2pUuVp}i0Rb?;oCXUNV1We%Ah`el258{H1k9aS z;GE3@V8MwL{(Nw(g{@W#)(3OqcmM#6O8Wt!8hj8aK;LdaApj6q;A)u}L_q6oaK3k| z9{W+&pOpfn=&XZJTtMumLJ9~#1Rfkaz`7L-_$+}Q%xNKK9$0DNx8X8JsC5)B>gooB zO3+XR6##I6n77d@+`Vt=TLA)=Fz}#(!4j|lA084qK(zyQF`$bUTzc%o)k+M7V;@-j z0mjgdD=wiAOn}LS0Qk2X2Cg13FL1V&sArxO%siy4_&`tqjxsyIEdUot;Hr-YVBqlD zMT^T>(&9250FLJ#3jjb47|`jJ(ivbtbAc)=B4u48=$Xs}V3<HyX*ajQw}g^92?7E* zfWf!^7%tGkoGDsa;J4Z$O{j&Qerufu0}LPm1_20wA;O7YhqVBNTA*@m=yl+x9<CuI zumu+ch_nNfzqWzE%pkM}F$O~KpC^oA-$5(1lEN7G+IygZ?;ntYyk4e6R{pToE$-Uz z^-9+=(qXGjabCq^s@KsCy{4CR@!Jak2iTbZ`KKZ7=^teF7r$Du#&NTW&TCM`0Mxk8 zf(*J~aJHtwl_{n(AZ*MAzLB!YSnz}<<W34vlbsf-kcFw~VB_XjK->s0fWK*=bZS^U z9@Z;?Jk*yDf7ie@U8ifX*}yN{@eX$|aUReJ1{BHh#3)K}idDqo6q~q3Dt6I{Q=Bm2 zU9MrPGMe#>Xhb6!)5yj)y77&0jH4R6fThIP@s4=RqaOFj$3FV;kAMth9zy^CJE;+Y ACjbBd
new file mode 100644 --- /dev/null +++ b/packages/hal/synth/arch/current/doc/overview.fig @@ -0,0 +1,57 @@ +#FIG 3.2 +Landscape +Center +Inches +Letter +100.00 +Single +-2 +1200 2 +2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5 + 300 300 3300 300 3300 1800 300 1800 300 300 +2 1 1 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2 + 2700 300 2700 1800 +2 1 1 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2 + 1800 300 1800 1800 +2 1 1 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2 + 1800 750 2700 750 +2 1 1 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2 + 1800 1350 2700 1350 +2 1 1 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2 + 5400 300 5400 1800 +2 1 1 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2 + 5400 750 6900 750 +2 1 1 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2 + 5400 1350 6900 1350 +2 2 0 1 0 7 50 0 -1 4.000 0 0 7 0 0 5 + 4200 300 6900 300 6900 1800 4200 1800 4200 300 +2 1 0 2 0 7 50 0 -1 6.000 0 0 7 1 1 2 + 1 1 2.00 120.00 240.00 + 1 1 2.00 120.00 240.00 + 3300 1050 4200 1050 +2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 1 1 2 + 1 1 1.00 60.00 120.00 + 1 1 1.00 60.00 120.00 + 6900 600 7500 600 +2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 1 1 2 + 1 1 1.00 60.00 120.00 + 1 1 1.00 60.00 120.00 + 6900 1125 7500 1125 +2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 1 1 2 + 1 1 1.00 60.00 120.00 + 1 1 1.00 60.00 120.00 + 6900 1650 7500 1650 +4 0 0 50 0 0 12 0.0000 4 135 375 2850 1200 HAL\001 +4 0 0 50 0 0 12 0.0000 4 135 585 1950 1650 console\001 +4 0 0 50 0 0 12 0.0000 4 135 690 1875 1200 /dev/ser0\001 +4 0 0 50 0 0 12 0.0000 4 135 330 2100 600 eth0\001 +4 0 0 50 0 0 12 0.0000 4 135 390 750 825 eCos\001 +4 0 0 50 0 0 12 0.0000 4 180 825 600 1200 application\001 +4 0 0 50 0 0 12 0.0000 4 180 975 4350 1200 I/O Auxiliary\001 +4 0 0 50 0 0 12 0.0000 4 180 690 4500 825 ecosynth\001 +4 0 0 50 0 0 12 0.0000 4 135 870 5775 675 ethernet.tcl\001 +4 0 0 50 0 0 12 0.0000 4 135 660 5775 1200 serial.tcl\001 +4 0 0 50 0 0 12 0.0000 4 135 825 5775 1725 console.tcl\001 +4 0 0 50 0 0 12 0.0000 4 180 795 7575 675 Linux tap3\001 +4 0 0 50 0 0 12 0.0000 4 180 765 7575 1200 /dev/ttyS1\001 +4 0 0 50 0 0 12 0.0000 4 135 135 7575 1725 X\001
new file mode 100644 index 0000000000000000000000000000000000000000..4e1c20eccdd9853e3ac325216a442645564778a1 GIT binary patch literal 1928 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 O2upavLTF3@0029Q!n?iz
new file mode 100644 index 0000000000000000000000000000000000000000..851b8110c4c8b8a1382ff1c412a6d4e65d6ad3bc GIT binary patch literal 9548 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
new file mode 100644 index 0000000000000000000000000000000000000000..e89d1a8001c502849bee38336c26c9b77e986fa9 GIT binary patch literal 24141 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≥%{Ny9RPGQe?6 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 a=Z53F>Rs-3WqaG-%6GTH1;Abd0suSbx^oo(
new file mode 100644 --- /dev/null +++ b/packages/hal/synth/arch/current/doc/synth-console.html @@ -0,0 +1,373 @@ +<!-- Copyright (C) 2002 Red Hat, Inc. --> +<!-- This material may be distributed only subject to the terms --> +<!-- and conditions set forth in the Open Publication License, v1.0 --> +<!-- or later (the latest version is presently available at --> +<!-- http://www.opencontent.org/openpub/). --> +<!-- Distribution of the work or derivative of the work in any --> +<!-- standard (paper) book form is prohibited unless prior --> +<!-- permission is obtained from the copyright holder. --> +<HTML +><HEAD +><TITLE +>The Console Device</TITLE +><meta name="MSSmartTagsPreventParsing" content="TRUE"> +<META +NAME="GENERATOR" +CONTENT="Modular DocBook HTML Stylesheet Version 1.76b+ +"><LINK +REL="HOME" +TITLE="eCos Synthetic Target" +HREF="hal-synth-arch.html"><LINK +REL="PREVIOUS" +TITLE="The I/O Auxiliary's User Interface" +HREF="synth-gui.html"><LINK +REL="NEXT" +TITLE="System Calls" +HREF="synth-syscalls.html"></HEAD +><BODY +CLASS="REFENTRY" +BGCOLOR="#FFFFFF" +TEXT="#000000" +LINK="#0000FF" +VLINK="#840084" +ALINK="#0000FF" +><DIV +CLASS="NAVHEADER" +><TABLE +SUMMARY="Header navigation table" +WIDTH="100%" +BORDER="0" +CELLPADDING="0" +CELLSPACING="0" +><TR +><TH +COLSPAN="3" +ALIGN="center" +>eCos Synthetic Target</TH +></TR +><TR +><TD +WIDTH="10%" +ALIGN="left" +VALIGN="bottom" +><A +HREF="synth-gui.html" +ACCESSKEY="P" +>Prev</A +></TD +><TD +WIDTH="80%" +ALIGN="center" +VALIGN="bottom" +></TD +><TD +WIDTH="10%" +ALIGN="right" +VALIGN="bottom" +><A +HREF="synth-syscalls.html" +ACCESSKEY="N" +>Next</A +></TD +></TR +></TABLE +><HR +ALIGN="LEFT" +WIDTH="100%"></DIV +><H1 +><A +NAME="SYNTH-CONSOLE">The Console Device</H1 +><DIV +CLASS="REFNAMEDIV" +><A +NAME="AEN435" +></A +><H2 +>Name</H2 +>The console device -- Show output from the eCos application</DIV +><DIV +CLASS="REFSECT1" +><A +NAME="SYNTH-CONSOLE-DESCRIPTION" +></A +><H2 +>Description</H2 +><P +>The eCos application can generate text output in a variety of ways, +including calling <TT +CLASS="FUNCTION" +>printf</TT +> or +<TT +CLASS="FUNCTION" +>diag_printf</TT +>. When the I/O auxiliary is enabled +the eCos startup code will instantiate a console device to process all +such output. If operating in text mode the output will simply go to +standard output, or to a logfile if the <TT +CLASS="OPTION" +>-l</TT +> command +line option is specified. If operating in graphical mode the output +will go to the central text window, and optionally to a logfile as +well. In addition it is possible to control the appearance of the main +text via the target definition file, and to install extra filters for +certain types of text. + </P +><P +>It should be noted that the console device is line-oriented, not +character-oriented. This means that outputting partial lines is not +supported, and some functions such as <TT +CLASS="FUNCTION" +>fflush</TT +> and +<TT +CLASS="FUNCTION" +>setvbuf</TT +> will not operate as expected. This +limitation prevents much possible confusion when using filters to +control the appearance of the text window, and has some performance +benefits - especially when the eCos application generates a great deal +of output such as when tracing is enabled. For most applications this +is not a problem, but it is something that developers should be aware +of. + </P +><P +>The console device is output-only, it does not provide any support for +keyboard input. If the application requires keyboard input then that +should be handled by a separate eCos device package and matching +host-side code. + </P +></DIV +><DIV +CLASS="REFSECT1" +><A +NAME="SYNTH-CONSOLE-INSTALL" +></A +><H2 +>Installation</H2 +><P +>The eCos side of the console device is implemented by the +architectural HAL itself, in the source file +<TT +CLASS="FILENAME" +>synth_diag.c</TT +>, rather than in a separate device +package. Similarly the host-side implementation, +<TT +CLASS="FUNCTION" +>console.tcl</TT +>, is part of the architectural HAL's +host-side support. It gets installed automatically alongside the I/O +auxiliary itself, so no separate installation procedure is required. + </P +></DIV +><DIV +CLASS="REFSECT1" +><A +NAME="SYNTH-CONSOLE-TDF" +></A +><H2 +>Target Definition File</H2 +><P +>The <A +HREF="synth-running.html#SYNTH-RUNNING-TDF" +>target definition file</A +> +can contain a number of entries related to the console device. These +are all optional, they only control the appearance of text output. If +such control is desired then the relevant options should appear in the +body of a <B +CLASS="COMMAND" +>synth_device</B +> entry: + </P +><TABLE +BORDER="5" +BGCOLOR="#E0E0F0" +WIDTH="70%" +><TR +><TD +><PRE +CLASS="PROGRAMLISTING" +>synth_device console { + … +}</PRE +></TD +></TR +></TABLE +><P +>The first option is <B +CLASS="COMMAND" +>appearance</B +>, used to control the +appearance of any text generated by the eCos application that does not +match one of the installed filters. This option takes the same +argument as any other filter, for example: + </P +><TABLE +BORDER="5" +BGCOLOR="#E0E0F0" +WIDTH="70%" +><TR +><TD +><PRE +CLASS="PROGRAMLISTING" +>synth_device console { + appearance -foreground white -background black + … +}</PRE +></TD +></TR +></TABLE +><P +>Any number of additional filters can be created with a +<B +CLASS="COMMAND" +>filter</B +> option, for example: + </P +><TABLE +BORDER="5" +BGCOLOR="#E0E0F0" +WIDTH="70%" +><TR +><TD +><PRE +CLASS="PROGRAMLISTING" +>synth_device console { + … + filter trace {^TRACE:.*} -foreground HotPink1 -hide 1 + … +}</PRE +></TD +></TR +></TABLE +><P +>The first argument gives the new filter a name which will be used in +the <A +HREF="synth-gui.html#SYNTH-GUI-TEXT" +>filters dialog</A +>. Filter names +should be unique. The second argument is a Tcl regular expression. The +console support will match each line of eCos output against this +regular expression, and if a match is found then the filter will be +used for this line of text. The above example matches any line of +output that begins with <TT +CLASS="LITERAL" +>TRACE:</TT +>, which corresponds +to the eCos infrastructure's tracing facilities. The remaining options +control the desired appearance for matched text. If some eCos output +matches the regular expressions for several different filters then +only the first match will be used. + </P +></DIV +><DIV +CLASS="REFSECT1" +><A +NAME="SYNTH-CONSOLE-TARGET-CONFIG" +></A +><H2 +>Target-side + Configuration Options</H2 +><P +>There are no target-side configuration options related to the console +device. + </P +></DIV +><DIV +CLASS="REFSECT1" +><A +NAME="SYNTH-CONSOLE-ARGUMENTS" +></A +><H2 +>Command Line Arguments</H2 +><P +>The console device does not use any command-line arguments. + </P +></DIV +><DIV +CLASS="REFSECT1" +><A +NAME="SYNTH-CONSOLE-HOOKS" +></A +><H2 +>Hooks</H2 +><P +>The console device does not provide any hooks. + </P +></DIV +><DIV +CLASS="REFSECT1" +><A +NAME="AEN477" +></A +><H2 +>Additional Tcl Procedures</H2 +><P +>The console device does not provide any additional Tcl procedures that +can be used by other scripts. + </P +></DIV +><DIV +CLASS="NAVFOOTER" +><HR +ALIGN="LEFT" +WIDTH="100%"><TABLE +SUMMARY="Footer navigation table" +WIDTH="100%" +BORDER="0" +CELLPADDING="0" +CELLSPACING="0" +><TR +><TD +WIDTH="33%" +ALIGN="left" +VALIGN="top" +><A +HREF="synth-gui.html" +ACCESSKEY="P" +>Prev</A +></TD +><TD +WIDTH="34%" +ALIGN="center" +VALIGN="top" +><A +HREF="hal-synth-arch.html" +ACCESSKEY="H" +>Home</A +></TD +><TD +WIDTH="33%" +ALIGN="right" +VALIGN="top" +><A +HREF="synth-syscalls.html" +ACCESSKEY="N" +>Next</A +></TD +></TR +><TR +><TD +WIDTH="33%" +ALIGN="left" +VALIGN="top" +>The I/O Auxiliary's User Interface</TD +><TD +WIDTH="34%" +ALIGN="center" +VALIGN="top" +> </TD +><TD +WIDTH="33%" +ALIGN="right" +VALIGN="top" +>System Calls</TD +></TR +></TABLE +></DIV +></BODY +></HTML +> \ No newline at end of file
new file mode 100644 --- /dev/null +++ b/packages/hal/synth/arch/current/doc/synth-gui.html @@ -0,0 +1,738 @@ +<!-- Copyright (C) 2002 Red Hat, Inc. --> +<!-- This material may be distributed only subject to the terms --> +<!-- and conditions set forth in the Open Publication License, v1.0 --> +<!-- or later (the latest version is presently available at --> +<!-- http://www.opencontent.org/openpub/). --> +<!-- Distribution of the work or derivative of the work in any --> +<!-- standard (paper) book form is prohibited unless prior --> +<!-- permission is obtained from the copyright holder. --> +<HTML +><HEAD +><TITLE +>The I/O Auxiliary's User Interface</TITLE +><meta name="MSSmartTagsPreventParsing" content="TRUE"> +<META +NAME="GENERATOR" +CONTENT="Modular DocBook HTML Stylesheet Version 1.76b+ +"><LINK +REL="HOME" +TITLE="eCos Synthetic Target" +HREF="hal-synth-arch.html"><LINK +REL="PREVIOUS" +TITLE="Running a Synthetic Target Application" +HREF="synth-running.html"><LINK +REL="NEXT" +TITLE="The Console Device" +HREF="synth-console.html"></HEAD +><BODY +CLASS="REFENTRY" +BGCOLOR="#FFFFFF" +TEXT="#000000" +LINK="#0000FF" +VLINK="#840084" +ALINK="#0000FF" +><DIV +CLASS="NAVHEADER" +><TABLE +SUMMARY="Header navigation table" +WIDTH="100%" +BORDER="0" +CELLPADDING="0" +CELLSPACING="0" +><TR +><TH +COLSPAN="3" +ALIGN="center" +>eCos Synthetic Target</TH +></TR +><TR +><TD +WIDTH="10%" +ALIGN="left" +VALIGN="bottom" +><A +HREF="synth-running.html" +ACCESSKEY="P" +>Prev</A +></TD +><TD +WIDTH="80%" +ALIGN="center" +VALIGN="bottom" +></TD +><TD +WIDTH="10%" +ALIGN="right" +VALIGN="bottom" +><A +HREF="synth-console.html" +ACCESSKEY="N" +>Next</A +></TD +></TR +></TABLE +><HR +ALIGN="LEFT" +WIDTH="100%"></DIV +><H1 +><A +NAME="SYNTH-GUI">The I/O Auxiliary's User Interface</H1 +><DIV +CLASS="REFNAMEDIV" +><A +NAME="AEN304" +></A +><H2 +>Name</H2 +>User Interface -- Controlling the I/O Auxiliary</DIV +><DIV +CLASS="REFSECT1" +><A +NAME="SYNTH-GUI-DESCRIPTION" +></A +><H2 +>Description</H2 +><P +>The synthetic target auxiliary is designed to support both extensions +and user customization. Support for the desired devices is dynamically +loaded, and each device can extend the user interface. For example it +is possible for a device to add menu options, place new buttons on the +toolbar, create its own sub-window within the overall layout, or even +create entire new toplevel windows. These subwindows or toplevels +could show graphs of activity such as interrupts or packets being +transferred. They could also allow users to interact with the eCos +application, for example by showing a number of buttons which will be +mapped on to digital inputs in the eCos application. Different +applications will have their own I/O requirements, changing the +host-side support files that get loaded and that may modify the user +interface. The I/O auxiliary also reads in user configuration scripts +which can enhance the interface in the same way. Therefore the exact +user interface will depend on the user and on the eCos application +being run. However the overall layout is likely to remain the same. + </P +><DIV +CLASS="INFORMALFIGURE" +><A +NAME="AEN310"><P +></P +><DIV +CLASS="MEDIAOBJECT" +><P +><IMG +SRC="screen_main.gif" +ALIGN="CENTER"></P +></DIV +><P +></P +></DIV +><P +>The title bar identifies the window as belonging to an eCos synthetic +target application and lists both the application name and its process +id. The latter is especially useful if the application was started +directly from a shell prompt and the user now wants to attach a gdb +session. The window has a conventional menu bar with the usual +entries, plus a toolbar with buttons for common operations such as cut +and paste. Balloon help is supported. + </P +><P +>There is a central <A +HREF="synth-gui.html#SYNTH-GUI-TEXT" +>text window</A +>, +possibly surrounded by various sub-windows for various devices. For +example there could be a row of emulated LED's above the text window, +and monitors of ethernet traffic and interrupt activity on the right. +At the bottom of the window is a status line, including a small +animation that shows whether or not the eCos application is still +running. + </P +></DIV +><DIV +CLASS="REFSECT1" +><A +NAME="SYNTH-GUI-MENUS" +></A +><H2 +>Menus and the Toolbar</H2 +><P +>Usually there will be four menus on the menu bar: +<SPAN +CLASS="GUIMENU" +>File</SPAN +>, <SPAN +CLASS="GUIMENU" +>Edit</SPAN +>, +<SPAN +CLASS="GUIMENU" +>View</SPAN +> and <SPAN +CLASS="GUIMENU" +>Help</SPAN +>. + </P +><DIV +CLASS="INFORMALFIGURE" +><A +NAME="AEN324"><P +></P +><DIV +CLASS="MEDIAOBJECT" +><P +><IMG +SRC="menu_file.gif" +ALIGN="CENTER"></P +></DIV +><P +></P +></DIV +><P +>On the <SPAN +CLASS="GUIMENU" +>File</SPAN +> menu there are three entries related to +saving the current contents of the central text window. +<SPAN +CLASS="GUIMENUITEM" +>Save</SPAN +> is used to save the currently visible +contents of the text window. Any text that is hidden because of +filters will not be written to the savefile. If there has been a +previous <SPAN +CLASS="GUIMENUITEM" +>Save</SPAN +> or <SPAN +CLASS="GUIMENUITEM" +>Save +As</SPAN +> operation then the existing savefile will be re-used, +otherwise the user will be asked to select a suitable file. +<SPAN +CLASS="GUIMENUITEM" +>Save As</SPAN +> also saves just the currently +visible contents but will always prompt the user for a filename. +<SPAN +CLASS="GUIMENUITEM" +>Save All</SPAN +> can be used to save the full +contents of the text window, including any text that is currently +hidden. It will always prompt for a new filename, to avoid confusion +with partial savefiles. + </P +><P +>Usually the eCos application will be run from inside gdb or from a +shell prompt. Killing off the application while it is being debugged +in a gdb session is not a good idea, it would be better to use gdb's +own <B +CLASS="COMMAND" +>kill</B +> command. Alternatively the eCos +application itself can use the <TT +CLASS="FUNCTION" +>CYG_TEST_EXIT</TT +> or +<TT +CLASS="FILENAME" +>cyg_hal_sys_exit</TT +> functionality. However it is +possible to terminate the application from the I/O auxiliary using +<SPAN +CLASS="GUIMENUITEM" +>Kill eCos</SPAN +>. A clean shutdown will be +attempted, but that can fail if the application is currently halted +inside gdb or if it has crashed completely. As a last resort +<TT +CLASS="CONSTANT" +>SIGKILL</TT +> will be used. + </P +><P +>When operating in graphical mode the I/O auxiliary will normally +continue to run even after the eCos application has exited. This +allows the user to examine the last few lines of output, and perhaps +perform actions such as saving the output to a file. The +<SPAN +CLASS="GUIMENUITEM" +>Exit</SPAN +> menu item can be used to shut down the +auxiliary. Note that this behaviour can be changed with command line +arguments <A +HREF="synth-running.html#SYNTH-RUNNING-ARGUMENTS" +><TT +CLASS="OPTION" +>--exit</TT +></A +> and +<A +HREF="synth-running.html#SYNTH-RUNNING-ARGUMENTS" +><TT +CLASS="OPTION" +>--no-exit</TT +></A +>. + </P +><P +>If <SPAN +CLASS="GUIMENUITEM" +>Exit</SPAN +> is used while the eCos application +is still running then the I/O auxiliary will first attempt to +terminate the application cleanly, and then exit. + </P +><DIV +CLASS="INFORMALFIGURE" +><A +NAME="AEN349"><P +></P +><DIV +CLASS="MEDIAOBJECT" +><P +><IMG +SRC="menu_edit.gif" +ALIGN="CENTER"></P +></DIV +><P +></P +></DIV +><P +>The <SPAN +CLASS="GUIMENU" +>Edit</SPAN +> menu contains the usual entries for +text manipulation: <SPAN +CLASS="GUIMENUITEM" +>Cut</SPAN +>, +<SPAN +CLASS="GUIMENUITEM" +>Copy</SPAN +>, <SPAN +CLASS="GUIMENUITEM" +>Paste</SPAN +>, +<SPAN +CLASS="GUIMENUITEM" +>Clear</SPAN +> and <SPAN +CLASS="GUIMENUITEM" +>Select +All</SPAN +>. These all operate on the central text window. By +default this window cannot be edited so the cut, paste and clear +operations are disabled. If the user wants to edit the contents of the +text window then the <SPAN +CLASS="GUIMENUITEM" +>Read Only</SPAN +> checkbutton +should be toggled. + </P +><P +>The <SPAN +CLASS="GUIMENUITEM" +>Preferences</SPAN +> menu item brings up a +miscellaneous preferences dialog. One of the preferences relates to +online help: the I/O auxiliary does not currently have a built-in html +viewer; instead it will execute an external browser of some sort. With +the example settings shown, the I/O auxiliary will first attempt to +interact with an existing mozilla session. If that fails it will try +to run a new mozilla instance, or as a last result use the Gnome help +viewer. + </P +><DIV +CLASS="INFORMALFIGURE" +><A +NAME="AEN363"><P +></P +><DIV +CLASS="MEDIAOBJECT" +><P +><IMG +SRC="preferences.gif" +ALIGN="CENTER"></P +></DIV +><P +></P +></DIV +><P +>The <SPAN +CLASS="GUIMENU" +>View</SPAN +> menu contains the <SPAN +CLASS="GUIMENUITEM" +>System +Filters</SPAN +> entry, used to edit the settings for the current +<A +HREF="synth-gui.html#SYNTH-GUI-TEXT" +>filters</A +>. + </P +><DIV +CLASS="INFORMALFIGURE" +><A +NAME="AEN371"><P +></P +><DIV +CLASS="MEDIAOBJECT" +><P +><IMG +SRC="menu_view.gif" +ALIGN="CENTER"></P +></DIV +><P +></P +></DIV +><P +>The <SPAN +CLASS="GUIMENU" +>Help</SPAN +> menu can be used to activate online help +for eCos generally, for the synthetic target as a whole, and for +specific devices supported by the generic target. The Preferences +dialog can be used to select the browser that will be used. + </P +><DIV +CLASS="INFORMALFIGURE" +><A +NAME="AEN377"><P +></P +><DIV +CLASS="MEDIAOBJECT" +><P +><IMG +SRC="menu_help.gif" +ALIGN="CENTER"></P +></DIV +><P +></P +></DIV +><DIV +CLASS="NOTE" +><BLOCKQUOTE +CLASS="NOTE" +><P +><B +>Note: </B +>At the time of writing there is no well-defined toplevel index file +for all eCos documentation. Hence the relevant menu item is disabled. +Documentation for the synthetic target and the supported devices +is stored as part of the package itself so can usually be found fairly +easily. It may be necessary to set the <TT +CLASS="ENVAR" +>ECOS_REPOSITORY</TT +> +environment variable. + </P +></BLOCKQUOTE +></DIV +></DIV +><DIV +CLASS="REFSECT1" +><A +NAME="SYNTH-GUI-TEXT" +></A +><H2 +>The Main Text Window</H2 +><P +>The central text window holds the console output from the eCos +application: the screen shot above shows DHCP initialization data from +the TCP/IP stack, and some output from the <TT +CLASS="FUNCTION" +>main</TT +> +thread at the bottom. Some devices can insert text of their own, for +example the ethernet device support can be configured to show details +of incoming and outgoing packets. Mixing the output from the eCos +application and the various devices can make it easier to understand +the order in which events occur. + </P +><P +>The appearance of text from different sources can be controlled by +means of filters, and it is also possible to hide some of the text. +For example, if tracing is enabled in the eCos configuration then the +trace output can be given its own colour scheme, making it stand out +from the rest of the output. In addition the trace output is generally +voluminous so it can be hidden by default, made visible only to find +out more about what was happening when a particular problem occurred. +Similarly the ethernet device support can output details of the +various packets being transferred, and using a different background +colour for this output again makes it easier to distinguish from +console output. + </P +><P +>The default appearance for most filters is controlled via the +<A +HREF="synth-running.html#SYNTH-RUNNING-TDF" +>target definition file</A +>. An +example entry might be: + </P +><TABLE +BORDER="5" +BGCOLOR="#E0E0F0" +WIDTH="70%" +><TR +><TD +><PRE +CLASS="PROGRAMLISTING" +> filter trace {^TRACE:.*} -foreground HotPink1 -hide 1</PRE +></TD +></TR +></TABLE +><P +>The various colours and the hide flag for each filter can be changed +at run-time, using the <SPAN +CLASS="GUIMENUITEM" +>System Filters</SPAN +> item +on the <SPAN +CLASS="GUIMENU" +>View</SPAN +> menu. This will bring up a dialog like +the following: + </P +><DIV +CLASS="INFORMALFIGURE" +><A +NAME="AEN395"><P +></P +><DIV +CLASS="MEDIAOBJECT" +><P +><IMG +SRC="filters.gif" +ALIGN="CENTER"></P +></DIV +><P +></P +></DIV +><P +>It should be noted that the text window is line-oriented, not +character-oriented. If an eCos application sends a partial line of +text then that will remain buffered until a newline character is +received, rather than being displayed immediately. This avoids +confusion when there is concurrent output from several sources. + </P +><P +>By default the text window is read-only. This means it will not allow +cut, paste and clear operations, and keyboard input will be ignored. +The <SPAN +CLASS="GUIMENU" +>Edit</SPAN +> menu has a checkbutton <SPAN +CLASS="GUIMENUITEM" +>Read +Only</SPAN +> which can be toggled to allow write operations. For +example, a user could type in a reminder of what was happening at this +time, or paste in part of a gdb session. Such keyboard input does not +get forwarded to the eCos application: if the latter requires keyboard +input then that should happen via a separate keyboard device. + </P +></DIV +><DIV +CLASS="REFSECT1" +><A +NAME="SYNTH-GUI-LAYOUT" +></A +><H2 +>Positioning Optional Windows</H2 +><P +>Some devices may create their own subwindows, for example to monitor +ethernet traffic or to provide additional I/O facilities such as +emulated LED's or buttons. Usually the target definition file can be +used to control the <A +HREF="synth-gui.html#SYNTH-GUI-LAYOUT" +>layout</A +> of +these windows. This requires an understanding of the overall layout of +the display. + </P +><DIV +CLASS="INFORMALFIGURE" +><A +NAME="AEN407"><P +></P +><DIV +CLASS="MEDIAOBJECT" +><P +><IMG +SRC="layout.gif" +ALIGN="CENTER"></P +></DIV +><P +></P +></DIV +><P +>Subwindows are generally packed in one of eight frames surrounding the +central text window: <TT +CLASS="VARNAME" +>.main.nw</TT +>, +<TT +CLASS="VARNAME" +>.main.n</TT +>, <TT +CLASS="VARNAME" +>.main.ne</TT +>, +<TT +CLASS="VARNAME" +>.main.w</TT +>, <TT +CLASS="VARNAME" +>.main.e</TT +>, +<TT +CLASS="VARNAME" +>.main.sw</TT +>, <TT +CLASS="VARNAME" +>.main.s</TT +>, and +<TT +CLASS="VARNAME" +>.main.se</TT +>. To position a row of LED's above the text +window and towards the left, a target definition file could contain an +entry such as: + </P +><TABLE +BORDER="5" +BGCOLOR="#E0E0F0" +WIDTH="70%" +><TR +><TD +><PRE +CLASS="PROGRAMLISTING" +>synth_device led { + pack -in .main.n -side left + … +}</PRE +></TD +></TR +></TABLE +><P +>Similarly, to put a traffic monitor window on the right of the text +window would involve something like: + </P +><TABLE +BORDER="5" +BGCOLOR="#E0E0F0" +WIDTH="70%" +><TR +><TD +><PRE +CLASS="PROGRAMLISTING" +> … + monitor_pack -in .main.e -side bottom + …</PRE +></TD +></TR +></TABLE +><P +>Often it will be sufficient to specify a container frame and one of +<TT +CLASS="CONSTANT" +>left</TT +>, <TT +CLASS="CONSTANT" +>right</TT +>, +<TT +CLASS="CONSTANT" +>top</TT +> or <TT +CLASS="CONSTANT" +>bottom</TT +>. Full control +over the positioning requires an understanding of Tcl/Tk and in +particular the packing algorithm, and an appropriate reference work +should be consulted. + </P +></DIV +><DIV +CLASS="REFSECT1" +><A +NAME="SYNTH-GUI-GLOBAL-CONFIG" +></A +><H2 +>Global Settings</H2 +><DIV +CLASS="NOTE" +><BLOCKQUOTE +CLASS="NOTE" +><P +><B +>Note: </B +>This section still to be written - it should document the interaction +between X resources and ecosynth, and how users can control settings +such as the main foreground and background colours. + </P +></BLOCKQUOTE +></DIV +></DIV +><DIV +CLASS="NAVFOOTER" +><HR +ALIGN="LEFT" +WIDTH="100%"><TABLE +SUMMARY="Footer navigation table" +WIDTH="100%" +BORDER="0" +CELLPADDING="0" +CELLSPACING="0" +><TR +><TD +WIDTH="33%" +ALIGN="left" +VALIGN="top" +><A +HREF="synth-running.html" +ACCESSKEY="P" +>Prev</A +></TD +><TD +WIDTH="34%" +ALIGN="center" +VALIGN="top" +><A +HREF="hal-synth-arch.html" +ACCESSKEY="H" +>Home</A +></TD +><TD +WIDTH="33%" +ALIGN="right" +VALIGN="top" +><A +HREF="synth-console.html" +ACCESSKEY="N" +>Next</A +></TD +></TR +><TR +><TD +WIDTH="33%" +ALIGN="left" +VALIGN="top" +>Running a Synthetic Target Application</TD +><TD +WIDTH="34%" +ALIGN="center" +VALIGN="top" +> </TD +><TD +WIDTH="33%" +ALIGN="right" +VALIGN="top" +>The Console Device</TD +></TR +></TABLE +></DIV +></BODY +></HTML +> \ No newline at end of file
new file mode 100644 --- /dev/null +++ b/packages/hal/synth/arch/current/doc/synth-install.html @@ -0,0 +1,404 @@ +<!-- Copyright (C) 2002 Red Hat, Inc. --> +<!-- This material may be distributed only subject to the terms --> +<!-- and conditions set forth in the Open Publication License, v1.0 --> +<!-- or later (the latest version is presently available at --> +<!-- http://www.opencontent.org/openpub/). --> +<!-- Distribution of the work or derivative of the work in any --> +<!-- standard (paper) book form is prohibited unless prior --> +<!-- permission is obtained from the copyright holder. --> +<HTML +><HEAD +><TITLE +>Installation</TITLE +><meta name="MSSmartTagsPreventParsing" content="TRUE"> +<META +NAME="GENERATOR" +CONTENT="Modular DocBook HTML Stylesheet Version 1.76b+ +"><LINK +REL="HOME" +TITLE="eCos Synthetic Target" +HREF="hal-synth-arch.html"><LINK +REL="PREVIOUS" +TITLE="Overview" +HREF="synth.html"><LINK +REL="NEXT" +TITLE="Running a Synthetic Target Application" +HREF="synth-running.html"></HEAD +><BODY +CLASS="REFENTRY" +BGCOLOR="#FFFFFF" +TEXT="#000000" +LINK="#0000FF" +VLINK="#840084" +ALINK="#0000FF" +><DIV +CLASS="NAVHEADER" +><TABLE +SUMMARY="Header navigation table" +WIDTH="100%" +BORDER="0" +CELLPADDING="0" +CELLSPACING="0" +><TR +><TH +COLSPAN="3" +ALIGN="center" +>eCos Synthetic Target</TH +></TR +><TR +><TD +WIDTH="10%" +ALIGN="left" +VALIGN="bottom" +><A +HREF="synth.html" +ACCESSKEY="P" +>Prev</A +></TD +><TD +WIDTH="80%" +ALIGN="center" +VALIGN="bottom" +></TD +><TD +WIDTH="10%" +ALIGN="right" +VALIGN="bottom" +><A +HREF="synth-running.html" +ACCESSKEY="N" +>Next</A +></TD +></TR +></TABLE +><HR +ALIGN="LEFT" +WIDTH="100%"></DIV +><H1 +><A +NAME="SYNTH-INSTALL">Installation</H1 +><DIV +CLASS="REFNAMEDIV" +><A +NAME="AEN45" +></A +><H2 +>Name</H2 +>Installation -- Preparing to use the synthetic target</DIV +><DIV +CLASS="REFSECT1" +><A +NAME="SYNTH-INSTALL-HOST" +></A +><H2 +>Host-side Software</H2 +><P +>To get the full functionality of the synthetic target, users must +build and install the I/O auxiliary ecosynth and various support +files. It is possible to develop applications for the synthetic target +without the auxiliary, but only limited I/O facilities will be +available. The relevant code resides in the <TT +CLASS="FILENAME" +>host</TT +> subdirectory of the synthetic target +architectural HAL package, and building it involves the standard +<B +CLASS="COMMAND" +>configure</B +>, <B +CLASS="COMMAND" +>make</B +>, and +<B +CLASS="COMMAND" +>make install</B +> steps. + </P +><P +>There are two main ways of building the host-side software. It is +possible to build both the generic host-side software and all +package-specific host-side software, including the I/O auxiliary. in a +single build tree. This involves using the +<B +CLASS="COMMAND" +>configure</B +> script at the toplevel of the eCos +repository, which will automatically search the <TT +CLASS="FILENAME" +>packages</TT +> hierarchy for host-side +software. For more information on this, see the +<TT +CLASS="FILENAME" +>README.host</TT +> file at the top of the repository. +Note that if you have an existing build tree which does not include +the synthetic target architectural HAL package then it will be +necessary to rerun the toplevel configure script: the search for +appropriate packages happens at configure time. + </P +><P +>The alternative is to build just the host-side for this package. +This involves creating a suitable build directory and running the +<B +CLASS="COMMAND" +>configure</B +> script. Note that building directly in +the source tree is not allowed. + </P +><TABLE +BORDER="5" +BGCOLOR="#E0E0F0" +WIDTH="70%" +><TR +><TD +><PRE +CLASS="SCREEN" +>$ cd <somewhere suitable> +$ mkdir synth_build +$ cd synth_build +$ <repo<>/packages/hal/synth/arch/<version>/host/configure <options> +$ make +$ make install</PRE +></TD +></TR +></TABLE +><P +>The code makes extensive use of Tcl/TK and requires version 8.3 or +later. This is checked by the <B +CLASS="COMMAND" +>configure</B +> script. By +default it will use the system's Tcl installation in <TT +CLASS="FILENAME" +>/usr</TT +>. If a different, more recent Tcl +installation should be used then its location can be specified using +the options <TT +CLASS="OPTION" +>--with-tcl=<path></TT +>, +<TT +CLASS="OPTION" +>--with-tcl-header=<path></TT +> and +<TT +CLASS="OPTION" +>--with-tcl-lib=<path></TT +>. For more information on these options +see the <TT +CLASS="FILENAME" +>README.host</TT +> file at the toplevel of the +eCos repository. + </P +><P +>Some users may also want to specify the install location using a +<TT +CLASS="OPTION" +>--prefix=<path></TT +> option. The default install +location is <TT +CLASS="FILENAME" +>/usr/local</TT +>. It is +essential that the <TT +CLASS="FILENAME" +>bin</TT +> +subdirectory of the install location is on the user's search +<TT +CLASS="ENVAR" +>PATH</TT +>, otherwise the eCos application will be unable to +locate and execute the I/O auxiliary ecosynth. + </P +><P +>Because ecosynth is run automatically by an eCos application rather +than explicitly by the user, it is not installed in the <TT +CLASS="FILENAME" +>bin</TT +> subdirectory itself. Instead it is +installed below <TT +CLASS="FILENAME" +>libexec</TT +>, +together with various support files such as images. At configure time +it is usually possible to specify an alternative location for +<TT +CLASS="FILENAME" +>libexec</TT +> using +<TT +CLASS="OPTION" +>--exec-prefix=<path></TT +> or +<TT +CLASS="OPTION" +>--libexecdir=<path></TT +>. These options should not +be used for this package because the eCos application is built +completely separately and does not know how the host-side was +configured. + </P +></DIV +><DIV +CLASS="REFSECT1" +><A +NAME="SYNTH-TOOLS" +></A +><H2 +>Toolchain</H2 +><P +>When developing eCos applications for a normal embedded target it is +necessary to use a suitable cross-compiler and related tools such as +the linker. Developing for the synthetic target is easier because you +can just use the standard GNU tools (gcc, g++, ld, …) which +were provided with your Linux distribution, or which you used to build +your own Linux setup. Any reasonably recent version of the tools, for +example gcc 2.96(Red Hat) as shipped with Red Hat Linux 7, should be +sufficient. + </P +><P +>There is one important limitation when using these tools: current gdb +will not support debugging of eCos threads on the synthetic target. As +far as gdb is concerned a synthetic target application is +indistinguishable from a normal Linux application, so it assumes that +any threads will be created by calls to the Linux +<TT +CLASS="FUNCTION" +>pthread_create</TT +> function provided by the C +library. Obviously this is not the case since the application is never +linked with that library. Therefore gdb never notices the eCos thread +mechanisms and assumes the application is single-threaded. Fixing this +is possible but would involve non-trivial changes to gdb. + </P +><P +>Theoretically it is possible to develop synthetic target applications +on, for example, a PC running Windows and then run the resulting +executables on another machine that runs Linux. This is rarely useful: +if a Linux machine is available then usually that machine will also be +used for building ecos and the application. However, if for some +reason it is necessary or desirable to build on another machine then +this requires a suitable cross-compiler and related tools. If the +application will be running on a typical PC with an x86 processor then +a suitable configure triplet would be +<TT +CLASS="USERINPUT" +><B +>i686-pc-linux-gnu</B +></TT +>. The installation +instructions for the various GNU tools should be consulted for further +information. + </P +></DIV +><DIV +CLASS="REFSECT1" +><A +NAME="SYNTH-HARDWARE" +></A +><H2 +>Hardware Preparation</H2 +><P +>Preparing a real embedded target for eCos development can be tricky. +Often the first step is to install suitable firmware, usually RedBoot. +This means creating and building a special configuration for eCos with +the RedBoot template, then somehow updating the target's flash chips +with the resulting RedBoot image. Typically it will also be necessary +to get a working serial connection, and possibly set up ethernet as +well. Although usually none of the individual steps are particularly +complicated, there are plenty of ways in which things can go wrong and +it can be hard to figure out what is actually happening. Of course +some board manufacturers make life easier for their developers by +shipping hardware with RedBoot preinstalled, but even then it is still +necessary to set up communication between host and target. + </P +><P +>None of this is applicable to the synthetic target. Instead you can +just build a normal eCos configuration, link your application with the +resulting libraries, and you end up with an executable that you can +run directly on your Linux machine or via gdb. A useful side effect of +this is that application development can start before any real +embedded hardware is actually available. + </P +><P +>Typically the memory map for a synthetic target application will be +set up such that there is a read-only ROM region containing all the +code and constant data, and a read-write RAM region for the data. The +default locations and sizes of these regions depend on the specific +platform being used for development. Note that the application always +executes out of ROM: on a real embedded target much of the development +would involve running RedBoot firmware there, with application code +and data loaded into RAM; usually this would change for the final +system; the firmware would be replaced by the eCos application itself, +configured for ROM bootstrap, and it would perform the appropriate +hardware initialization. Therefore the synthetic target actually +emulates the behaviour of a final system, not of a development +environment. In practice this is rarely significant, although having +the code in read-only memory can help catch some problems in +application code. + </P +></DIV +><DIV +CLASS="NAVFOOTER" +><HR +ALIGN="LEFT" +WIDTH="100%"><TABLE +SUMMARY="Footer navigation table" +WIDTH="100%" +BORDER="0" +CELLPADDING="0" +CELLSPACING="0" +><TR +><TD +WIDTH="33%" +ALIGN="left" +VALIGN="top" +><A +HREF="synth.html" +ACCESSKEY="P" +>Prev</A +></TD +><TD +WIDTH="34%" +ALIGN="center" +VALIGN="top" +><A +HREF="hal-synth-arch.html" +ACCESSKEY="H" +>Home</A +></TD +><TD +WIDTH="33%" +ALIGN="right" +VALIGN="top" +><A +HREF="synth-running.html" +ACCESSKEY="N" +>Next</A +></TD +></TR +><TR +><TD +WIDTH="33%" +ALIGN="left" +VALIGN="top" +>Overview</TD +><TD +WIDTH="34%" +ALIGN="center" +VALIGN="top" +> </TD +><TD +WIDTH="33%" +ALIGN="right" +VALIGN="top" +>Running a Synthetic Target Application</TD +></TR +></TABLE +></DIV +></BODY +></HTML +> \ No newline at end of file
new file mode 100644 --- /dev/null +++ b/packages/hal/synth/arch/current/doc/synth-new-host.html @@ -0,0 +1,1734 @@ +<!-- Copyright (C) 2002 Red Hat, Inc. --> +<!-- This material may be distributed only subject to the terms --> +<!-- and conditions set forth in the Open Publication License, v1.0 --> +<!-- or later (the latest version is presently available at --> +<!-- http://www.opencontent.org/openpub/). --> +<!-- Distribution of the work or derivative of the work in any --> +<!-- standard (paper) book form is prohibited unless prior --> +<!-- permission is obtained from the copyright holder. --> +<HTML +><HEAD +><TITLE +>Writing New Devices - host</TITLE +><meta name="MSSmartTagsPreventParsing" content="TRUE"> +<META +NAME="GENERATOR" +CONTENT="Modular DocBook HTML Stylesheet Version 1.76b+ +"><LINK +REL="HOME" +TITLE="eCos Synthetic Target" +HREF="hal-synth-arch.html"><LINK +REL="PREVIOUS" +TITLE="Writing New Devices - target" +HREF="synth-new-target.html"><LINK +REL="NEXT" +TITLE="Porting" +HREF="synth-porting.html"></HEAD +><BODY +CLASS="REFENTRY" +BGCOLOR="#FFFFFF" +TEXT="#000000" +LINK="#0000FF" +VLINK="#840084" +ALINK="#0000FF" +><DIV +CLASS="NAVHEADER" +><TABLE +SUMMARY="Header navigation table" +WIDTH="100%" +BORDER="0" +CELLPADDING="0" +CELLSPACING="0" +><TR +><TH +COLSPAN="3" +ALIGN="center" +>eCos Synthetic Target</TH +></TR +><TR +><TD +WIDTH="10%" +ALIGN="left" +VALIGN="bottom" +><A +HREF="synth-new-target.html" +ACCESSKEY="P" +>Prev</A +></TD +><TD +WIDTH="80%" +ALIGN="center" +VALIGN="bottom" +></TD +><TD +WIDTH="10%" +ALIGN="right" +VALIGN="bottom" +><A +HREF="synth-porting.html" +ACCESSKEY="N" +>Next</A +></TD +></TR +></TABLE +><HR +ALIGN="LEFT" +WIDTH="100%"></DIV +><H1 +><A +NAME="SYNTH-NEW-HOST">Writing New Devices - host</H1 +><DIV +CLASS="REFNAMEDIV" +><A +NAME="AEN726" +></A +><H2 +>Name</H2 +>Writing New Devices -- extending the synthetic target, host-side</DIV +><DIV +CLASS="REFSECT1" +><A +NAME="SYNTH-NEW-HOST-DESCRIPTION" +></A +><H2 +>Description</H2 +><P +>On the host-side adding a new device means writing a Tcl/Tk script +that will handle instantiation and subsequent requests from the +target-side. These scripts all run in the same full interpreter, +extended with various commands provided by the main I/O auxiliary +code, and running in an overall GUI framework. Some knowledge of +programming with Tcl/Tk is required to implement host-side device +support. + </P +><P +>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 +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 +advanced emulation could organize the buttons with the right layout, +perhaps even matching the colour scheme, the shapes, and the relative +sizes. With other devices it may be necessary for the Tcl script to +interact with an external program, because the required functionality +cannot easily be accessed from a Tcl script. For example interacting +with a raw ethernet device involves some <TT +CLASS="FUNCTION" +>ioctl</TT +> +calls, which is easier to do in a C program. Therefore the +<TT +CLASS="FILENAME" +>ethernet.tcl</TT +> script which implements the +host-side ethernet support spawns a separate program +<TT +CLASS="FILENAME" +>rawether</TT +>, written in C, that performs the +low-level I/O. Raw ethernet access usually also requires root +privileges, and running a small program <TT +CLASS="FILENAME" +>rawether</TT +> +with such privileges is somewhat less of a security risk than the +whole eCos application, the I/O auxiliary, and various dynamically +loaded Tcl scripts. + </P +><P +>Because all scripts run in a single interpreter, some care has +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 +namespace, so for example the <TT +CLASS="FILENAME" +>ethernet.tcl</TT +> script +creates a namespace <TT +CLASS="VARNAME" +>ethernet::</TT +> and all variables +and procedures reside in this namespace. Similarly the I/O auxiliary +itself makes use of a <TT +CLASS="VARNAME" +>synth::</TT +> namespace. + </P +></DIV +><DIV +CLASS="REFSECT1" +><A +NAME="SYNTH-NEW-HOST-BUILD" +></A +><H2 +>Building and Installation</H2 +><P +>When an eCos device driver or application code instantiates a device, +the I/O auxiliary will attempt to load a matching Tcl script. The +third argument to <TT +CLASS="FUNCTION" +>synth_auxiliary_instantiate</TT +> +specifies the type of device, for example <TT +CLASS="LITERAL" +>ethernet</TT +>, +and the I/O auxiliary will append a <TT +CLASS="FILENAME" +>.tcl</TT +> suffix +and look for a script <TT +CLASS="FILENAME" +>ethernet.tcl</TT +>. + </P +><P +>If the device being instantiated is application-specific rather than +part of an eCos package, the I/O auxiliary will look first in the +current directory, then in <TT +CLASS="FILENAME" +>~/.ecos/synth</TT +>. If it is part of an eCos +package then the auxiliary will expect to find the Tcl script and any +support files below <TT +CLASS="FILENAME" +>libexec/ecos</TT +> in the install tree - note +that the same install tree must be used for the I/O auxiliary itself +and for any device driver support. The directory hierarchy below +<TT +CLASS="FILENAME" +>libexec/ecos</TT +> matches the +structure of the eCos repository, allowing multiple versions of a +package to be installed to allow for incompatible protocol changes. + </P +><P +>The preferred way to build host-side software is to use +<B +CLASS="COMMAND" +>autoconf</B +> and <B +CLASS="COMMAND" +>automake</B +>. Usually +this involves little more than copying the +<TT +CLASS="FILENAME" +>acinclude.m4</TT +>, <TT +CLASS="FILENAME" +>configure.in</TT +> +and <TT +CLASS="FILENAME" +>Makefile.am</TT +> files from an existing package, +for example the synthetic target ethernet driver, and then making +minor edits. In <TT +CLASS="FILENAME" +>acinclude.m4</TT +> it may be necessary +to adjust the path to the root of the repository. +<TT +CLASS="FILENAME" +>configure.in</TT +> may require a similar change, and +the <TT +CLASS="FUNCTION" +>AC_INIT</TT +> macro invocation will have to be +changed to match one of the files in the new package. A critical macro +in this file is <TT +CLASS="FILENAME" +>ECOS_PACKAGE_DIRS</TT +> which will set +up the correct install directory. <TT +CLASS="FILENAME" +>Makefile.am</TT +> may +require some more changes, for example to specify the data files that +should be installed (including the Tcl script). These files should +then be processed using <B +CLASS="COMMAND" +>aclocal</B +>, +<B +CLASS="COMMAND" +>autoconf</B +> and <B +CLASS="COMMAND" +>automake</B +> in that +order. Actually building the software then just involves +<B +CLASS="COMMAND" +>configure</B +>, <B +CLASS="COMMAND" +>make</B +> and +<B +CLASS="COMMAND" +>make install</B +>, as per the instructions in the +toplevel <TT +CLASS="FILENAME" +>README.host</TT +> file. + </P +><P +>To assist developers, if the environment variable +<TT +CLASS="ENVAR" +>ECOSYNTH_DEVEL</TT +> is set then a slightly different +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 +source tree, and if the script there is more recent than the installed +version it will be used in preference. This allows developers to +modify the master copy without having to run <B +CLASS="COMMAND" +>make +install</B +> all the time. + </P +><P +>If a script needs to know where it has been installed it can examine +the Tcl variable <TT +CLASS="VARNAME" +>synth::device_install_dir</TT +> . This +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 +variable. + </P +></DIV +><DIV +CLASS="REFSECT1" +><A +NAME="SYNTH-NEW-HOST-INSTANTIATION" +></A +><H2 +>Instantiation</H2 +><P +>The I/O auxiliary will <B +CLASS="COMMAND" +>source</B +> the device-specific +Tcl script when the eCos application first attempts to instantiate a +device of that type. The script should return a procedure that will be +invoked to instantiate a device. + </P +><TABLE +BORDER="5" +BGCOLOR="#E0E0F0" +WIDTH="70%" +><TR +><TD +><PRE +CLASS="PROGRAMLISTING" +>namespace eval ethernet { + … + proc instantiate { id instance data } { + … + return ethernet::handle_request + } +} +return ethernet::instantiate</PRE +></TD +></TR +></TABLE +><P +>The <TT +CLASS="VARNAME" +>id</TT +> argument is a unique identifier for this +device instance. It will also be supplied on subsequent calls to the +request handler, and will match the return value of +<TT +CLASS="FUNCTION" +>synth_auxiliary_instantiate</TT +> on the target side. A +common use for this value is as an array index to support multiple +instances of this types of device. The <TT +CLASS="VARNAME" +>instance</TT +> and +<TT +CLASS="VARNAME" +>data</TT +> arguments match the corresponding arguments to +<TT +CLASS="FUNCTION" +>synth_auxiliary_instantiate</TT +> on the target side, so +a typical value for <TT +CLASS="VARNAME" +>instance</TT +> would be +<TT +CLASS="LITERAL" +>eth0</TT +>, and <TT +CLASS="VARNAME" +>data</TT +> is used to pass +arbitrary initialization parameters from target to host. + </P +><P +>The actual work done by the instantiation procedure is obviously +device-specific. It may involve allocating an <A +HREF="synth-new-host.html#SYNTH-NEW-HOST-INTERRUPTS" +>interrupt vector</A +>, adding a +device-specific subwindow to the display, opening a real Linux device, +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 +the above. + </P +><P +>If the device is successfully instantiated then the return value +should be a handler for subsequent I/O requests. Otherwise the return +value should be an empty string, and on the target-side the +<TT +CLASS="FUNCTION" +>synth_auxiliary_instantiate</TT +> call will return +<TT +CLASS="LITERAL" +>-1</TT +>. The script is responsible for providing +<A +HREF="synth-new-host.html#SYNTH-NEW-HOST-OUTPUT" +>diagnostics</A +> explaining +why the device could not be instantiated. + </P +></DIV +><DIV +CLASS="REFSECT1" +><A +NAME="SYNTH-NEW-HOST-REQUESTS" +></A +><H2 +>Handling Requests</H2 +><P +>When the target-side calls +<TT +CLASS="FUNCTION" +>synth_auxiliary_xchgmsg</TT +>, the I/O auxiliary will +end up calling the request handler for the appropriate device instance +returned during instantiation: + </P +><TABLE +BORDER="5" +BGCOLOR="#E0E0F0" +WIDTH="70%" +><TR +><TD +><PRE +CLASS="PROGRAMLISTING" +>namespace eval ethernet { + … + proc handle_request { id request arg1 arg2 txdata txlen max_rxlen } { + … + if { <some condition> } { + synth::send_reply <error code> 0 "" + return + } + … + synth::send_reply <reply code> $packet_len $packet + } + … +}</PRE +></TD +></TR +></TABLE +><P +>The <TT +CLASS="VARNAME" +>id</TT +> argument is the same device id that was +passed to the instantiate function, and is typically used as an array +index to access per-device data. The <TT +CLASS="VARNAME" +>request</TT +>, +<TT +CLASS="VARNAME" +>arg1</TT +>, <TT +CLASS="VARNAME" +>arg2</TT +>, and +<TT +CLASS="VARNAME" +>max_rxlen</TT +> are the same values that were passed to +<TT +CLASS="FUNCTION" +>synth_auxiliary_xchgmsg</TT +> on the target-side, +although since this is a Tcl script obviously the numbers have been +converted to strings. The <TT +CLASS="VARNAME" +>txdata</TT +> buffer is raw data +as transmitted by the target, or an empty string if the I/O operation +does not involve any additional data. The Tcl procedures +<B +CLASS="COMMAND" +>binary scan</B +>, <B +CLASS="COMMAND" +>string index</B +> and +<B +CLASS="COMMAND" +>string range</B +> may be found especially useful when +manipulating this buffer. <TT +CLASS="VARNAME" +>txlen</TT +> is provided for +convenience, although <B +CLASS="COMMAND" +>string length $txdata</B +> would +give the same information. + </P +><P +>The code for actually processing the request is of course device +specific. If the target does not expect a reply then the request +handler should just return when finished. If a reply is expected then +there should be a call to <B +CLASS="COMMAND" +>synth::send_reply</B +>. The +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 +of the reply data, and the third argument is the reply data itself. +For some devices the Tcl procedure <B +CLASS="COMMAND" +>binary format</B +> +may prove useful. If the reply involves just a code and no additional +data, the second and third arguments should be <TT +CLASS="LITERAL" +>0</TT +> +and an empty string respectively. + </P +><P +>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 +target-side expects, will all be detected by the I/O auxiliary and +result in run-time error messages. + </P +><P +>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 +example because some I/O operation has completed, then an interrupt +should be raised. + </P +></DIV +><DIV +CLASS="REFSECT1" +><A +NAME="SYNTH-NEW-HOST-INTERRUPTS" +></A +><H2 +>Interrupts</H2 +><P +>The I/O auxiliary provides a number of procedures for interrupt +handling. + </P +><TABLE +BORDER="5" +BGCOLOR="#E0E0F0" +WIDTH="70%" +><TR +><TD +><PRE +CLASS="PROGRAMLISTING" +>synth::interrupt_allocate <name> +synth::interrupt_get_max +synth::interrupt_get_devicename <vector> +synth::interrupt_raise <vector></PRE +></TD +></TR +></TABLE +><P +><B +CLASS="COMMAND" +>synth::interrupt_allocate</B +> is normally called during +device instantiation, and returns the next free interrupt vector. This +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 +vector. Interrupt vector <TT +CLASS="LITERAL" +>0</TT +> is used within the +target-side code for the real-time clock, so the allocated vectors +will start at <TT +CLASS="LITERAL" +>1</TT +>. The argument identifies the +device, for example <TT +CLASS="LITERAL" +>eth0</TT +>. This is not actually used +internally, but can be accessed by user-initialization scripts that +provide some sort of interrupt monitoring facility (typically via the +<TT +CLASS="LITERAL" +>interrupt</TT +> <A +HREF="synth-new-host.html#SYNTH-NEW-HOST-HOOKS" +>hook</A +>). It is possible for a +single device to allocate multiple interrupt vectors, but the +synthetic target supports a maximum of 32 such vectors. + </P +><P +><B +CLASS="COMMAND" +>synth::interrupt_get_max</B +> returns the highest +interrupt vector that has been allocated, or <TT +CLASS="LITERAL" +>0</TT +> if +there have been no calls to +<B +CLASS="COMMAND" +>synth::interrupt_allocate</B +>. +<B +CLASS="COMMAND" +>synth::interrupt_get_devicename</B +> returns the string +that was passed to <B +CLASS="COMMAND" +>synth::interrupt_allocate</B +> when +the vector was allocated. + </P +><P +><B +CLASS="COMMAND" +>synth::interrupt_raise</B +> can be called any time after +initialization. The argument should be the vector returned by +<B +CLASS="COMMAND" +>synth::interrupt_allocate</B +> for this device. It will +activate the normal eCos interrupt handling mechanism so, subject to +interrupts being enabled and this particular interrupt not being +masked out, the appropriate ISR will run. + </P +><DIV +CLASS="NOTE" +><BLOCKQUOTE +CLASS="NOTE" +><P +><B +>Note: </B +>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 +devices effectively depends on the order in which the eCos devices get +initialized, and that may change if the eCos application is rebuilt. A +future extension may allow devices to allocate specific vectors, thus +making things more deterministic. However that will introduce new +problems, in particular the code will have to start worrying about +requests for vectors that have already been allocated. + </P +></BLOCKQUOTE +></DIV +></DIV +><DIV +CLASS="REFSECT1" +><A +NAME="SYNTH-NEW-HOST-ARGS" +></A +><H2 +>Flags and Command Line Arguments</H2 +><P +>The generic I/O auxiliary code will process the standard command line +arguments, and will set various flag variables accordingly. Some of +these should be checked by device-specific scripts. + </P +><P +></P +><DIV +CLASS="VARIABLELIST" +><DL +><DT +><TT +CLASS="VARNAME" +>synth::flag_gui</TT +></DT +><DD +><P +>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 +layout are only available in graphical mode. + </P +><TABLE +BORDER="5" +BGCOLOR="#E0E0F0" +WIDTH="70%" +><TR +><TD +><PRE +CLASS="PROGRAMLISTING" +> if { $synth::flag_gui } { + … + }</PRE +></TD +></TR +></TABLE +></DD +><DT +><TT +CLASS="VARNAME" +>synth::flag_verbose</TT +></DT +><DD +><P +>The user has requested additional information during startup. Each +device driver can decide how much additional information, if any, +should be produced. + </P +></DD +><DT +><TT +CLASS="VARNAME" +>synth::flag_keep_going</TT +></DT +><DD +><P +>The user has specified <TT +CLASS="OPTION" +>-k</TT +> or +<TT +CLASS="OPTION" +>--keep-going</TT +>, so even if an error occurs the I/O +auxiliary and the various device driver scripts should continue running +if at all possible. Diagnostics should still be generated. + </P +></DD +></DL +></DIV +><P +>Some scripts may want to support additional command line arguments. +This facility should be used with care since there is no way to +prevent two different scripts from trying to use the same argument. +The following Tcl procedures are available: + </P +><TABLE +BORDER="5" +BGCOLOR="#E0E0F0" +WIDTH="70%" +><TR +><TD +><PRE +CLASS="PROGRAMLISTING" +>synth::argv_defined <name> +synth::argv_get_value <name></PRE +></TD +></TR +></TABLE +><P +><B +CLASS="COMMAND" +>synth::argv_defined</B +> returns a boolean to indicate +whether or not a particular argument is present. If the argument is +the name part of a name/value pair, an <TT +CLASS="LITERAL" +>=</TT +> character +should be appended. Typical uses might be: + </P +><TABLE +BORDER="5" +BGCOLOR="#E0E0F0" +WIDTH="70%" +><TR +><TD +><PRE +CLASS="PROGRAMLISTING" +> if { [synth::argv_defined "-o13"] } { + … + } + + if { [synth::argv_defined "-mark="] } { + … + }</PRE +></TD +></TR +></TABLE +><P +>The first call checks for a flag <TT +CLASS="LITERAL" +>-o13</TT +> or +<TT +CLASS="LITERAL" +>--o13</TT +> - the code treats options with single and +double hyphens interchangeably. The second call checks for an argument +of the form <TT +CLASS="LITERAL" +>-mark=<value></TT +> or a pair of +arguments <TT +CLASS="LITERAL" +>-mark <value></TT +>. The value part of a +name/value pair can be obtained using +<B +CLASS="COMMAND" +>synth::argv_get_value</B +>; + </P +><TABLE +BORDER="5" +BGCOLOR="#E0E0F0" +WIDTH="70%" +><TR +><TD +><PRE +CLASS="PROGRAMLISTING" +> variable speed 1 + if { [synth::argv_defined "-mark="] } { + set mark [synth::argv_get_value "-mark="] + if { ![string is integer $mark] || ($mark < 1) || ($mark > 9) } { + <issue diagnostic> + } else { + set speed $mark + } + }</PRE +></TD +></TR +></TABLE +><P +><B +CLASS="COMMAND" +>synth::argv_get_value</B +> should only be used after a +successful call to <B +CLASS="COMMAND" +>synth::argv_defined</B +>. +At present there is no support for some advanced forms of command line +argument processing. For example it is not possible to repeat a +certain option such as <TT +CLASS="OPTION" +>-v</TT +> or +<TT +CLASS="OPTION" +>--verbose</TT +>, with each occurrence increasing the level +of verbosity. + </P +><P +>If a script is going to have its own set of command-line arguments +then it should give appropriate details if the user specifies +<TT +CLASS="OPTION" +>--help</TT +>. This involves a hook function: + </P +><TABLE +BORDER="5" +BGCOLOR="#E0E0F0" +WIDTH="70%" +><TR +><TD +><PRE +CLASS="PROGRAMLISTING" +>namespace eval my_device { + proc help_hook { } { + puts " -o13 : activate the omega 13 device" + puts " -mark <speed> : set speed. Valid values are 1 to 9." + } + + synth::hook_add "help" my_device::help_hook +}</PRE +></TD +></TR +></TABLE +></DIV +><DIV +CLASS="REFSECT1" +><A +NAME="SYNTH-NEW-HOST-TDF" +></A +><H2 +>The Target Definition File</H2 +><P +>Most device scripts will want to check entries in the target +definition file for run-time configuration information. The Tcl +procedures for this are as follows: + </P +><TABLE +BORDER="5" +BGCOLOR="#E0E0F0" +WIDTH="70%" +><TR +><TD +><PRE +CLASS="PROGRAMLISTING" +>synth::tdf_has_device <name> +synth::tdf_get_devices +synth::tdf_has_option <devname> <option> +synth::tdf_get_option <devname> <option> +synth::tdf_get_options <devname> <option> +synth::tdf_get_all_options <devname></PRE +></TD +></TR +></TABLE +><P +><B +CLASS="COMMAND" +>synth::tdf_has_device</B +> can be used to check whether +or not the target definition file had an entry +<TT +CLASS="LITERAL" +>synth_device <name></TT +>. Usually the name +will match the type of device, so the +<TT +CLASS="FILENAME" +>console.tcl</TT +> script will look for a target +definition file entry <TT +CLASS="LITERAL" +>console</TT +>. +<B +CLASS="COMMAND" +>synth::tdf_get_devices</B +> returns a list of all +device entries in the target definition file. + </P +><P +>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. +<B +CLASS="COMMAND" +>synth::tdf_has_option</B +> just checks for the presence, +returning a boolean: + </P +><TABLE +BORDER="5" +BGCOLOR="#E0E0F0" +WIDTH="70%" +><TR +><TD +><PRE +CLASS="PROGRAMLISTING" +> if { [synth::tdf_has_option "console" "appearance"] } { + … + }</PRE +></TD +></TR +></TABLE +><P +><B +CLASS="COMMAND" +>synth::tdf_get_option</B +> returns a list of all the +arguments for a given option. For example, if the target definition +file contains an entry: + </P +><TABLE +BORDER="5" +BGCOLOR="#E0E0F0" +WIDTH="70%" +><TR +><TD +><PRE +CLASS="PROGRAMLISTING" +>synth_device console { + appearance -foreground white -background black + filter trace {^TRACE:.*} -foreground HotPink1 -hide 1 + filter xyzzy {.*xyzzy.*} -foreground PapayaWhip +}</PRE +></TD +></TR +></TABLE +><P +>A call +<B +CLASS="COMMAND" +>synth::tdf_get_option console appearance</B +> +will return the list <TT +CLASS="LITERAL" +>{-foreground white -background +black}</TT +>. This list can be manipulated using standard Tcl routines +such as <B +CLASS="COMMAND" +>llength</B +> and <B +CLASS="COMMAND" +>lindex</B +>. Some +options can occur multiple times in one entry, for example +<TT +CLASS="OPTION" +>filter</TT +> in the <TT +CLASS="LITERAL" +>console</TT +> entry. +<B +CLASS="COMMAND" +>synth::tdf_get_options</B +> returns a list of lists, +with one entry for each option occurrence. +<B +CLASS="COMMAND" +>synth::tdf_get_all_options</B +> returns a list of lists +of all options. This time each entry will include the option name as +well. + </P +><P +>The I/O auxiliary will not issue warnings about entries in the target +definition file for devices which were not loaded, unless the +<TT +CLASS="OPTION" +>-v</TT +> or <TT +CLASS="OPTION" +>--verbose</TT +> command line +argument was used. This makes it easier to use a single target +definition file for different applications. However the auxiliary will +issue warnings about options within an entry that were ignored, +because often these indicate a typing mistake of some sort. Hence a +script should always call <B +CLASS="COMMAND" +>synth::tdf_has_option</B +>, +<B +CLASS="COMMAND" +>synth:;tdf_get_option</B +> or +<B +CLASS="COMMAND" +>synth::tdf_get_options</B +> for all valid options, even +if some of the options preclude the use of others. + </P +></DIV +><DIV +CLASS="REFSECT1" +><A +NAME="SYNTH-NEW-HOST-HOOKS" +></A +><H2 +>Hooks</H2 +><P +>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 +further I/O. This is supported using hooks: + </P +><TABLE +BORDER="5" +BGCOLOR="#E0E0F0" +WIDTH="70%" +><TR +><TD +><PRE +CLASS="PROGRAMLISTING" +>namespace eval my_device { + … + proc handle_ecos_exit { arg_list } { + … + } + synth::hook_add "ecos_exit" my_device::handle_ecos_exit +}</PRE +></TD +></TR +></TABLE +><P +>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 +user initialization scripts that want to monitor some types of I/O. +The available Tcl procedures for manipulating hooks are: + </P +><TABLE +BORDER="5" +BGCOLOR="#E0E0F0" +WIDTH="70%" +><TR +><TD +><PRE +CLASS="PROGRAMLISTING" +>synth::hook_define <name> +synth::hook_defined <name> +synth::hook_add <name> <function> +synth::hook_call <name> <args></PRE +></TD +></TR +></TABLE +><P +><B +CLASS="COMMAND" +>synth::hook_define</B +> creates a new hook with the +specified name. This hook must not already exist. +<B +CLASS="COMMAND" +>synth::hook_defined</B +> can be used to check for the +existence of a hook. <B +CLASS="COMMAND" +>synth::hook_add</B +> allows other +scripts to register a callback function for this hook, and +<B +CLASS="COMMAND" +>synth::hook_call</B +> allows the owner script to invoke +all such callback functions. A hook must already be defined before a +callback can be attached. Therefore typically device scripts will only +use standard hooks and their own hooks, not hooks created by some +other device, because the order of device initialization is not +sufficiently defined. User scripts run from +<TT +CLASS="FILENAME" +>mainrc.tcl</TT +> can use any hooks that have been +defined. + </P +><P +><B +CLASS="COMMAND" +>synth::hook_call</B +> takes an arbitrary list of +arguments, for example: + </P +><TABLE +BORDER="5" +BGCOLOR="#E0E0F0" +WIDTH="70%" +><TR +><TD +><PRE +CLASS="PROGRAMLISTING" +> synth::hook_call "ethernet_rx" "eth0" $packet</PRE +></TD +></TR +></TABLE +><P +>The callback function will always be invoked with a single argument, +a list of the arguments that were passed to +<B +CLASS="COMMAND" +>synth::hook_call</B +>: + </P +><TABLE +BORDER="5" +BGCOLOR="#E0E0F0" +WIDTH="70%" +><TR +><TD +><PRE +CLASS="PROGRAMLISTING" +> proc rx_callback { arg_list } { + set device [lindex $arg_list 0] + set packet [lindex $arg_list 1] + }</PRE +></TD +></TR +></TABLE +><P +>Although it might seem more appropriate to use Tcl's +<B +CLASS="COMMAND" +>eval</B +> procedure and have the callback functions +invoked with the right number of arguments rather than a single list, +that would cause serious problems if any of the data contained special +characters such as <TT +CLASS="LITERAL" +>[</TT +> or <TT +CLASS="LITERAL" +>$</TT +>. The +current implementation of hooks avoids such problems, at the cost of +minor inconvenience when writing callbacks. + </P +><P +>A number of hooks are defined as standard. Some devices will add +additional hooks, and the device-specific documentation should be +consulted for those. User scripts can add their own hooks if desired. + </P +><P +></P +><DIV +CLASS="VARIABLELIST" +><DL +><DT +><TT +CLASS="LITERAL" +>exit</TT +></DT +><DD +><P +>This hook is called just before the I/O auxiliary exits. Hence it +provides much the same functionality as <TT +CLASS="FUNCTION" +>atexit</TT +> in +C programs. The argument list passed to the callback function will be +empty. + </P +></DD +><DT +><TT +CLASS="LITERAL" +>ecos_exit</TT +></DT +><DD +><P +>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 +running then there is no point in raising interrupts or storing +incoming packets. The callback argument list will be empty. + </P +></DD +><DT +><TT +CLASS="LITERAL" +>ecos_initialized</TT +></DT +><DD +><P +>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 +instantiated. A script could now check how many instances there are of +a given type of device, for example ethernet devices, and create a +little monitor window showing traffic on all the devices. The +<TT +CLASS="LITERAL" +>ecos_initialized</TT +> callbacks will be run just before +the user's <TT +CLASS="FILENAME" +>mainrc.tcl</TT +> script. The callback +argument list will be empty. + </P +></DD +><DT +><TT +CLASS="LITERAL" +>help</TT +></DT +><DD +><P +>This hook is also invoked once static constructors have been run, but +only if the user specified <TT +CLASS="OPTION" +>-h</TT +> or +<TT +CLASS="OPTION" +>--help</TT +>. Any scripts that add their own command line +arguments should add a callback to this hook which outputs details of +the additional arguments. The callback argument list will be empty. + </P +></DD +><DT +><TT +CLASS="LITERAL" +>interrupt</TT +></DT +><DD +><P +>Whenever a device calls <B +CLASS="COMMAND" +>synth::interrupt_raise</B +> the +<TT +CLASS="LITERAL" +>interrupt</TT +> hook will be called with a single +argument, the interrupt vector. The main use for this is to allow +user scripts to monitor interrupt traffic. + </P +></DD +></DL +></DIV +></DIV +><DIV +CLASS="REFSECT1" +><A +NAME="SYNTH-NEW-HOST-OUTPUT" +></A +><H2 +>Output and Filters</H2 +><P +>Scripts can use conventional facilities for sending text output to the +user, for example calling <B +CLASS="COMMAND" +>puts</B +> or directly +manipulating the central text widget +<TT +CLASS="VARNAME" +>.main.centre.text</TT +>. However in nearly all cases it +is better to use output facilities provided by the I/O auxiliary +itself: + </P +><TABLE +BORDER="5" +BGCOLOR="#E0E0F0" +WIDTH="70%" +><TR +><TD +><PRE +CLASS="PROGRAMLISTING" +>synth::report <msg> +synth::report_warning <msg> +synth::report_error <msg> +synth::internal_error <msg> +synth::output <msg> <filter></PRE +></TD +></TR +></TABLE +><P +><B +CLASS="COMMAND" +>synth::report</B +> is intended for messages related to +the operation of the I/O auxiliary itself, especially additional +output resulting from <TT +CLASS="OPTION" +>-v</TT +> or +<TT +CLASS="OPTION" +>--verbose</TT +>. If running in text mode the output will go +to standard output. If running in graphical mode the output will go to +the central text window. In both modes, use of <TT +CLASS="OPTION" +>-l</TT +> or +<TT +CLASS="OPTION" +>--logfile</TT +> will modify the behaviour. + </P +><P +><B +CLASS="COMMAND" +>synth::report_warning</B +>, +<B +CLASS="COMMAND" +>synth::report_error</B +> and +<B +CLASS="COMMAND" +>synth::internal_error</B +> have the obvious meaning, +including prepending strings such as <TT +CLASS="LITERAL" +>Warning:</TT +> and +<TT +CLASS="LITERAL" +>Error:</TT +>. When the eCos application informs the I/O +auxiliary that all static constructors have run, if at that point +there have been any calls to <B +CLASS="COMMAND" +>synth::error</B +> then the +I/O auxiliary will exit. This can be suppressed with command line +arguments <TT +CLASS="OPTION" +>-k</TT +> or <TT +CLASS="OPTION" +>--keep-going</TT +>. +<B +CLASS="COMMAND" +>synth::internal_error</B +> will output some information +about the current state of the I/O auxiliary and then exit +immediately. Of course it should never be necessary to call this +function. + </P +><P +><B +CLASS="COMMAND" +>synth::output</B +> is the main routine for outputting +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 +be used to control the appearance of this output. A typical use would +be: + </P +><TABLE +BORDER="5" +BGCOLOR="#E0E0F0" +WIDTH="70%" +><TR +><TD +><PRE +CLASS="PROGRAMLISTING" +> synth::output $line "console"</PRE +></TD +></TR +></TABLE +><P +>This outputs a single line of text using the +<TT +CLASS="LITERAL" +>console</TT +> filter. If running in graphical mode the +default appearance of this text can be modified with the +<TT +CLASS="OPTION" +>appearance</TT +> option in the +<B +CLASS="COMMAND" +>synth_device console</B +> entry of the target +definition file. The <SPAN +CLASS="GUIMENUITEM" +>System filters</SPAN +> menu +option can be used to change the appearance at run-time. + </P +><P +>Filters should be created before they are used. The procedures +available for this are: + </P +><TABLE +BORDER="5" +BGCOLOR="#E0E0F0" +WIDTH="70%" +><TR +><TD +><PRE +CLASS="PROGRAMLISTING" +>synth::filter_exists <name> +synth::filter_get_list +synth::filter_add <name> [options] +synth::filter_parse_options <options> <parsed_options> <message> +synth::filter_add_parsed <name> <parsed_options></PRE +></TD +></TR +></TABLE +><P +><B +CLASS="COMMAND" +>synth::filter_exists</B +> can be used to check whether +or not a particular filter already exists: creating two filters with +the same name is not allowed. +<B +CLASS="COMMAND" +>synth::filter_get_list</B +> returns a list of the +current known filters. <B +CLASS="COMMAND" +>synth::filter_add</B +> can be +used to create a new filter. The first argument names the new filter, +and the remaining arguments control the initial appearance. A typical +use might be: + </P +><TABLE +BORDER="5" +BGCOLOR="#E0E0F0" +WIDTH="70%" +><TR +><TD +><PRE +CLASS="PROGRAMLISTING" +> synth::filter_add "my_device_tx" -foreground yellow -hide 1</PRE +></TD +></TR +></TABLE +><P +>It is assumed that the supplied arguments are valid, which typically +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 +I/O auxiliary provides a parsing utility. Typical usage would be: + </P +><TABLE +BORDER="5" +BGCOLOR="#E0E0F0" +WIDTH="70%" +><TR +><TD +><PRE +CLASS="PROGRAMLISTING" +> array set parsed_options [list] + set message "" + if { ![synth::filter_parse_options $console_appearance parsed_options message] } { + synth::report_error \ + "Invalid entry in target definition file $synth::target_definition\ + \n synth_device \"console\", entry \"appearance\"\n$message" + } else { + synth::filter_add_parsed "console" parsed_options + }</PRE +></TD +></TR +></TABLE +><P +>On success <TT +CLASS="VARNAME" +>parsed_options</TT +> will be updated with an +internal representation of the desired appearance, which can then be +used in a call to <B +CLASS="COMMAND" +>synth::filter_add_parsed</B +>. On +failure <TT +CLASS="VARNAME" +>message</TT +> will be updated with details of the +parsing error that occurred. + </P +></DIV +><DIV +CLASS="REFSECT1" +><A +NAME="SYNTH-NEW-HOST-GUI" +></A +><H2 +>The Graphical Interface</H2 +><P +>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 +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, +or even creating entire new toplevel windows. These may be simple +monitor windows, displaying additional information about what is going +on in the system in a graphical format. Alternatively they may emulate +actual I/O operations, for example button widgets could be used to +emulate real physical buttons. + </P +><P +>The I/O auxiliary does not provide many procedures related to the +graphical interface. Instead it is expected that scripts will just +update the widget hierarchy directly. + </P +><DIV +CLASS="INFORMALFIGURE" +><A +NAME="AEN1018"><P +></P +><DIV +CLASS="MEDIAOBJECT" +><P +><IMG +SRC="layout.gif" +ALIGN="CENTER"></P +></DIV +><P +></P +></DIV +><P +>So adding a new item to the <SPAN +CLASS="GUIMENU" +>Help</SPAN +> menu involves a +<B +CLASS="COMMAND" +>.menubar.help add</B +> operation with suitable +arguments. Adding a new button to the toolbar involves creating a +child window in <TT +CLASS="VARNAME" +>.toolbar</TT +> and packing it +appropriately. Scripts can create their own subwindows and then pack +it into one of <TT +CLASS="VARNAME" +>.main.nw</TT +>, +<TT +CLASS="VARNAME" +>.main.n</TT +>, <TT +CLASS="VARNAME" +>.main.ne</TT +>, +<TT +CLASS="VARNAME" +>.main.w</TT +>, <TT +CLASS="VARNAME" +>.main.e</TT +>, +<TT +CLASS="VARNAME" +>.main.sw</TT +>, <TT +CLASS="VARNAME" +>.main.s</TT +> or +<TT +CLASS="VARNAME" +>.main.se</TT +>. Normally the user should be allowed to +<A +HREF="synth-gui.html#SYNTH-GUI-LAYOUT" +>control</A +> this via the target +definition file. The central window <TT +CLASS="VARNAME" +>.main.centre</TT +> +should normally be left alone by other scripts since it gets used for +text output. + </P +><P +>The following graphics-related utilities may be found useful: + </P +><TABLE +BORDER="5" +BGCOLOR="#E0E0F0" +WIDTH="70%" +><TR +><TD +><PRE +CLASS="PROGRAMLISTING" +>synth::load_image <image name> <filename> +synth::register_ballon_help <widget> <message> +synth::handle_help <URL></PRE +></TD +></TR +></TABLE +><P +><B +CLASS="COMMAND" +>synth::load_image</B +> can be used to add a new image to +the current interpreter. If the specified file has a +<TT +CLASS="FILENAME" +>.xbm</TT +> extension then the image will be a +monochrome bitmap, otherwise it will be a colour image of some sort. +A boolean will be returned to indicate success or failure, and +suitable diagnostics will be generated if necessary. + </P +><P +><B +CLASS="COMMAND" +>synth::register_balloon_help</B +> provides balloon help +for a specific widget, usually a button on the toolbar. + </P +><P +><B +CLASS="COMMAND" +>synth::handle_help</B +> is a utility routine that can be +installed as the command for displaying online help, for example: + </P +><TABLE +BORDER="5" +BGCOLOR="#E0E0F0" +WIDTH="70%" +><TR +><TD +><PRE +CLASS="PROGRAMLISTING" +> .menubar.help add command -label "my device" -command \ + [list synth::handle_help "file://$path"]</PRE +></TD +></TR +></TABLE +></DIV +><DIV +CLASS="NAVFOOTER" +><HR +ALIGN="LEFT" +WIDTH="100%"><TABLE +SUMMARY="Footer navigation table" +WIDTH="100%" +BORDER="0" +CELLPADDING="0" +CELLSPACING="0" +><TR +><TD +WIDTH="33%" +ALIGN="left" +VALIGN="top" +><A +HREF="synth-new-target.html" +ACCESSKEY="P" +>Prev</A +></TD +><TD +WIDTH="34%" +ALIGN="center" +VALIGN="top" +><A +HREF="hal-synth-arch.html" +ACCESSKEY="H" +>Home</A +></TD +><TD +WIDTH="33%" +ALIGN="right" +VALIGN="top" +><A +HREF="synth-porting.html" +ACCESSKEY="N" +>Next</A +></TD +></TR +><TR +><TD +WIDTH="33%" +ALIGN="left" +VALIGN="top" +>Writing New Devices - target</TD +><TD +WIDTH="34%" +ALIGN="center" +VALIGN="top" +> </TD +><TD +WIDTH="33%" +ALIGN="right" +VALIGN="top" +>Porting</TD +></TR +></TABLE +></DIV +></BODY +></HTML +> \ No newline at end of file
new file mode 100644 --- /dev/null +++ b/packages/hal/synth/arch/current/doc/synth-new-target.html @@ -0,0 +1,823 @@ +<!-- Copyright (C) 2002 Red Hat, Inc. --> +<!-- This material may be distributed only subject to the terms --> +<!-- and conditions set forth in the Open Publication License, v1.0 --> +<!-- or later (the latest version is presently available at --> +<!-- http://www.opencontent.org/openpub/). --> +<!-- Distribution of the work or derivative of the work in any --> +<!-- standard (paper) book form is prohibited unless prior --> +<!-- permission is obtained from the copyright holder. --> +<HTML +><HEAD +><TITLE +>Writing New Devices - target</TITLE +><meta name="MSSmartTagsPreventParsing" content="TRUE"> +<META +NAME="GENERATOR" +CONTENT="Modular DocBook HTML Stylesheet Version 1.76b+ +"><LINK +REL="HOME" +TITLE="eCos Synthetic Target" +HREF="hal-synth-arch.html"><LINK +REL="PREVIOUS" +TITLE="System Calls" +HREF="synth-syscalls.html"><LINK +REL="NEXT" +TITLE="Writing New Devices - host" +HREF="synth-new-host.html"></HEAD +><BODY +CLASS="REFENTRY" +BGCOLOR="#FFFFFF" +TEXT="#000000" +LINK="#0000FF" +VLINK="#840084" +ALINK="#0000FF" +><DIV +CLASS="NAVHEADER" +><TABLE +SUMMARY="Header navigation table" +WIDTH="100%" +BORDER="0" +CELLPADDING="0" +CELLSPACING="0" +><TR +><TH +COLSPAN="3" +ALIGN="center" +>eCos Synthetic Target</TH +></TR +><TR +><TD +WIDTH="10%" +ALIGN="left" +VALIGN="bottom" +><A +HREF="synth-syscalls.html" +ACCESSKEY="P" +>Prev</A +></TD +><TD +WIDTH="80%" +ALIGN="center" +VALIGN="bottom" +></TD +><TD +WIDTH="10%" +ALIGN="right" +VALIGN="bottom" +><A +HREF="synth-new-host.html" +ACCESSKEY="N" +>Next</A +></TD +></TR +></TABLE +><HR +ALIGN="LEFT" +WIDTH="100%"></DIV +><H1 +><A +NAME="SYNTH-NEW-TARGET">Writing New Devices - target</H1 +><DIV +CLASS="REFNAMEDIV" +><A +NAME="AEN524" +></A +><H2 +>Name</H2 +>Writing New Devices -- extending the synthetic target, target-side</DIV +><DIV +CLASS="REFSYNOPSISDIV" +><A +NAME="AEN527"><H2 +>Synopsis</H2 +><DIV +CLASS="FUNCSYNOPSIS" +><A +NAME="AEN528"><P +></P +><TABLE +BORDER="5" +BGCOLOR="#E0E0F0" +WIDTH="70%" +><TR +><TD +><PRE +CLASS="FUNCSYNOPSISINFO" +>#include <cyg/hal/hal_io.h + </PRE +></TD +></TR +></TABLE +><P +><CODE +><CODE +CLASS="FUNCDEF" +>int synth_auxiliary_instantiate</CODE +>(const char* package, const char* version, const char* device, const char* instance, const char* data);</CODE +></P +><P +><CODE +><CODE +CLASS="FUNCDEF" +>void synth_auxiliary_xchgmsg</CODE +>(int device_id, int request, int arg1, int arg2, const unsigned char* txdata, int txlen, int* reply, unsigned char* rxdata, int* rxlen, int max_rxlen);</CODE +></P +><P +></P +></DIV +></DIV +><DIV +CLASS="REFSECT1" +><A +NAME="SYNTH-NEW-TARGET-DESCRIPTION" +></A +><H2 +>Description</H2 +><P +>In some ways writing a device driver for the synthetic target is very +similar to writing one for a real target. Obviously it has to provide +the standard interface for that class of device, so for example an +ethernet device has to provide <TT +CLASS="FUNCTION" +>can_send</TT +>, +<TT +CLASS="FUNCTION" +>send</TT +>, <TT +CLASS="FUNCTION" +>recv</TT +> and similar +functions. Many devices will involve interrupts, so the driver +contains ISR and DSR functions and will call +<TT +CLASS="FUNCTION" +>cyg_drv_interrupt_create</TT +>, +<TT +CLASS="FUNCTION" +>cyg_drv_interrupt_acknowledge</TT +>, and related +functions. + </P +><P +>In other ways writing a device driver for the synthetic target is very +different. Usually the driver will not have any direct access to the +underlying hardware. In fact for some devices the I/O may not involve +real hardware, instead everything is emulated by widgets on the +graphical display. Therefore the driver cannot just peek and poke +device registers, instead it must interact with host-side code by +exchanging message. The synthetic target HAL provides a function +<TT +CLASS="FUNCTION" +>synth_auxiliary_xchgmsg</TT +> for this purpose. + </P +><P +>Initialization of a synthetic target device driver is also very +different. On real targets the device hardware already exists when the +driver's initialization routine runs. On the synthetic target it is +first necessary to instantiate the device inside the I/O auxiliary, by +a call to <TT +CLASS="FUNCTION" +>synth_auxiliary_instantiate</TT +>. That +function performs a special message exchange with the I/O auxiliary, +causing it to load a Tcl script for the desired type of device and run +an instantiation procedure within that script. + </P +><P +>Use of the I/O auxiliary is optional: if the user does not specify +<TT +CLASS="OPTION" +>--io</TT +> on the command line then the auxiliary will not +be started and hence most I/O operations will not be possible. Device +drivers should allow for this possibility, for example by just +discarding any data that gets written. The HAL exports a flag +<TT +CLASS="VARNAME" +>synth_auxiliary_running</TT +> which should be checked. + </P +></DIV +><DIV +CLASS="REFSECT1" +><A +NAME="SYNTH-NEW-TARGET-INSTANTIATE" +></A +><H2 +>Instantiating a Device</H2 +><P +>Device instantiation should happen during the C++ prioritized static +constructor phase of system initialization, before control switches to +<TT +CLASS="FUNCTION" +>cyg_user_start</TT +> and general application code. This +ensures that there is a clearly defined point at which the I/O +auxiliary knows that all required devices have been loaded. It can +then perform various consistency checks and clean-ups, run the user's +<TT +CLASS="FILENAME" +>mainrc.tcl</TT +> script, and make the main window +visible. + </P +><P +>For standard devices generic eCos I/O code will call the device +initialization routines at the right time, iterating through the +<TT +CLASS="VARNAME" +>DEVTAB</TT +> table in a static constructor. The same +holds for network devices and file systems. For more custom devices +code like the following can be used: + </P +><TABLE +BORDER="5" +BGCOLOR="#E0E0F0" +WIDTH="70%" +><TR +><TD +><PRE +CLASS="PROGRAMLISTING" +>#include <cyg/infra/cyg_type.h> +class mydev_init { + public: + mydev_init() { + … + } +}; +static mydev_init mydev_init_object CYGBLD_ATTRIB_INIT_PRI(CYG_INIT_IO);</PRE +></TD +></TR +></TABLE +><P +>Some care has to be taken because the object +<TT +CLASS="VARNAME" +>mydev_init_object</TT +> will typically not be referenced +by other code, and hence may get eliminated at link-time. If the code +is part of an eCos package then problems can be avoided by putting the +relevant file in <TT +CLASS="FILENAME" +>libextras.a</TT +>: + </P +><TABLE +BORDER="5" +BGCOLOR="#E0E0F0" +WIDTH="70%" +><TR +><TD +><PRE +CLASS="PROGRAMLISTING" +>cdl_package CYGPKG_DEVS_MINE { + … + compile -library=libextras.a init.cxx +}</PRE +></TD +></TR +></TABLE +><P +>For devices inside application code the same can be achieved by +linking the relevant module as a <TT +CLASS="FILENAME" +>.o</TT +> file rather +than putting it in a <TT +CLASS="FILENAME" +>.a</TT +> library. + </P +><P +>In the device initialization routine the main operation is a call to +<TT +CLASS="FUNCTION" +>synth_auxiliary_instantiate</TT +>. This takes five +arguments, all of which should be strings: + </P +><P +></P +><DIV +CLASS="VARIABLELIST" +><DL +><DT +><TT +CLASS="VARNAME" +>package</TT +></DT +><DD +><P +>For device drivers which are eCos packages this should be a directory +path relative to the eCos repository, for example +<TT +CLASS="LITERAL" +>devs/eth/synth/ecosynth</TT +>. This will allow the I/O +auxiliary to find the various host-side support files for this package +within the install tree. If the device is application-specific and not +part of an eCos package then a NULL pointer can be used, causing the +I/O auxiliary to search for the support files in the current directory +and then in <TT +CLASS="FILENAME" +>~/.ecos/synth</TT +> +instead. + </P +></DD +><DT +><TT +CLASS="VARNAME" +>version</TT +></DT +><DD +><P +>For eCos packages this argument should be the version of the package +that is being used, for example <TT +CLASS="LITERAL" +>current</TT +>. A simple +way to get this version is to use the +<TT +CLASS="FUNCTION" +>SYNTH_MAKESTRING</TT +> macro on the package name. +If the device is application-specific then a NULL pointer should be +used. + </P +></DD +><DT +><TT +CLASS="VARNAME" +>device</TT +></DT +><DD +><P +>This argument specifies the type of device being instantiated, for +example <TT +CLASS="LITERAL" +>ethernet</TT +>. More specifically the I/O +auxiliary will append a <TT +CLASS="FILENAME" +>.tcl</TT +> suffix, giving +the name of a Tcl script that will handle all I/O requests for the +device. If the application requires several instances of a type +of device then the script will only be loaded once, but the script +will contain an instantiation procedure that will be called for each +device instance. + </P +></DD +><DT +><TT +CLASS="VARNAME" +>instance</TT +></DT +><DD +><P +>If it is possible to have multiple instances of a device then this +argument identifies the particular instance, for example +<TT +CLASS="LITERAL" +>eth0</TT +> or <TT +CLASS="LITERAL" +>eth1</TT +>. Otherwise a NULL +pointer can be used. + </P +></DD +><DT +><TT +CLASS="VARNAME" +>data</TT +></DT +><DD +><P +>This argument can be used to pass additional initialization data from +eCos to the host-side support. This is useful for devices where eCos +configury must control certain aspects of the device, rather than +host-side configury such as the target definition file, because eCos +has compile-time dependencies on some or all of the relevant options. +An example might be an emulated frame buffer where eCos has been +statically configured for a particular screen size, orientation and +depth. There is no fixed format for this string, it will be +interpreted only by the device-specific host-side Tcl script. However +the string length should be limited to a couple of hundred bytes to +avoid possible buffer overflow problems. + </P +></DD +></DL +></DIV +><P +>Typical usage would look like: + </P +><TABLE +BORDER="5" +BGCOLOR="#E0E0F0" +WIDTH="70%" +><TR +><TD +><PRE +CLASS="PROGRAMLISTING" +> if (!synth_auxiliary_running) { + return; + } + id = synth_auxiliary_instantiate("devs/eth/synth/ecosynth", + SYNTH_MAKESTRING(CYGPKG_DEVS_ETH_ECOSYNTH), + "ethernet", + "eth0", + (const char*) 0);</PRE +></TD +></TR +></TABLE +><P +>The return value will be a device identifier which can be used for +subsequent calls to <TT +CLASS="FUNCTION" +>synth_auxiliary_xchgmsg</TT +>. If +the device could not be instantiated then <TT +CLASS="LITERAL" +>-1</TT +> will +be returned. It is the responsibility of the host-side software to +issue suitable diagnostics explaining what went wrong, so normally the +target-side code should fail silently. + </P +><P +>Once the desired device has been instantiated, often it will be +necessary to do some additional initialization by a message exchange. +For example an ethernet device might need information from the +host-side about the MAC address, the <A +HREF="synth-new-target.html#SYNTH-NEW-TARGET-INTERRUPTS" +>interrupt vector</A +>, and +whether or not multicasting is supported. + </P +></DIV +><DIV +CLASS="REFSECT1" +><A +NAME="SYNTH-NEW-TARGET-XCHGMSG" +></A +><H2 +>Communicating with a Device</H2 +><P +>Once a device has been instantiated it is possible to perform I/O by +sending messages to the appropriate Tcl script running inside the +auxiliary, and optionally getting back replies. I/O operations are +always initiated by the eCos target-side, it is not possible for the +host-side software to initiate data transfers. However the host-side +can raise interrupts, and the interrupt handler inside the target can +then exchange one or more messages with the host. + </P +><P +>There is a single function to perform I/O operations, +<TT +CLASS="FUNCTION" +>synth_auxiliary_xchgmsg</TT +>. This takes the following +arguments: + </P +><P +></P +><DIV +CLASS="VARIABLELIST" +><DL +><DT +><TT +CLASS="VARNAME" +>device_id</TT +></DT +><DD +><P +>This should be one of the identifiers returned by a previous +call to <TT +CLASS="FUNCTION" +>synth_auxiliary_instantiate</TT +>, specifying the +particular device which should perform some I/O. + </P +></DD +><DT +><TT +CLASS="VARNAME" +>request</TT +></DT +><DD +><P +>Request are just signed 32-bit integers that identify the particular +I/O operation being requested. There is no fixed set of codes, instead +each type of device can define its own. + </P +></DD +><DT +><TT +CLASS="VARNAME" +>arg1</TT +>, <TT +CLASS="VARNAME" +>arg2</TT +></DT +><DD +><P +>For some requests it is convenient to pass one or two additional +parameters alongside the request code. For example an ethernet device +could define a multicast-all request, with <TT +CLASS="VARNAME" +>arg1</TT +> +controlling whether this mode should be enabled or disabled. Both +<TT +CLASS="VARNAME" +>arg1</TT +> and <TT +CLASS="VARNAME" +>arg2</TT +> should be signed +32-bit integers, and their values are interpreted only by the +device-specific Tcl script. + </P +></DD +><DT +><TT +CLASS="VARNAME" +>txdata</TT +>, <TT +CLASS="VARNAME" +>txlen</TT +></DT +><DD +><P +>Some I/O operations may involve sending additional data, for example +an ethernet packet. Alternatively a control operation may require many +more parameters than can easily be encoded in <TT +CLASS="VARNAME" +>arg1</TT +> +and <TT +CLASS="VARNAME" +>arg2</TT +>, so those parameters have to be placed in +a suitable buffer and extracted at the other end. +<TT +CLASS="VARNAME" +>txdata</TT +> is an arbitrary buffer of +<TT +CLASS="VARNAME" +>txlen</TT +> bytes that should be sent to the host-side. +There is no specific upper bound on the number of bytes that can be +sent, but usually it is a good idea to allocate the transmit buffer +statically and keep transfers down to at most several kilobytes. + </P +></DD +><DT +><TT +CLASS="VARNAME" +>reply</TT +></DT +><DD +><P +>If the host-side is expected to send a reply message then +<TT +CLASS="VARNAME" +>reply</TT +> should be a pointer to an integer variable +and will be updated with a reply code, a simple 32-bit integer. The +synthetic target HAL code assumes that the host-side and target-side +agree on the protocol being used: if the host-side will not send a +reply to this message then the <TT +CLASS="VARNAME" +>reply</TT +> argument +should be a NULL pointer; otherwise the host-side must always send +a reply code and the <TT +CLASS="VARNAME" +>reply</TT +> argument must be valid. + </P +></DD +><DT +><TT +CLASS="VARNAME" +>rxdata</TT +>, <TT +CLASS="VARNAME" +>rxlen</TT +></DT +><DD +><P +>Some operations may involve additional data coming from the host-side, +for example an incoming ethernet packet. <TT +CLASS="VARNAME" +>rxdata</TT +> +should be a suitably-sized buffer, and <TT +CLASS="VARNAME" +>rxlen</TT +> a +pointer to an integer variable that will end up containing the number +of bytes that were actually received. These arguments will only be +used if the host-side is expected to send a reply and hence the +<TT +CLASS="VARNAME" +>reply</TT +> argument was not NULL. + </P +></DD +><DT +><TT +CLASS="VARNAME" +>max_rxlen</TT +></DT +><DD +><P +>If a reply to this message is expected and that reply may involve +additional data, <TT +CLASS="VARNAME" +>max_rxlen</TT +> limits the size of that +reply. In other words, it corresponds to the size of the +<TT +CLASS="VARNAME" +>rxdata</TT +> buffer. + </P +></DD +></DL +></DIV +><P +>Most I/O operations involve only some of the arguments. For example +transmitting an ethernet packet would use the +<TT +CLASS="VARNAME" +>request</TT +>, <TT +CLASS="VARNAME" +>txdata</TT +> and +<TT +CLASS="VARNAME" +>txlen</TT +> fields (in addition to +<TT +CLASS="VARNAME" +>device_id</TT +> which is always required), but would not +involve <TT +CLASS="VARNAME" +>arg1</TT +> or <TT +CLASS="VARNAME" +>arg2</TT +> and no +reply would be expected. Receiving an ethernet packet would involve +<TT +CLASS="VARNAME" +>request</TT +>, <TT +CLASS="VARNAME" +>rxdata</TT +>, +<TT +CLASS="VARNAME" +>rxlen</TT +> and <TT +CLASS="VARNAME" +>max_rxlen</TT +>; in addition +<TT +CLASS="VARNAME" +>reply</TT +> is needed to get any reply from the host-side +at all, and could be used to indicate whether or not any more packets +are buffered up. A control operation such as enabling multicast mode +would involve <TT +CLASS="VARNAME" +>request</TT +> and <TT +CLASS="VARNAME" +>arg1</TT +>, +but none of the remaining arguments. + </P +></DIV +><DIV +CLASS="REFSECT1" +><A +NAME="SYNTH-NEW-TARGET-INTERRUPTS" +></A +><H2 +>Interrupt Handling</H2 +><P +>Interrupt handling in the synthetic target is much the same as on a +real target. An interrupt object is created using +<TT +CLASS="FUNCTION" +>cyg_drv_interrupt_create</TT +>, attached, and unmasked. +The emulated device - in other words the Tcl script running inside the +I/O auxiliary - can raise an interrupt. Subject to interrupts being +disabled and the appropriate vector being masked, the system will +invoke the specified ISR function. The synthetic target HAL +implementation does have some limitations: there is no support for +nested interrupts, interrupt priorities, or a separate interrupt +stack. Supporting those might be appropriate when targetting a +simulator that attempts to model real hardware accurately, but not for +the simple emulation provided by the synthetic target. + </P +><P +>Of course the actual implementation of the ISR and DSR functions will +be rather different for a synthetic target device driver. For real +hardware the device driver will interact with the device by reading +and writing device registers, managing DMA engines, and the like. A +synthetic target driver will instead call +<TT +CLASS="FUNCTION" +>synth_auxiliary_xchgmsg</TT +> to perform the I/O +operations. + </P +><P +>There is one other significant difference between interrupt handling +on the synthetic target and on real hardware. Usually the eCos code +will know which interrupt vectors are used for which devices. That +information is fixed when the target hardware is designed. With the +synthetic target interrupt vectors are assigned to devices on the host +side, either via the target definition file or dynamically when the +device is instantiated. Therefore the initialization code for a +target-side device driver will need to request interrupt vector +information from the host-side, via a message exchange. Such interrupt +vectors will be in the range 1 to 31 inclusive, with interrupt 0 being +reserved for the real-time clock. + </P +></DIV +><DIV +CLASS="NAVFOOTER" +><HR +ALIGN="LEFT" +WIDTH="100%"><TABLE +SUMMARY="Footer navigation table" +WIDTH="100%" +BORDER="0" +CELLPADDING="0" +CELLSPACING="0" +><TR +><TD +WIDTH="33%" +ALIGN="left" +VALIGN="top" +><A +HREF="synth-syscalls.html" +ACCESSKEY="P" +>Prev</A +></TD +><TD +WIDTH="34%" +ALIGN="center" +VALIGN="top" +><A +HREF="hal-synth-arch.html" +ACCESSKEY="H" +>Home</A +></TD +><TD +WIDTH="33%" +ALIGN="right" +VALIGN="top" +><A +HREF="synth-new-host.html" +ACCESSKEY="N" +>Next</A +></TD +></TR +><TR +><TD +WIDTH="33%" +ALIGN="left" +VALIGN="top" +>System Calls</TD +><TD +WIDTH="34%" +ALIGN="center" +VALIGN="top" +> </TD +><TD +WIDTH="33%" +ALIGN="right" +VALIGN="top" +>Writing New Devices - host</TD +></TR +></TABLE +></DIV +></BODY +></HTML +> \ No newline at end of file
--- a/packages/hal/synth/arch/current/doc/synth-porting.html +++ b/packages/hal/synth/arch/current/doc/synth-porting.html @@ -3,9 +3,6 @@ <!-- and conditions set forth in the Open Publication License, v1.0 --> <!-- or later (the latest version is presently available at --> <!-- http://www.opencontent.org/openpub/). --> -<!-- Distribution of substantively modified versions of this --> -<!-- document is prohibited without the explicit permission of the --> -<!-- copyright holder. --> <!-- Distribution of the work or derivative of the work in any --> <!-- standard (paper) book form is prohibited unless prior --> <!-- permission is obtained from the copyright holder. --> @@ -16,14 +13,14 @@ ><meta name="MSSmartTagsPreventParsing" content="TRUE"> <META NAME="GENERATOR" -CONTENT="Modular DocBook HTML Stylesheet Version 1.64 +CONTENT="Modular DocBook HTML Stylesheet Version 1.76b+ "><LINK REL="HOME" TITLE="eCos Synthetic Target" HREF="hal-synth-arch.html"><LINK REL="PREVIOUS" -TITLE="System Calls" -HREF="synth-syscalls.html"></HEAD +TITLE="Writing New Devices - host" +HREF="synth-new-host.html"></HEAD ><BODY CLASS="REFENTRY" BGCOLOR="#FFFFFF" @@ -34,6 +31,7 @@ ALINK="#0000FF" ><DIV CLASS="NAVHEADER" ><TABLE +SUMMARY="Header navigation table" WIDTH="100%" BORDER="0" CELLPADDING="0" @@ -50,7 +48,8 @@ WIDTH="10%" ALIGN="left" VALIGN="bottom" ><A -HREF="synth-syscalls.html" +HREF="synth-new-host.html" +ACCESSKEY="P" >Prev</A ></TD ><TD @@ -70,17 +69,15 @@ ALIGN="LEFT" WIDTH="100%"></DIV ><H1 ><A -NAME="SYNTH-PORTING" ->Porting</A -></H1 +NAME="SYNTH-PORTING">Porting</H1 ><DIV CLASS="REFNAMEDIV" ><A -NAME="AEN92" +NAME="AEN1049" ></A ><H2 >Name</H2 ->Porting -- The eCos synthetic target</DIV +>Porting -- Adding support for other hosts</DIV ><DIV CLASS="REFSECT1" ><A @@ -96,7 +93,7 @@ straightforward, for example a port to L an x86. Porting to Unix or Unix-like operating systems other than Linux may be possible, but would involve more effort. Porting to a completely different operating system such as Windows would be very -difficult. The text below completes the eCos Porting Guide. +difficult. The text below complements the eCos Porting Guide. </P ></DIV ><DIV @@ -128,12 +125,11 @@ to update the toplevel <TT CLASS="FILENAME" >ecos.db</TT > database with an -entry for the new HAL package, and a new target entry will be needed -as well. +entry for the new HAL package, and a new target entry will be needed. </P ><P ->Obviously a different processor will have different register sets -and calling conventions, so the code for saving and restoring thread +>Obviously a different processor will have different register sets and +calling conventions, so the code for saving and restoring thread contexts and for implementing <TT CLASS="FUNCTION" >setjmp</TT @@ -142,20 +138,21 @@ CLASS="FUNCTION" CLASS="FUNCTION" >longjmp</TT > will need to be updated. The exact way of -performing Linux system calls will also vary: on i386linux this -usually involves pushing some registers on the stack and then -executing an <TT +performing Linux system calls will vary: on x86 linux this usually +involves pushing some registers on the stack and then executing an +<TT CLASS="LITERAL" >int 0x080</TT -> trap instruction, but -on a different processor the arguments might be passed in registers -instead and certainly a different trap instruction will be used. The -startup code is also written in assembler, but needs to do little more -than jump to the main <TT +> trap instruction, but on a different +processor the arguments might be passed in registers instead and +certainly a different trap instruction will be used. The startup code +is written in assembler, but needs to do little more than extract the +process' argument and environment variables and then jump to the main +<TT CLASS="FUNCTION" >linux_entry</TT -> function -provided by the architectural synthetic target HAL package. +> function provided by the +architectural synthetic target HAL package. </P ><P >The header file <TT @@ -164,7 +161,7 @@ CLASS="FILENAME" > provided by the architectural HAL package provides various structure definitions, function prototypes, and macros related to system calls. These are -correct for i386linux, but there may be problems on other processors. +correct for x86 linux, but there may be problems on other processors. For example a structure field that is currently defined as a 32-bit number may in fact may be a 64-bit number instead. </P @@ -185,7 +182,10 @@ but usually eCos applications can and sh ><P >Other HAL functionality such as interrupt handling, diagnostics, and the system clock are provided by the architectural HAL package and -should work on different processors with few if any changes. +should work on different processors with few if any changes. There may +be some problems in the code that interacts with the I/O auxiliary +because of lurking assumptions about endianness or the sizes of +various data types. </P ><P >When porting to other processors, a number of sources of information @@ -205,11 +205,11 @@ NAME="SYNTH-PORTING-UNIX" >Other Unix Platforms</H2 ><P >Porting to a Unix or Unix-like operating system other than Linux would -be somewhat more involved. The first requirement involves toolchains: -the GNU compilers, gcc and g++, must definitely be used; use of other -GNU tools such as the linker may be needed as well, because eCos -depends on functionality such as prioritizing C++ static constructors, -and other linkers may not implement this or may implement it in a +be somewhat more involved. The first requirement is toolchains: the +GNU compilers, gcc and g++, must definitely be used; use of other GNU +tools such as the linker may be needed as well, because eCos depends +on functionality such as prioritizing C++ static constructors, and +other linkers may not implement this or may implement it in a different and incompatible way. A closely related requirement is the use of ELF format for binary executables: if the operating system still uses an older format such as COFF then there are likely to be @@ -241,6 +241,16 @@ simple system calls, and instead wrapper implemented at the variant HAL level. </P ><P +>The generic I/O auxiliary code should be fairly portable to other Unix +platforms. However some of the device drivers may contain code that is +specific to Linux, for example the <TT +CLASS="LITERAL" +>PF_PACKET</TT +> socket +address family and the ethertap virtual tunnelling interface. These +may prove quite difficult to port. + </P +><P >The remaining porting task is to implement one or more platform HAL packages, one per processor type that is supported. This should involve much the same work as a port to <A @@ -255,39 +265,6 @@ However there is still a good chance tha been ported already, so its source code may contain much useful information. </P -><DIV -CLASS="CAUTION" -><P -></P -><TABLE -CLASS="CAUTION" -BORDER="1" -WIDTH="100%" -><TR -><TD -ALIGN="CENTER" -><B ->Caution</B -></TD -></TR -><TR -><TD -ALIGN="LEFT" -><P ->Users should be aware that future enhancements to the synthetic target -code, especially in areas related to I/O, may be much more closely -tied to Linux. For example access to ethernet facilities might be -implemented using the <TT -CLASS="LITERAL" ->PF_PACKET</TT -> socket address -family, or the virtual tunnelling interface. Porting such code to -other Unix operating systems may prove rather more difficult. - </P -></TD -></TR -></TABLE -></DIV ></DIV ><DIV CLASS="REFSECT1" @@ -348,6 +325,7 @@ CLASS="NAVFOOTER" ><HR ALIGN="LEFT" WIDTH="100%"><TABLE +SUMMARY="Footer navigation table" WIDTH="100%" BORDER="0" CELLPADDING="0" @@ -358,7 +336,8 @@ WIDTH="33%" ALIGN="left" VALIGN="top" ><A -HREF="synth-syscalls.html" +HREF="synth-new-host.html" +ACCESSKEY="P" >Prev</A ></TD ><TD @@ -367,6 +346,7 @@ ALIGN="center" VALIGN="top" ><A HREF="hal-synth-arch.html" +ACCESSKEY="H" >Home</A ></TD ><TD @@ -380,7 +360,7 @@ VALIGN="top" WIDTH="33%" ALIGN="left" VALIGN="top" ->System Calls</TD +>Writing New Devices - host</TD ><TD WIDTH="34%" ALIGN="center"
new file mode 100644 --- /dev/null +++ b/packages/hal/synth/arch/current/doc/synth-running.html @@ -0,0 +1,964 @@ +<!-- Copyright (C) 2002 Red Hat, Inc. --> +<!-- This material may be distributed only subject to the terms --> +<!-- and conditions set forth in the Open Publication License, v1.0 --> +<!-- or later (the latest version is presently available at --> +<!-- http://www.opencontent.org/openpub/). --> +<!-- Distribution of the work or derivative of the work in any --> +<!-- standard (paper) book form is prohibited unless prior --> +<!-- permission is obtained from the copyright holder. --> +<HTML +><HEAD +><TITLE +>Running a Synthetic Target Application</TITLE +><meta name="MSSmartTagsPreventParsing" content="TRUE"> +<META +NAME="GENERATOR" +CONTENT="Modular DocBook HTML Stylesheet Version 1.76b+ +"><LINK +REL="HOME" +TITLE="eCos Synthetic Target" +HREF="hal-synth-arch.html"><LINK +REL="PREVIOUS" +TITLE="Installation" +HREF="synth-install.html"><LINK +REL="NEXT" +TITLE="The I/O Auxiliary's User Interface" +HREF="synth-gui.html"></HEAD +><BODY +CLASS="REFENTRY" +BGCOLOR="#FFFFFF" +TEXT="#000000" +LINK="#0000FF" +VLINK="#840084" +ALINK="#0000FF" +><DIV +CLASS="NAVHEADER" +><TABLE +SUMMARY="Header navigation table" +WIDTH="100%" +BORDER="0" +CELLPADDING="0" +CELLSPACING="0" +><TR +><TH +COLSPAN="3" +ALIGN="center" +>eCos Synthetic Target</TH +></TR +><TR +><TD +WIDTH="10%" +ALIGN="left" +VALIGN="bottom" +><A +HREF="synth-install.html" +ACCESSKEY="P" +>Prev</A +></TD +><TD +WIDTH="80%" +ALIGN="center" +VALIGN="bottom" +></TD +><TD +WIDTH="10%" +ALIGN="right" +VALIGN="bottom" +><A +HREF="synth-gui.html" +ACCESSKEY="N" +>Next</A +></TD +></TR +></TABLE +><HR +ALIGN="LEFT" +WIDTH="100%"></DIV +><H1 +><A +NAME="SYNTH-RUNNING">Running a Synthetic Target Application</H1 +><DIV +CLASS="REFNAMEDIV" +><A +NAME="AEN95" +></A +><H2 +>Name</H2 +>Execution -- Arguments and configuration files</DIV +><DIV +CLASS="REFSECT1" +><A +NAME="SYNTH-RUNNING-DESCRIPTION" +></A +><H2 +>Description</H2 +><P +>The procedure for configuring and building eCos and an application for +the synthetic target is the same as for any other eCos target. Once an +executable has been built it can be run like any Linux program, for +example from a shell prompt, + </P +><TABLE +BORDER="5" +BGCOLOR="#E0E0F0" +WIDTH="70%" +><TR +><TD +><PRE +CLASS="SCREEN" +>$ ecos_hello <options></PRE +></TD +></TR +></TABLE +><P +>or using gdb: + </P +><TABLE +BORDER="5" +BGCOLOR="#E0E0F0" +WIDTH="70%" +><TR +><TD +><PRE +CLASS="SCREEN" +>$ gdb --nw --quiet --args ecos_hello <options> +(gdb) run +Starting program: ecos_hello <options></PRE +></TD +></TR +></TABLE +><P +>By default use of the I/O auxiliary is disabled. If its I/O facilities +are required then the option <TT +CLASS="OPTION" +>--io</TT +> must be used. + </P +><DIV +CLASS="NOTE" +><BLOCKQUOTE +CLASS="NOTE" +><P +><B +>Note: </B +>In future the default behaviour may change, with the I/O auxiliary +being started by default. The option <TT +CLASS="OPTION" +>--nio</TT +> can be +used to prevent the auxiliary from being run. + </P +></BLOCKQUOTE +></DIV +></DIV +><DIV +CLASS="REFSECT1" +><A +NAME="SYNTH-RUNNING-ARGUMENTS" +></A +><H2 +>Command-line Arguments</H2 +><P +>The syntax for running a synthetic target application is: + </P +><TABLE +BORDER="5" +BGCOLOR="#E0E0F0" +WIDTH="70%" +><TR +><TD +><PRE +CLASS="SCREEN" +>$ <ecos_app> [options] [-- [app_options]]</PRE +></TD +></TR +></TABLE +><P +>Command line options up to the <TT +CLASS="OPTION" +>--</TT +> are passed on to +the I/O auxiliary. Subsequent arguments are not passed on to the +auxiliary, and hence can be used by the eCos application itself. The +full set of arguments can be accessed through the variables +<TT +CLASS="VARNAME" +>cyg_hal_sys_argc</TT +> and +<TT +CLASS="VARNAME" +>cyg_hal_sys_argv</TT +>. + </P +><P +>The following options are accepted as standard: + </P +><P +></P +><DIV +CLASS="VARIABLELIST" +><DL +><DT +><TT +CLASS="OPTION" +>--io</TT +></DT +><DD +><P +>This option causes the eCos application to spawn the I/O auxiliary +during HAL initialization. Without this option only limited I/O will +be available. + </P +></DD +><DT +><TT +CLASS="OPTION" +>--nio</TT +></DT +><DD +><P +>This option prevents the eCos application from spawning the I/O +auxiliary. In the current version of the software this is the default. + </P +></DD +><DT +><TT +CLASS="OPTION" +>-nw</TT +>, <TT +CLASS="OPTION" +>--no-windows</TT +></DT +><DD +><P +>The I/O auxiliary can either provide a graphical user interface, or it +can run in a text-only mode. The default is to provide the graphical +interface, but this can be disabled with <TT +CLASS="OPTION" +>-nw</TT +>. +Emulation of some devices, for example buttons connected to digital +inputs, requires the graphical interface. + </P +></DD +><DT +><TT +CLASS="OPTION" +>-w</TT +>, <TT +CLASS="OPTION" +>--windows</TT +></DT +><DD +><P +>The <TT +CLASS="OPTION" +>-w</TT +> causes the I/O auxiliary to provide a +graphical user interface. This is the default. + </P +></DD +><DT +><TT +CLASS="OPTION" +>-v</TT +>, <TT +CLASS="OPTION" +>--version</TT +></DT +><DD +><P +>The <TT +CLASS="OPTION" +>-v</TT +> option can be used to determine the version of +the I/O auxiliary being used and where it has been installed. Both the +auxiliary and the eCos application will exit immediately. + </P +></DD +><DT +><TT +CLASS="OPTION" +>-h</TT +>, <TT +CLASS="OPTION" +>--help</TT +></DT +><DD +><P +><TT +CLASS="OPTION" +>-h</TT +> causes the I/O auxiliary to list all accepted +command-line arguments. This happens after all devices have been +initialized, since the host-side support for some of the devices may +extend the list of recognised options. After this both the auxiliary +and the eCos application will exit immediately. This option implies +<TT +CLASS="OPTION" +>-nw</TT +>. + </P +></DD +><DT +><TT +CLASS="OPTION" +>-k</TT +>, <TT +CLASS="OPTION" +>--keep-going</TT +></DT +><DD +><P +>If an error occurs in the I/O auxiliary while reading in any of the +configuration files or initializing devices, by default both the +auxiliary and the eCos application will exit. The <TT +CLASS="OPTION" +>-k</TT +> +option can be used to make the auxiliary continue in spite of errors, +although obviously it may not be fully functional. + </P +></DD +><DT +><TT +CLASS="OPTION" +>-nr</TT +>, <TT +CLASS="OPTION" +>--no-rc</TT +></DT +><DD +><P +>Normally the auxiliary processes two <A +HREF="synth-running.html#SYNTH-RUNNING-USER-CONFIG" +>user configuration files</A +> +during startup: <TT +CLASS="FILENAME" +>initrc.tcl</TT +> and +<TT +CLASS="FILENAME" +>mainrc.tcl</TT +>. This can be suppressed using the +<TT +CLASS="OPTION" +>-nr</TT +> option. + </P +></DD +><DT +><TT +CLASS="OPTION" +>-x</TT +>, <TT +CLASS="OPTION" +>--exit</TT +></DT +><DD +><P +>When providing a graphical user interface the I/O auxiliary will +normally continue running even after the eCos application has exited. +This allows the user to take actions such as saving the current +contents of the main text window. If run with <TT +CLASS="OPTION" +>-x</TT +> then +the auxiliary will exit as soon the application exits. + </P +></DD +><DT +><TT +CLASS="OPTION" +>-nx</TT +>, <TT +CLASS="OPTION" +>--no-exit</TT +></DT +><DD +><P +>When the graphical user interface is disabled with +<TT +CLASS="OPTION" +>-nw</TT +> the I/O auxiliary will normally exit immediately +when the eCos application exits. Without the graphical frontend there +is usually no way for the user to interact directly with the +auxiliary, so there is no point in continuing to run once the eCos +application will no longer request any I/O operations. Specifying the +<TT +CLASS="OPTION" +>-nx</TT +> option causes the auxiliary to continue running +even after the application has exited. + </P +></DD +><DT +><TT +CLASS="OPTION" +>-V</TT +>, <TT +CLASS="OPTION" +>--verbose</TT +></DT +><DD +><P +>This option causes the I/O auxiliary to output some additional +information, especially during initialization. + </P +></DD +><DT +><TT +CLASS="OPTION" +>-l <file></TT +>, <TT +CLASS="OPTION" +>--logfile <file></TT +></DT +><DD +><P +>Much of the output of the eCos application and the I/O auxiliary is +simple text, for example resulting from eCos +<TT +CLASS="FUNCTION" +>printf</TT +> or <TT +CLASS="FUNCTION" +>diag_printf</TT +> calls. +When running in graphical mode this output goes to a central text +window, and can be saved to a file or edited via menus. The +<TT +CLASS="OPTION" +>-l</TT +> can be used to automatically generate an +additional logfile containing all the text. If graphical +mode is disabled then by default all the text just goes to the current +standard output. Specifying <TT +CLASS="OPTION" +>-l</TT +> causes most of the +text to go into a logfile instead, although some messages such as +errors generated by the auxiliary itself will still go to stdout as +well. + </P +></DD +><DT +><TT +CLASS="OPTION" +>-t <file></TT +>, <TT +CLASS="OPTION" +>--target <file></TT +></DT +><DD +><P +>During initialization the I/O auxiliary reads in a target definition +file. This file holds information such as which Linux devices should +be used to emulate the various eCos devices. The <TT +CLASS="OPTION" +>-t</TT +> +option can be used to specify which target definition should be used +for the current run, defaulting to <TT +CLASS="FILENAME" +>default.tdf</TT +>. +It is not necessary to include the <TT +CLASS="FILENAME" +>.tdf</TT +> suffix, +this will be appended automatically if necessary. + </P +></DD +><DT +><TT +CLASS="OPTION" +>-geometry <geometry></TT +></DT +><DD +><P +>This option can be used to control the size and position of the main +window, as per X conventions. + </P +></DD +></DL +></DIV +><P +>The I/O auxiliary loads support for the various devices dynamically +and some devices may accept additional command line arguments. Details +of these can be obtained using the <TT +CLASS="OPTION" +>-h</TT +> option or by +consulting the device-specific documentation. If an unrecognised +command line argument is used then a warning will be issued. + </P +></DIV +><DIV +CLASS="REFSECT1" +><A +NAME="SYNTH-RUNNING-TDF" +></A +><H2 +>The Target Definition File</H2 +><P +>The eCos application will want to access devices such as +<TT +CLASS="VARNAME" +>eth0</TT +> or <TT +CLASS="VARNAME" +>/dev/ser0</TT +>. These need to +be mapped on to Linux devices. For example some users may all traffic +on the eCos <TT +CLASS="VARNAME" +>/dev/ser0</TT +> serial device to go via the +Linux serial device <TT +CLASS="VARNAME" +>/dev/ttyS1</TT +>, while ethernet I/O +for the eCos <TT +CLASS="VARNAME" +>eth0</TT +> device should be mapped to the +Linux ethertap device <TT +CLASS="VARNAME" +>tap3</TT +>. Some devices may need +additional configuration information, for example to limit the +number of packets that should be buffered within the I/O auxiliary. +The target definition file provides all this information. + </P +><P +>By default the I/O auxiliary will look for a file +<TT +CLASS="FILENAME" +>default.tdf</TT +>. An alternative target definition can +be specified on the command line using <TT +CLASS="OPTION" +>-t</TT +>, for +example: + </P +><TABLE +BORDER="5" +BGCOLOR="#E0E0F0" +WIDTH="70%" +><TR +><TD +><PRE +CLASS="SCREEN" +>$ bridge_app --io -t twineth</PRE +></TD +></TR +></TABLE +><P +>A <TT +CLASS="FILENAME" +>.tdf</TT +> suffix will be appended automatically if +necessary. If a relative pathname is used then the I/O auxiliary will +search for the target definition file in the current directory, then +in <TT +CLASS="FILENAME" +>~/.ecos/synth/</TT +>, and finally +in its install location. + </P +><P +>A typical target definition file might look like this: + </P +><TABLE +BORDER="5" +BGCOLOR="#E0E0F0" +WIDTH="70%" +><TR +><TD +><PRE +CLASS="PROGRAMLISTING" +>synth_device console { + # appearance -foreground white -background black + filter trace {^TRACE:.*} -foreground HotPink1 -hide 1 +} + +synth_device ethernet { + eth0 real eth1 + eth1 ethertap tap4 00:01:02:03:FE:06 + + ## Maximum number of packets that should be buffered per interface. + ## Default 16 + #max_buffer 32 + + ## Filters for the various recognised protocols. + ## By default all filters are visible and use standard colours. + filter ether -hide 0 + #filter arp -hide 1 + #filter ipv4 -hide 1 + #filter ipv6 -hide 1 +}</PRE +></TD +></TR +></TABLE +><P +>A target definition file is actually a Tcl script that gets run in the +main interpreter of the I/O auxiliary during initialization. This +provides a lot of flexibility if necessary. For example the script +could open a socket to a resource management server of some sort to +determine which hardware facilities are already in use and adapt +accordingly. Another possibility is to adapt based on <A +HREF="synth-new-host.html#SYNTH-NEW-HOST-ARGS" +>command line arguments</A +>. Users who +are not familiar with Tcl programming should still be able to edit a +simple target definition file without too much difficulty, using a +mixture of cut'n'paste, commenting or uncommenting various lines, and +making small edits such as changing <TT +CLASS="LITERAL" +>tap4</TT +> to +<TT +CLASS="LITERAL" +>eth2</TT +>. + </P +><P +>Each type of device will have its own entry in the target definition +file, taking the form: + </P +><TABLE +BORDER="5" +BGCOLOR="#E0E0F0" +WIDTH="70%" +><TR +><TD +><PRE +CLASS="PROGRAMLISTING" +>synth_device <device type> { + <options> +}</PRE +></TD +></TR +></TABLE +><P +>The documentaton for each synthetic target device should provide +details of the options available for that device, and often a suitable +fragment that can be pasted into a target definition file and edited. +There is no specific set of options that a given device will always +provide. However in practice many devices will use common code +exported by the main I/O auxiliary, or their implementation will +involve some re-use of code for an existing device. Hence certain +types of option are common to many devices. + </P +><P +>A good example of this is filters, which control the appearance of +text output. The above target definition file defines a filter +<TT +CLASS="VARNAME" +>trace</TT +> for output from the eCos application. The +regular expression will match output from the infrastructure package's +tracing facilities when <TT +CLASS="VARNAME" +>CYGDBG_USE_TRACING</TT +> and +<TT +CLASS="VARNAME" +>CYGDBG_INFRA_DEBUG_TRACE_ASSERT_SIMPLE</TT +> are enabled. +With the current settings this output will not be visible by default, +but can be made visible using the menu item <SPAN +CLASS="GUIMENUITEM" +>System +Filters</SPAN +>. If made visible the trace output will appear in +an unusual colour, so users can easily distinguish the trace output +from other text. All filters accept the following options: + </P +><P +></P +><DIV +CLASS="VARIABLELIST" +><DL +><DT +><TT +CLASS="OPTION" +>-hide [0|1]</TT +></DT +><DD +><P +>This controls whether or not text matching this filter should be +invisible by default or not. At run-time the visibility of each filter +can be controlled using the <SPAN +CLASS="GUIMENUITEM" +>System Filters</SPAN +> +menu item. + </P +></DD +><DT +><TT +CLASS="OPTION" +>-foreground <colour></TT +></DT +><DD +><P +>This specifies the foreground colour for all text matching this +filter. The colour can be specified using an RGB value such as +<TT +CLASS="LITERAL" +>#F08010</TT +>, or a symbolic name such as +<TT +CLASS="LITERAL" +>"light steel blue"</TT +>. The X11 utility +<SPAN +CLASS="APPLICATION" +>showrgb</SPAN +> can be used to find out +about the available colours. + </P +></DD +><DT +><TT +CLASS="OPTION" +>-background <colour></TT +></DT +><DD +><P +>This specifies the background colour for all text matching the filter. +As with <TT +CLASS="OPTION" +>-foreground</TT +> the colour can be specified using +a symbolic name or an RGB value. + </P +></DD +></DL +></DIV +><P +>Some devices may create their own subwindows, for example to monitor +ethernet traffic or to provide additional I/O facilities such as +emulated LED's or buttons. Usually the target definition file can be +used to control the <A +HREF="synth-gui.html#SYNTH-GUI-LAYOUT" +>layout</A +> of +these windows. + </P +><P +>The I/O auxiliary will not normally warn about +<B +CLASS="COMMAND" +>synth_device</B +> entries in the target definition file +for devices that are not actually needed by the current eCos +application. This makes it easier to use a single file for several +different applications. However it can lead to confusion if an entry +is spelled incorrectly and hence does not actually get used. The +<TT +CLASS="OPTION" +>-V</TT +> command line option can be used to get warnings +about unused device entries in the target definition file. + </P +><P +>If the body of a <B +CLASS="COMMAND" +>synth_device</B +> command contains an +unrecognised option and the relevant device is in use, the I/O +auxiliary will always issue a warning about such options. + </P +></DIV +><DIV +CLASS="REFSECT1" +><A +NAME="SYNTH-RUNNING-USER-CONFIG" +></A +><H2 +>User Configuration Files</H2 +><P +>During initialization the I/O auxiliary will execute two user +configuration files, <TT +CLASS="FILENAME" +>initrc.tcl</TT +> and +<TT +CLASS="FILENAME" +>mainrc.tcl</TT +>. It will look for these files in the +directory <TT +CLASS="FILENAME" +>~/.ecos/synth/</TT +>. If +that directory does not yet exist it will be created and populated +with initial dummy files. + </P +><P +>Both of these configuration files are Tcl scripts and will be run in +the main interpreter used by the I/O auxiliary itself. This means that +they have full access to the internals of the auxiliary including the +various Tk widgets, and they can perform file or socket I/O if +desired. The section <A +HREF="synth-new-host.html" +>Writing New Devices - host</A +> contains +information about the facilities available on the host-side for +writing new device drivers, and these can also be used in the +initialization scripts. + </P +><P +>The <TT +CLASS="FILENAME" +>initrc.tcl</TT +> script is run before the auxiliary +has processed any requests from the eCos application, and hence before +any devices have been instantiated. At this point the generic +command-line arguments has been processed, the target definition file +has been read in, and the hooks functionality has been initialized. If +running in graphical mode the main window will have been created, but +has been withdrawn from the screen to allow new widgets to be added +without annoying screen flicker. A typical +<TT +CLASS="FILENAME" +>initrc.tcl</TT +> script could add some menu or toolbar +options, or install a hook function that will be run when the +eCos application exits. + </P +><P +>The <TT +CLASS="FILENAME" +>mainrc.tcl</TT +> script is run after eCos has +performed all its device initialization and after C++ static +constructors have run, and just before the call to +<TT +CLASS="FUNCTION" +>cyg_start</TT +> which will end up transferring control +to the application itself. A typical <TT +CLASS="FILENAME" +>mainrc.tcl</TT +> +script could look at what interrupt vectors have been allocated to +which devices and create a little monitor window that shows interrupt +activity. + </P +></DIV +><DIV +CLASS="REFSECT1" +><A +NAME="SYNTH-RUNNING-SESSION" +></A +><H2 +>Session Information</H2 +><P +>When running in graphical mode, the I/O auxiliary will read in a file +<TT +CLASS="FILENAME" +>~/.ecos/synth/guisession</TT +> containing session +information. This file should not normally be edited manually, instead +it gets updated automatically when the auxiliary exits. The purpose of +this file is to hold configuration options that are manipulated via +the graphical interface, for example which browser should be used to +display online help. + </P +><DIV +CLASS="WARNING" +><P +></P +><TABLE +CLASS="WARNING" +BORDER="1" +WIDTH="100%" +><TR +><TD +ALIGN="CENTER" +><B +>Warning</B +></TD +></TR +><TR +><TD +ALIGN="LEFT" +><P +>GUI session functionality is not yet available in the current release. +When that functionality is fully implemented it is possible that some +target definition file options may be removed, to be replaced by +graphical editing via a suitable preferences dialog, with the +current settings saved in the session file. + </P +></TD +></TR +></TABLE +></DIV +></DIV +><DIV +CLASS="NAVFOOTER" +><HR +ALIGN="LEFT" +WIDTH="100%"><TABLE +SUMMARY="Footer navigation table" +WIDTH="100%" +BORDER="0" +CELLPADDING="0" +CELLSPACING="0" +><TR +><TD +WIDTH="33%" +ALIGN="left" +VALIGN="top" +><A +HREF="synth-install.html" +ACCESSKEY="P" +>Prev</A +></TD +><TD +WIDTH="34%" +ALIGN="center" +VALIGN="top" +><A +HREF="hal-synth-arch.html" +ACCESSKEY="H" +>Home</A +></TD +><TD +WIDTH="33%" +ALIGN="right" +VALIGN="top" +><A +HREF="synth-gui.html" +ACCESSKEY="N" +>Next</A +></TD +></TR +><TR +><TD +WIDTH="33%" +ALIGN="left" +VALIGN="top" +>Installation</TD +><TD +WIDTH="34%" +ALIGN="center" +VALIGN="top" +> </TD +><TD +WIDTH="33%" +ALIGN="right" +VALIGN="top" +>The I/O Auxiliary's User Interface</TD +></TR +></TABLE +></DIV +></BODY +></HTML +> \ No newline at end of file
--- a/packages/hal/synth/arch/current/doc/synth-syscalls.html +++ b/packages/hal/synth/arch/current/doc/synth-syscalls.html @@ -3,9 +3,6 @@ <!-- and conditions set forth in the Open Publication License, v1.0 --> <!-- or later (the latest version is presently available at --> <!-- http://www.opencontent.org/openpub/). --> -<!-- Distribution of substantively modified versions of this --> -<!-- document is prohibited without the explicit permission of the --> -<!-- copyright holder. --> <!-- Distribution of the work or derivative of the work in any --> <!-- standard (paper) book form is prohibited unless prior --> <!-- permission is obtained from the copyright holder. --> @@ -16,17 +13,17 @@ ><meta name="MSSmartTagsPreventParsing" content="TRUE"> <META NAME="GENERATOR" -CONTENT="Modular DocBook HTML Stylesheet Version 1.64 +CONTENT="Modular DocBook HTML Stylesheet Version 1.76b+ "><LINK REL="HOME" TITLE="eCos Synthetic Target" HREF="hal-synth-arch.html"><LINK REL="PREVIOUS" -TITLE="Overview" -HREF="synth.html"><LINK +TITLE="The Console Device" +HREF="synth-console.html"><LINK REL="NEXT" -TITLE="Porting" -HREF="synth-porting.html"></HEAD +TITLE="Writing New Devices - target" +HREF="synth-new-target.html"></HEAD ><BODY CLASS="REFENTRY" BGCOLOR="#FFFFFF" @@ -37,6 +34,7 @@ ALINK="#0000FF" ><DIV CLASS="NAVHEADER" ><TABLE +SUMMARY="Header navigation table" WIDTH="100%" BORDER="0" CELLPADDING="0" @@ -53,7 +51,8 @@ WIDTH="10%" ALIGN="left" VALIGN="bottom" ><A -HREF="synth.html" +HREF="synth-console.html" +ACCESSKEY="P" >Prev</A ></TD ><TD @@ -66,7 +65,8 @@ WIDTH="10%" ALIGN="right" VALIGN="bottom" ><A -HREF="synth-porting.html" +HREF="synth-new-target.html" +ACCESSKEY="N" >Next</A ></TD ></TR @@ -76,13 +76,11 @@ ALIGN="LEFT" WIDTH="100%"></DIV ><H1 ><A -NAME="SYNTH-SYSCALLS" ->System Calls</A -></H1 +NAME="SYNTH-SYSCALLS">System Calls</H1 ><DIV CLASS="REFNAMEDIV" ><A -NAME="AEN51" +NAME="AEN483" ></A ><H2 >Name</H2 @@ -90,21 +88,17 @@ NAME="AEN51" ><DIV CLASS="REFSYNOPSISDIV" ><A -NAME="AEN54" -></A -><H2 +NAME="AEN486"><H2 >Synopsis</H2 ><DIV CLASS="FUNCSYNOPSIS" ><A -NAME="AEN55" -></A -><P +NAME="AEN487"><P ></P ><TABLE -BORDER="0" -BGCOLOR="#E0E0E0" -WIDTH="100%" +BORDER="5" +BGCOLOR="#E0E0F0" +WIDTH="70%" ><TR ><TD ><PRE @@ -118,7 +112,7 @@ CLASS="FUNCSYNOPSISINFO" ><CODE ><CODE CLASS="FUNCDEF" ->int cyg_hal_sys_xyz</CODE +>int cyg_hal_sys_xyzzy</CODE >(...);</CODE ></P ><P @@ -281,6 +275,7 @@ CLASS="NAVFOOTER" ><HR ALIGN="LEFT" WIDTH="100%"><TABLE +SUMMARY="Footer navigation table" WIDTH="100%" BORDER="0" CELLPADDING="0" @@ -291,7 +286,8 @@ WIDTH="33%" ALIGN="left" VALIGN="top" ><A -HREF="synth.html" +HREF="synth-console.html" +ACCESSKEY="P" >Prev</A ></TD ><TD @@ -300,6 +296,7 @@ ALIGN="center" VALIGN="top" ><A HREF="hal-synth-arch.html" +ACCESSKEY="H" >Home</A ></TD ><TD @@ -307,7 +304,8 @@ WIDTH="33%" ALIGN="right" VALIGN="top" ><A -HREF="synth-porting.html" +HREF="synth-new-target.html" +ACCESSKEY="N" >Next</A ></TD ></TR @@ -316,7 +314,7 @@ HREF="synth-porting.html" WIDTH="33%" ALIGN="left" VALIGN="top" ->Overview</TD +>The Console Device</TD ><TD WIDTH="34%" ALIGN="center" @@ -326,7 +324,7 @@ VALIGN="top" WIDTH="33%" ALIGN="right" VALIGN="top" ->Porting</TD +>Writing New Devices - target</TD ></TR ></TABLE ></DIV
--- a/packages/hal/synth/arch/current/doc/synth.html +++ b/packages/hal/synth/arch/current/doc/synth.html @@ -3,9 +3,6 @@ <!-- and conditions set forth in the Open Publication License, v1.0 --> <!-- or later (the latest version is presently available at --> <!-- http://www.opencontent.org/openpub/). --> -<!-- Distribution of substantively modified versions of this --> -<!-- document is prohibited without the explicit permission of the --> -<!-- copyright holder. --> <!-- Distribution of the work or derivative of the work in any --> <!-- standard (paper) book form is prohibited unless prior --> <!-- permission is obtained from the copyright holder. --> @@ -16,7 +13,7 @@ ><meta name="MSSmartTagsPreventParsing" content="TRUE"> <META NAME="GENERATOR" -CONTENT="Modular DocBook HTML Stylesheet Version 1.64 +CONTENT="Modular DocBook HTML Stylesheet Version 1.76b+ "><LINK REL="HOME" TITLE="eCos Synthetic Target" @@ -25,8 +22,8 @@ REL="PREVIOUS" TITLE="eCos Synthetic Target" HREF="hal-synth-arch.html"><LINK REL="NEXT" -TITLE="System Calls" -HREF="synth-syscalls.html"></HEAD +TITLE="Installation" +HREF="synth-install.html"></HEAD ><BODY CLASS="REFENTRY" BGCOLOR="#FFFFFF" @@ -37,6 +34,7 @@ ALINK="#0000FF" ><DIV CLASS="NAVHEADER" ><TABLE +SUMMARY="Header navigation table" WIDTH="100%" BORDER="0" CELLPADDING="0" @@ -54,6 +52,7 @@ ALIGN="left" VALIGN="bottom" ><A HREF="hal-synth-arch.html" +ACCESSKEY="P" >Prev</A ></TD ><TD @@ -66,7 +65,8 @@ WIDTH="10%" ALIGN="right" VALIGN="bottom" ><A -HREF="synth-syscalls.html" +HREF="synth-install.html" +ACCESSKEY="N" >Next</A ></TD ></TR @@ -76,9 +76,7 @@ ALIGN="LEFT" WIDTH="100%"></DIV ><H1 ><A -NAME="SYNTH" ->Overview</A -></H1 +NAME="SYNTH">Overview</H1 ><DIV CLASS="REFNAMEDIV" ><A @@ -86,7 +84,7 @@ NAME="AEN6" ></A ><H2 >Name</H2 ->Overview -- The eCos synthetic target</DIV +>The eCos synthetic target -- Overview</DIV ><DIV CLASS="REFSECT1" ><A @@ -106,13 +104,13 @@ hardware. Such boards have a number of t TYPE="1" ><LI ><P ->Obviously there has to be at least one processor to do the work. -Usually this will be a 32-bit processor, but it can be smaller or -larger. Processor speed will vary widely, depending on the expected -needs of the application. However usually the exact processor being -used does not matter very much for most of the development process: -the use of languages such as C or C++ means that the compiler will -handle those details. +>Obviously there has to be at least one processor to do the work. Often +this will be a 32-bit processor, but it can be smaller or larger. +Processor speed will vary widely, depending on the expected needs of +the application. However the exact processor being used tends not to +matter very much for most of the development process: the use of +languages such as C or C++ means that the compiler will handle those +details. </P ></LI ><LI @@ -161,18 +159,52 @@ Instead of running the embedded applicat target board of some sort, it can be run as a Linux process. The processor will be the PC's own processor, for example an x86, and the memory will be the process' address space. Some I/O facilities can be -emulated through system calls. For example clock hardware can be -emulated by setting up a <TT +emulated directly through system calls. For example clock hardware can +be emulated by setting up a <TT CLASS="LITERAL" >SIGALRM</TT -> signal, which will -cause the process to be interrupted at regular intervals. This -emulation of real hardware will not be particularly accurate, for -example the number of cpu cycles available to the eCos application -between clock ticks will vary widely depending on what else is running -on the PC, but for much development work it will be good enough. +> signal, which +will cause the process to be interrupted at regular intervals. This +emulation of real hardware will not be particularly accurate, the +number of cpu cycles available to the eCos application between clock +ticks will vary widely depending on what else is running on the PC, +but for much development work it will be good enough. </P ><P +>Other I/O facilities are provided through an I/O auxiliary process, +ecosynth, that gets spawned by the eCos application during startup. +When an eCos device driver wants to perform some I/O operation, for +example send out an ethernet packet, it sends a request to the I/O +auxiliary. That is an ordinary Linux application so it has ready +access to all normal Linux I/O facilities. To emulate a device +interrupt the I/O auxiliary can raise a <TT +CLASS="LITERAL" +>SIGIO</TT +> +signal within the eCos application. The HAL's interrupt subsystem +installs a signal handler for this, which will then invoke the +standard eCos ISR/DSR mechanisms. The I/O auxiliary is based around +Tcl scripting, making it easy to extend and customize. It should be +possible to configure the synthetic target so that its I/O +functionality is similar to what will be available on the final target +hardware for the application being developed. + </P +><DIV +CLASS="INFORMALFIGURE" +><A +NAME="AEN25"><P +></P +><DIV +CLASS="MEDIAOBJECT" +><P +><IMG +SRC="overview.gif" +ALIGN="CENTER"></P +></DIV +><P +></P +></DIV +><P >A key requirement for synthetic target code is that the embedded application must not be linked with any of the standard Linux libraries such as the GNU C library: that would lead to a confusing @@ -209,12 +241,20 @@ arguments on to the stack and executes t kernel cannot tell the difference, so it will perform the I/O operation requested by the synthetic target. With appropriate knowledge of what system calls are available, this makes it possible -to emulate the required I/O facilities. For example diagnostic output -can be achieved by a <TT +to emulate the required I/O facilities. For example, spawning the +ecosynth I/O auxiliary involves system calls +<TT +CLASS="FUNCTION" +>cyg_hal_sys_fork</TT +> and +<TT +CLASS="FUNCTION" +>cyg_hal_sys_execve</TT +>, and sending a request to the +auxiliary uses <TT CLASS="FUNCTION" >cyg_hal_sys_write</TT -> system -call using file descriptor 1, which corresponds to stdout. +>. </P ><P >In many ways developing for the synthetic target is no different from @@ -268,125 +308,13 @@ simulator or special tools. This will be simpler than using an architectural simulator, but no attempt is made to accurately match the behaviour of a real embedded target. </P -><DIV -CLASS="NOTE" -><BLOCKQUOTE -CLASS="NOTE" -><P -><B ->Note: </B ->Support for emulating standard hardware such as ethernet is not yet -available in the current release of the eCos synthetic target code, -but is planned for future versions. Emulating application-specific -custom hardware is rather more difficult since there is no way of -knowing just what strange hardware a particular application might -need, but the I/O mechanisms planned should allow for -application-specific extensions. - </P -></BLOCKQUOTE -></DIV -></DIV -><DIV -CLASS="REFSECT1" -><A -NAME="SYNTH-TOOLS" -></A -><H2 ->Toolchain</H2 -><P ->When developing eCos applications for a normal embedded target it is -necessary to use a suitable cross-compiler and related tools such as -the linker. Developing for the synthetic target is easier because you -can just use the standard GNU tools (gcc, g++, ld, …) which -were provided with your Linux distribution, or which you used to build -your own Linux setup. Any reasonably recent version of the tools, for -example gcc 2.96(Red Hat) as shipped with Red Hat Linux 7, should be -sufficient. - </P -><P ->There is one important limitation when using these tools: current gdb -will not support debugging of eCos threads on the synthetic target. As -far as gdb is concerned a synthetic target application is also -indistinguishable from a normal Linux application, so it assumes that -any threads will be created by calls to the Linux -<TT -CLASS="FUNCTION" ->pthread_create</TT -> function provided by the C -library. Obviously this is not the case since the application is never -linked with that library. Therefore gdb never notices the eCos thread -mechanisms and assumes the application is single-threaded. Fixing this -is possible but would involve non-trivial changes to gdb. - </P -><P ->Theoretically it is possible to develop synthetic target applications -on, for example, a PC running Windows and then run the resulting -executables on another machine that runs Linux. This is rarely useful: -if a Linux machine is available then usually that machine will also be -used for building ecos and the application. However, if for some -reason it is necessary or desirable to build on another machine then -this requires a suitable cross-compiler and related tools. If the -application will be running on a typical PC with an x86 processor then -a suitable configure triplet would be -<TT -CLASS="USERINPUT" -><B ->i686-pc-linux-gnu</B -></TT ->. The installation -instructions for the various GNU tools should be consulted for further -information. - </P -></DIV -><DIV -CLASS="REFSECT1" -><A -NAME="SYNTH-HARDWARE" -></A -><H2 ->Hardware Preparation</H2 -><P ->Preparing a real embedded target for eCos development can be tricky. -Often the first step is to install suitable firmware, usually RedBoot. -This means creating and building a special configuration for eCos with -the RedBoot template, then somehow updating the target's flash chips -with the resulting RedBoot image. Typically it will also be necessary -to get a working serial connection, and possibly set up ethernet as -well. Although usually none of the individual steps are particularly -complicated, there are plenty of ways in which things can go wrong and -it can be hard to figure out what is actually happening. Of course -some board manufacturers make life easier for their developers by -shipping hardware with RedBoot preinstalled, but even then it is still -necessary to set up communication between host and target. - </P -><P ->None of this is applicable to the synthetic target. Instead you can -just build a normal eCos configuration, link your application with the -resulting libraries, and you end up with an executable that you can -run directly on your Linux machine or via gdb. A useful side effect of -this is that application development can start before any real -embedded hardware is actually available. - </P -><P ->Typically the memory map for a synthetic target application will be -set up such that there is a read-only ROM region containing all the -code and constant data, and a read-write RAM region for the data. The -default locations and sizes of these regions depend on the specific -platform being used for development. Note that the application always -executes out of ROM: on a real embedded target much of the development -would involve running RedBoot firmware there, with application code -and data loaded into RAM; usually this would change for the final -system; the firmware would be removed; and the application itself -would execute from ROM and perform the appropriate hardware -initialization. Therefore the synthetic target actually emulates the -behaviour of the final system, not the development environment. - </P ></DIV ><DIV CLASS="NAVFOOTER" ><HR ALIGN="LEFT" WIDTH="100%"><TABLE +SUMMARY="Footer navigation table" WIDTH="100%" BORDER="0" CELLPADDING="0" @@ -398,6 +326,7 @@ ALIGN="left" VALIGN="top" ><A HREF="hal-synth-arch.html" +ACCESSKEY="P" >Prev</A ></TD ><TD @@ -406,6 +335,7 @@ ALIGN="center" VALIGN="top" ><A HREF="hal-synth-arch.html" +ACCESSKEY="H" >Home</A ></TD ><TD @@ -413,7 +343,8 @@ WIDTH="33%" ALIGN="right" VALIGN="top" ><A -HREF="synth-syscalls.html" +HREF="synth-install.html" +ACCESSKEY="N" >Next</A ></TD ></TR @@ -432,7 +363,7 @@ VALIGN="top" WIDTH="33%" ALIGN="right" VALIGN="top" ->System Calls</TD +>Installation</TD ></TR ></TABLE ></DIV
--- a/packages/hal/synth/arch/current/doc/synth.sgml +++ b/packages/hal/synth/arch/current/doc/synth.sgml @@ -9,38 +9,22 @@ <!-- Synthetic target architectural documentation. --> <!-- --> <!-- =============================================================== --> -#####ECOSGPLCOPYRIGHTBEGIN#### -## ------------------------------------------- -## This file is part of eCos, the Embedded Configurable Operating System. -## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. -## -## eCos is free software; you can redistribute it and/or modify it under -## the terms of the GNU General Public License as published by the Free -## Software Foundation; either version 2 or (at your option) any later version. -## -## eCos is distributed in the hope that it will be useful, but WITHOUT ANY -## WARRANTY; without even the implied warranty of MERCHANTABILITY or -## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -## for more details. -## -## You should have received a copy of the GNU General Public License along -## with eCos; if not, write to the Free Software Foundation, Inc., -## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. -## -## As a special exception, if other files instantiate templates or use macros -## or inline functions from this file, or you compile this file and link it -## with other works to produce a work based on this file, this file does not -## by itself cause the resulting work to be covered by the GNU General Public -## License. However the source code for this file must still be made available -## in accordance with section (3) of the GNU General Public License. -## -## This exception does not invalidate any other reasons why a work based on -## this file might be covered by the GNU General Public License. -## -## Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. -## at http://sources.redhat.com/ecos/ecos-license/ -## ------------------------------------------- -#####ECOSGPLCOPYRIGHTEND#### +<!-- ####COPYRIGHTBEGIN#### --> +<!-- --> +<!-- =============================================================== --> +<!-- Copyright (C) 2002 Bart Veer. --> +<!-- Copyright (C) 2002 Red Hat, Inc. --> +<!-- This material may be distributed only subject to the terms --> +<!-- and conditions set forth in the Open Publication License, v1.0 --> +<!-- or later (the latest version is presently available at --> +<!-- http://www.opencontent.org/openpub/) --> +<!-- Distribution of the work or derivative of the work in any --> +<!-- standard (paper) book form is prohibited unless prior --> +<!-- permission obtained from the copyright holder --> +<!-- =============================================================== --> +<!-- --> +<!-- ####COPYRIGHTEND#### --> +<!-- =============================================================== --> <!-- =============================================================== --> <!-- #####DESCRIPTIONBEGIN#### --> <!-- --> @@ -63,8 +47,8 @@ <refentrytitle>Overview</refentrytitle> </refmeta> <refnamediv> - <refname>Overview</refname> - <refpurpose>The eCos synthetic target</refpurpose> + <refname>The eCos synthetic target</refname> + <refpurpose>Overview</refpurpose> </refnamediv> <refsect1 id="synth-description"><title>Description</title> @@ -76,13 +60,13 @@ hardware. Such boards have a number of t </para> <orderedlist> <listitem><para> -Obviously there has to be at least one processor to do the work. -Usually this will be a 32-bit processor, but it can be smaller or -larger. Processor speed will vary widely, depending on the expected -needs of the application. However usually the exact processor being -used does not matter very much for most of the development process: -the use of languages such as C or C++ means that the compiler will -handle those details. +Obviously there has to be at least one processor to do the work. Often +this will be a 32-bit processor, but it can be smaller or larger. +Processor speed will vary widely, depending on the expected needs of +the application. However the exact processor being used tends not to +matter very much for most of the development process: the use of +languages such as C or C++ means that the compiler will handle those +details. </para></listitem> <listitem><para> There needs to be memory for code and for data. A typical system will @@ -124,15 +108,38 @@ Instead of running the embedded applicat target board of some sort, it can be run as a Linux process. The processor will be the PC's own processor, for example an x86, and the memory will be the process' address space. Some I/O facilities can be -emulated through system calls. For example clock hardware can be -emulated by setting up a <literal>SIGALRM</literal> signal, which will -cause the process to be interrupted at regular intervals. This -emulation of real hardware will not be particularly accurate, for -example the number of cpu cycles available to the eCos application -between clock ticks will vary widely depending on what else is running -on the PC, but for much development work it will be good enough. +emulated directly through system calls. For example clock hardware can +be emulated by setting up a <literal>SIGALRM</literal> signal, which +will cause the process to be interrupted at regular intervals. This +emulation of real hardware will not be particularly accurate, the +number of cpu cycles available to the eCos application between clock +ticks will vary widely depending on what else is running on the PC, +but for much development work it will be good enough. </para> <para> +Other I/O facilities are provided through an I/O auxiliary process, +ecosynth, that gets spawned by the eCos application during startup. +When an eCos device driver wants to perform some I/O operation, for +example send out an ethernet packet, it sends a request to the I/O +auxiliary. That is an ordinary Linux application so it has ready +access to all normal Linux I/O facilities. To emulate a device +interrupt the I/O auxiliary can raise a <literal>SIGIO</literal> +signal within the eCos application. The HAL's interrupt subsystem +installs a signal handler for this, which will then invoke the +standard eCos ISR/DSR mechanisms. The I/O auxiliary is based around +Tcl scripting, making it easy to extend and customize. It should be +possible to configure the synthetic target so that its I/O +functionality is similar to what will be available on the final target +hardware for the application being developed. + </para> + <informalfigure PgWide=1> + <mediaobject> + <imageobject> + <imagedata fileref="overview.gif" format="gif" Scalefit=1 Align="Center"> + </imageobject> + </mediaobject> + </informalfigure> + <para> A key requirement for synthetic target code is that the embedded application must not be linked with any of the standard Linux libraries such as the GNU C library: that would lead to a confusing @@ -154,9 +161,11 @@ arguments on to the stack and executes t kernel cannot tell the difference, so it will perform the I/O operation requested by the synthetic target. With appropriate knowledge of what system calls are available, this makes it possible -to emulate the required I/O facilities. For example diagnostic output -can be achieved by a <function>cyg_hal_sys_write</function> system -call using file descriptor 1, which corresponds to stdout. +to emulate the required I/O facilities. For example, spawning the +ecosynth I/O auxiliary involves system calls +<function>cyg_hal_sys_fork</function> and +<function>cyg_hal_sys_execve</function>, and sending a request to the +auxiliary uses <function>cyg_hal_sys_write</function>. </para> <para> In many ways developing for the synthetic target is no different from @@ -205,15 +214,97 @@ simulator or special tools. This will be simpler than using an architectural simulator, but no attempt is made to accurately match the behaviour of a real embedded target. </para> - <note><para> -Support for emulating standard hardware such as ethernet is not yet -available in the current release of the eCos synthetic target code, -but is planned for future versions. Emulating application-specific -custom hardware is rather more difficult since there is no way of -knowing just what strange hardware a particular application might -need, but the I/O mechanisms planned should allow for -application-specific extensions. - </para></note> + </refsect1> +</refentry> + +<!-- }}} --> +<!-- {{{ Installation --> + +<refentry id="synth-install"> + <refmeta> + <refentrytitle>Installation</refentrytitle> + </refmeta> + <refnamediv> + <refname>Installation</refname> + <refpurpose>Preparing to use the synthetic target</refpurpose> + </refnamediv> + + <refsect1 id="synth-install-host"><title>Host-side Software</title> + <para> +To get the full functionality of the synthetic target, users must +build and install the I/O auxiliary ecosynth and various support +files. It is possible to develop applications for the synthetic target +without the auxiliary, but only limited I/O facilities will be +available. The relevant code resides in the <filename +class="directory">host</filename> subdirectory of the synthetic target +architectural HAL package, and building it involves the standard +<command>configure</command>, <command>make</command>, and +<command>make install</command> steps. + </para> + <para> +There are two main ways of building the host-side software. It is +possible to build both the generic host-side software and all +package-specific host-side software, including the I/O auxiliary. in a +single build tree. This involves using the +<command>configure</command> script at the toplevel of the eCos +repository, which will automatically search the <filename +class="directory">packages</filename> hierarchy for host-side +software. For more information on this, see the +<filename>README.host</filename> file at the top of the repository. +Note that if you have an existing build tree which does not include +the synthetic target architectural HAL package then it will be +necessary to rerun the toplevel configure script: the search for +appropriate packages happens at configure time. + </para> + <para> +The alternative is to build just the host-side for this package. +This involves creating a suitable build directory and running the +<command>configure</command> script. Note that building directly in +the source tree is not allowed. + </para> + <screen> +$ cd <somewhere suitable> +$ mkdir synth_build +$ cd synth_build +$ <repo<>/packages/hal/synth/arch/<version>/host/configure <options> +$ make +$ make install +</screen> + <para> +The code makes extensive use of Tcl/TK and requires version 8.3 or +later. This is checked by the <command>configure</command> script. By +default it will use the system's Tcl installation in <filename +class="directory">/usr</filename>. If a different, more recent Tcl +installation should be used then its location can be specified using +the options <option>--with-tcl=<path></option>, +<option>--with-tcl-header=<path></option> and +<option>--with-tcl-lib=<path></option>. For more information on these options +see the <filename>README.host</filename> file at the toplevel of the +eCos repository. + </para> + <para> +Some users may also want to specify the install location using a +<option>--prefix=<path></option> option. The default install +location is <filename class="directory">/usr/local</filename>. It is +essential that the <filename class="directory">bin</filename> +subdirectory of the install location is on the user's search +<envar>PATH</envar>, otherwise the eCos application will be unable to +locate and execute the I/O auxiliary ecosynth. + </para> + <para> +Because ecosynth is run automatically by an eCos application rather +than explicitly by the user, it is not installed in the <filename +class="directory">bin</filename> subdirectory itself. Instead it is +installed below <filename class="directory">libexec</filename>, +together with various support files such as images. At configure time +it is usually possible to specify an alternative location for +<filename class="directory">libexec</filename> using +<option>--exec-prefix=<path></option> or +<option>--libexecdir=<path></option>. These options should not +be used for this package because the eCos application is built +completely separately and does not know how the host-side was +configured. + </para> </refsect1> <refsect1 id="synth-tools"><title>Toolchain</title> @@ -230,7 +321,7 @@ sufficient. <para> There is one important limitation when using these tools: current gdb will not support debugging of eCos threads on the synthetic target. As -far as gdb is concerned a synthetic target application is also +far as gdb is concerned a synthetic target application is indistinguishable from a normal Linux application, so it assumes that any threads will be created by calls to the Linux <function>pthread_create</function> function provided by the C @@ -287,10 +378,890 @@ platform being used for development. Not executes out of ROM: on a real embedded target much of the development would involve running RedBoot firmware there, with application code and data loaded into RAM; usually this would change for the final -system; the firmware would be removed; and the application itself -would execute from ROM and perform the appropriate hardware -initialization. Therefore the synthetic target actually emulates the -behaviour of the final system, not the development environment. +system; the firmware would be replaced by the eCos application itself, +configured for ROM bootstrap, and it would perform the appropriate +hardware initialization. Therefore the synthetic target actually +emulates the behaviour of a final system, not of a development +environment. In practice this is rarely significant, although having +the code in read-only memory can help catch some problems in +application code. + </para> + </refsect1> + +</refentry> + +<!-- }}} --> +<!-- {{{ Running the application --> + +<refentry id="synth-running"> + <refmeta> + <refentrytitle>Running a Synthetic Target Application</refentrytitle> + </refmeta> + <refnamediv> + <refname>Execution</refname> + <refpurpose>Arguments and configuration files</refpurpose> + </refnamediv> + + <refsect1 id="synth-running-description"><title>Description</title> + <para> +The procedure for configuring and building eCos and an application for +the synthetic target is the same as for any other eCos target. Once an +executable has been built it can be run like any Linux program, for +example from a shell prompt, + </para> + <screen> +$ ecos_hello <options> +</screen> + <para> +or using gdb: + </para> + <screen> +$ gdb --nw --quiet --args ecos_hello <options> +(gdb) run +Starting program: ecos_hello <options> +</screen> + <para> +By default use of the I/O auxiliary is disabled. If its I/O facilities +are required then the option <option>--io</option> must be used. + </para> + <note><para> +In future the default behaviour may change, with the I/O auxiliary +being started by default. The option <option>--nio</option> can be +used to prevent the auxiliary from being run. + </para></note> + </refsect1> + + <refsect1 id="synth-running-arguments"><title>Command-line Arguments</title> + <para> +The syntax for running a synthetic target application is: + </para> + <screen> +$ <ecos_app> [options] [-- [app_options]] +</screen> + <para> +Command line options up to the <option>--</option> are passed on to +the I/O auxiliary. Subsequent arguments are not passed on to the +auxiliary, and hence can be used by the eCos application itself. The +full set of arguments can be accessed through the variables +<varname>cyg_hal_sys_argc</varname> and +<varname>cyg_hal_sys_argv</varname>. + </para> + <para> +The following options are accepted as standard: + </para> + <variablelist> + <varlistentry> + <term><option>--io</option></term> + <listitem><para> +This option causes the eCos application to spawn the I/O auxiliary +during HAL initialization. Without this option only limited I/O will +be available. + </para></listitem> + </varlistentry> + <varlistentry> + <term><option>--nio</option></term> + <listitem><para> +This option prevents the eCos application from spawning the I/O +auxiliary. In the current version of the software this is the default. + </para></listitem> + </varlistentry> + <varlistentry> + <term><option>-nw</option>, <option>--no-windows</option></term> + <listitem><para> +The I/O auxiliary can either provide a graphical user interface, or it +can run in a text-only mode. The default is to provide the graphical +interface, but this can be disabled with <option>-nw</option>. +Emulation of some devices, for example buttons connected to digital +inputs, requires the graphical interface. + </para></listitem> + </varlistentry> + <varlistentry> + <term><option>-w</option>, <option>--windows</option></term> + <listitem><para> +The <option>-w</option> causes the I/O auxiliary to provide a +graphical user interface. This is the default. + </para></listitem> + </varlistentry> + <varlistentry> + <term><option>-v</option>, <option>--version</option></term> + <listitem><para> +The <option>-v</option> option can be used to determine the version of +the I/O auxiliary being used and where it has been installed. Both the +auxiliary and the eCos application will exit immediately. + </para></listitem> + </varlistentry> + <varlistentry> + <term><option>-h</option>, <option>--help</option></term> + <listitem><para> +<option>-h</option> causes the I/O auxiliary to list all accepted +command-line arguments. This happens after all devices have been +initialized, since the host-side support for some of the devices may +extend the list of recognised options. After this both the auxiliary +and the eCos application will exit immediately. This option implies +<option>-nw</option>. + </para></listitem> + </varlistentry> + <varlistentry> + <term><option>-k</option>, <option>--keep-going</option></term> + <listitem><para> +If an error occurs in the I/O auxiliary while reading in any of the +configuration files or initializing devices, by default both the +auxiliary and the eCos application will exit. The <option>-k</option> +option can be used to make the auxiliary continue in spite of errors, +although obviously it may not be fully functional. + </para></listitem> + </varlistentry> + <varlistentry> + <term><option>-nr</option>, <option>--no-rc</option></term> + <listitem><para> +Normally the auxiliary processes two <link +linkend="synth-running-user-config">user configuration files</link> +during startup: <filename>initrc.tcl</filename> and +<filename>mainrc.tcl</filename>. This can be suppressed using the +<option>-nr</option> option. + </para></listitem> + </varlistentry> + <varlistentry> + <term><option>-x</option>, <option>--exit</option></term> + <listitem><para> +When providing a graphical user interface the I/O auxiliary will +normally continue running even after the eCos application has exited. +This allows the user to take actions such as saving the current +contents of the main text window. If run with <option>-x</option> then +the auxiliary will exit as soon the application exits. + </para></listitem> + </varlistentry> + <varlistentry> + <term><option>-nx</option>, <option>--no-exit</option></term> + <listitem><para> +When the graphical user interface is disabled with +<option>-nw</option> the I/O auxiliary will normally exit immediately +when the eCos application exits. Without the graphical frontend there +is usually no way for the user to interact directly with the +auxiliary, so there is no point in continuing to run once the eCos +application will no longer request any I/O operations. Specifying the +<option>-nx</option> option causes the auxiliary to continue running +even after the application has exited. + </para></listitem> + </varlistentry> + <varlistentry> + <term><option>-V</option>, <option>--verbose</option></term> + <listitem><para> +This option causes the I/O auxiliary to output some additional +information, especially during initialization. + </para></listitem> + </varlistentry> + <varlistentry> + <term><option>-l <file></option>, <option>--logfile <file></option></term> + <listitem><para> +Much of the output of the eCos application and the I/O auxiliary is +simple text, for example resulting from eCos +<function>printf</function> or <function>diag_printf</function> calls. +When running in graphical mode this output goes to a central text +window, and can be saved to a file or edited via menus. The +<option>-l</option> can be used to automatically generate an +additional logfile containing all the text. If graphical +mode is disabled then by default all the text just goes to the current +standard output. Specifying <option>-l</option> causes most of the +text to go into a logfile instead, although some messages such as +errors generated by the auxiliary itself will still go to stdout as +well. + </para></listitem> + </varlistentry> + <varlistentry> + <term><option>-t <file></option>, <option>--target <file></option></term> + <listitem><para> +During initialization the I/O auxiliary reads in a target definition +file. This file holds information such as which Linux devices should +be used to emulate the various eCos devices. The <option>-t</option> +option can be used to specify which target definition should be used +for the current run, defaulting to <filename>default.tdf</filename>. +It is not necessary to include the <filename>.tdf</filename> suffix, +this will be appended automatically if necessary. + </para></listitem> + </varlistentry> + <varlistentry> + <term><option>-geometry <geometry></option></term> + <listitem><para> +This option can be used to control the size and position of the main +window, as per X conventions. + </para></listitem> + </varlistentry> + </variablelist> + <para> +The I/O auxiliary loads support for the various devices dynamically +and some devices may accept additional command line arguments. Details +of these can be obtained using the <option>-h</option> option or by +consulting the device-specific documentation. If an unrecognised +command line argument is used then a warning will be issued. + </para> + </refsect1> + + <refsect1 id="synth-running-tdf"><title>The Target Definition File</title> + <para> +The eCos application will want to access devices such as +<varname>eth0</varname> or <varname>/dev/ser0</varname>. These need to +be mapped on to Linux devices. For example some users may all traffic +on the eCos <varname>/dev/ser0</varname> serial device to go via the +Linux serial device <varname>/dev/ttyS1</varname>, while ethernet I/O +for the eCos <varname>eth0</varname> device should be mapped to the +Linux ethertap device <varname>tap3</varname>. Some devices may need +additional configuration information, for example to limit the +number of packets that should be buffered within the I/O auxiliary. +The target definition file provides all this information. + </para> + <para> +By default the I/O auxiliary will look for a file +<filename>default.tdf</filename>. An alternative target definition can +be specified on the command line using <option>-t</option>, for +example: + </para> + <screen> +$ bridge_app --io -t twineth +</screen> + <para> +A <filename>.tdf</filename> suffix will be appended automatically if +necessary. If a relative pathname is used then the I/O auxiliary will +search for the target definition file in the current directory, then +in <filename class="directory">~/.ecos/synth/</filename>, and finally +in its install location. + </para> + <para> +A typical target definition file might look like this: + </para> + <programlisting> +synth_device console { + # appearance -foreground white -background black + filter trace {^TRACE:.*} -foreground HotPink1 -hide 1 +} + +synth_device ethernet { + eth0 real eth1 + eth1 ethertap tap4 00:01:02:03:FE:06 + + ## Maximum number of packets that should be buffered per interface. + ## Default 16 + #max_buffer 32 + + ## Filters for the various recognised protocols. + ## By default all filters are visible and use standard colours. + filter ether -hide 0 + #filter arp -hide 1 + #filter ipv4 -hide 1 + #filter ipv6 -hide 1 +} +</programlisting> + <para> +A target definition file is actually a Tcl script that gets run in the +main interpreter of the I/O auxiliary during initialization. This +provides a lot of flexibility if necessary. For example the script +could open a socket to a resource management server of some sort to +determine which hardware facilities are already in use and adapt +accordingly. Another possibility is to adapt based on <link +linkend="synth-new-host-args">command line arguments</link>. Users who +are not familiar with Tcl programming should still be able to edit a +simple target definition file without too much difficulty, using a +mixture of cut'n'paste, commenting or uncommenting various lines, and +making small edits such as changing <literal>tap4</literal> to +<literal>eth2</literal>. + </para> + <para> +Each type of device will have its own entry in the target definition +file, taking the form: + </para> + <programlisting> +synth_device <device type> { + <options> +} +</programlisting> + <para> +The documentaton for each synthetic target device should provide +details of the options available for that device, and often a suitable +fragment that can be pasted into a target definition file and edited. +There is no specific set of options that a given device will always +provide. However in practice many devices will use common code +exported by the main I/O auxiliary, or their implementation will +involve some re-use of code for an existing device. Hence certain +types of option are common to many devices. + </para> + <para> +A good example of this is filters, which control the appearance of +text output. The above target definition file defines a filter +<varname>trace</varname> for output from the eCos application. The +regular expression will match output from the infrastructure package's +tracing facilities when <varname>CYGDBG_USE_TRACING</varname> and +<varname>CYGDBG_INFRA_DEBUG_TRACE_ASSERT_SIMPLE</varname> are enabled. +With the current settings this output will not be visible by default, +but can be made visible using the menu item <guimenuitem>System +Filters</guimenuitem>. If made visible the trace output will appear in +an unusual colour, so users can easily distinguish the trace output +from other text. All filters accept the following options: + </para> + <variablelist> + <varlistentry> + <term><option>-hide [0|1]</option></term> + <listitem><para> +This controls whether or not text matching this filter should be +invisible by default or not. At run-time the visibility of each filter +can be controlled using the <guimenuitem>System Filters</guimenuitem> +menu item. + </para></listitem> + </varlistentry> + <varlistentry> + <term><option>-foreground <colour></option></term> + <listitem><para> +This specifies the foreground colour for all text matching this +filter. The colour can be specified using an RGB value such as +<literal>#F08010</literal>, or a symbolic name such as +<literal>"light steel blue"</literal>. The X11 utility +<application>showrgb</application> can be used to find out +about the available colours. + </para></listitem> + </varlistentry> + <varlistentry> + <term><option>-background <colour></option></term> + <listitem><para> +This specifies the background colour for all text matching the filter. +As with <option>-foreground</option> the colour can be specified using +a symbolic name or an RGB value. + </para></listitem> + </varlistentry> + </variablelist> + <para> +Some devices may create their own subwindows, for example to monitor +ethernet traffic or to provide additional I/O facilities such as +emulated LED's or buttons. Usually the target definition file can be +used to control the <link linkend="synth-gui-layout">layout</link> of +these windows. + </para> + <para> +The I/O auxiliary will not normally warn about +<command>synth_device</command> entries in the target definition file +for devices that are not actually needed by the current eCos +application. This makes it easier to use a single file for several +different applications. However it can lead to confusion if an entry +is spelled incorrectly and hence does not actually get used. The +<option>-V</option> command line option can be used to get warnings +about unused device entries in the target definition file. + </para> + <para> +If the body of a <command>synth_device</command> command contains an +unrecognised option and the relevant device is in use, the I/O +auxiliary will always issue a warning about such options. + </para> + </refsect1> + + <refsect1 id="synth-running-user-config"><title>User Configuration Files</title> + <para> +During initialization the I/O auxiliary will execute two user +configuration files, <filename>initrc.tcl</filename> and +<filename>mainrc.tcl</filename>. It will look for these files in the +directory <filename class="directory">~/.ecos/synth/</filename>. If +that directory does not yet exist it will be created and populated +with initial dummy files. + </para> + <para> +Both of these configuration files are Tcl scripts and will be run in +the main interpreter used by the I/O auxiliary itself. This means that +they have full access to the internals of the auxiliary including the +various Tk widgets, and they can perform file or socket I/O if +desired. The section <xref linkend="synth-new-host"> contains +information about the facilities available on the host-side for +writing new device drivers, and these can also be used in the +initialization scripts. + </para> + <para> +The <filename>initrc.tcl</filename> script is run before the auxiliary +has processed any requests from the eCos application, and hence before +any devices have been instantiated. At this point the generic +command-line arguments has been processed, the target definition file +has been read in, and the hooks functionality has been initialized. If +running in graphical mode the main window will have been created, but +has been withdrawn from the screen to allow new widgets to be added +without annoying screen flicker. A typical +<filename>initrc.tcl</filename> script could add some menu or toolbar +options, or install a hook function that will be run when the +eCos application exits. + </para> + <para> +The <filename>mainrc.tcl</filename> script is run after eCos has +performed all its device initialization and after C++ static +constructors have run, and just before the call to +<function>cyg_start</function> which will end up transferring control +to the application itself. A typical <filename>mainrc.tcl</filename> +script could look at what interrupt vectors have been allocated to +which devices and create a little monitor window that shows interrupt +activity. + </para> + </refsect1> + + <refsect1 id="synth-running-session"><title>Session Information</title> + <para> +When running in graphical mode, the I/O auxiliary will read in a file +<filename>~/.ecos/synth/guisession</filename> containing session +information. This file should not normally be edited manually, instead +it gets updated automatically when the auxiliary exits. The purpose of +this file is to hold configuration options that are manipulated via +the graphical interface, for example which browser should be used to +display online help. + </para> + <warning><para> +GUI session functionality is not yet available in the current release. +When that functionality is fully implemented it is possible that some +target definition file options may be removed, to be replaced by +graphical editing via a suitable preferences dialog, with the +current settings saved in the session file. + </para></warning> + </refsect1> + +</refentry> + +<!-- }}} --> +<!-- {{{ ecosynth user interface --> + +<refentry id="synth-gui"> + <refmeta> + <refentrytitle>The I/O Auxiliary's User Interface</refentrytitle> + </refmeta> + <refnamediv> + <refname>User Interface</refname> + <refpurpose>Controlling the I/O Auxiliary</refpurpose> + </refnamediv> + + <refsect1 id="synth-gui-description"><title>Description</title> + <para> +The synthetic target auxiliary is designed to support both extensions +and user customization. Support for the desired devices is dynamically +loaded, and each device can extend the user interface. For example it +is possible for a device to add menu options, place new buttons on the +toolbar, create its own sub-window within the overall layout, or even +create entire new toplevel windows. These subwindows or toplevels +could show graphs of activity such as interrupts or packets being +transferred. They could also allow users to interact with the eCos +application, for example by showing a number of buttons which will be +mapped on to digital inputs in the eCos application. Different +applications will have their own I/O requirements, changing the +host-side support files that get loaded and that may modify the user +interface. The I/O auxiliary also reads in user configuration scripts +which can enhance the interface in the same way. Therefore the exact +user interface will depend on the user and on the eCos application +being run. However the overall layout is likely to remain the same. + </para> + <informalfigure PgWide=1> + <mediaobject> + <imageobject> + <imagedata fileref="screen_main.gif" format="gif" Scalefit=1 Align="Center"> + </imageobject> + </mediaobject> + </informalfigure> + <para> +The title bar identifies the window as belonging to an eCos synthetic +target application and lists both the application name and its process +id. The latter is especially useful if the application was started +directly from a shell prompt and the user now wants to attach a gdb +session. The window has a conventional menu bar with the usual +entries, plus a toolbar with buttons for common operations such as cut +and paste. Balloon help is supported. + </para> + <para> +There is a central <link linkend="synth-gui-text">text window</link>, +possibly surrounded by various sub-windows for various devices. For +example there could be a row of emulated LED's above the text window, +and monitors of ethernet traffic and interrupt activity on the right. +At the bottom of the window is a status line, including a small +animation that shows whether or not the eCos application is still +running. + </para> + </refsect1> + + <refsect1 id="synth-gui-menus"><title>Menus and the Toolbar</title> + <para> +Usually there will be four menus on the menu bar: +<guimenu>File</guimenu>, <guimenu>Edit</guimenu>, +<guimenu>View</guimenu> and <guimenu>Help</guimenu>. + </para> + <informalfigure PgWide=1> + <mediaobject> + <imageobject> + <imagedata fileref="menu_file.gif" format="gif" Scalefit=1 Align="Center"> + </imageobject> + </mediaobject> + </informalfigure> + <para> +On the <guimenu>File</guimenu> menu there are three entries related to +saving the current contents of the central text window. +<guimenuitem>Save</guimenuitem> is used to save the currently visible +contents of the text window. Any text that is hidden because of +filters will not be written to the savefile. If there has been a +previous <guimenuitem>Save</guimenuitem> or <guimenuitem>Save +As</guimenuitem> operation then the existing savefile will be re-used, +otherwise the user will be asked to select a suitable file. +<guimenuitem>Save As</guimenuitem> also saves just the currently +visible contents but will always prompt the user for a filename. +<guimenuitem>Save All</guimenuitem> can be used to save the full +contents of the text window, including any text that is currently +hidden. It will always prompt for a new filename, to avoid confusion +with partial savefiles. + </para> + <para> +Usually the eCos application will be run from inside gdb or from a +shell prompt. Killing off the application while it is being debugged +in a gdb session is not a good idea, it would be better to use gdb's +own <command>kill</command> command. Alternatively the eCos +application itself can use the <function>CYG_TEST_EXIT</function> or +<filename>cyg_hal_sys_exit</filename> functionality. However it is +possible to terminate the application from the I/O auxiliary using +<guimenuitem>Kill eCos</guimenuitem>. A clean shutdown will be +attempted, but that can fail if the application is currently halted +inside gdb or if it has crashed completely. As a last resort +<constant>SIGKILL</constant> will be used. + </para> + <para> +When operating in graphical mode the I/O auxiliary will normally +continue to run even after the eCos application has exited. This +allows the user to examine the last few lines of output, and perhaps +perform actions such as saving the output to a file. The +<guimenuitem>Exit</guimenuitem> menu item can be used to shut down the +auxiliary. Note that this behaviour can be changed with command line +arguments <link +linkend="synth-running-arguments"><option>--exit</option></link> and +<link +linkend="synth-running-arguments"><option>--no-exit</option></link>. + </para> + <para> +If <guimenuitem>Exit</guimenuitem> is used while the eCos application +is still running then the I/O auxiliary will first attempt to +terminate the application cleanly, and then exit. + </para> + <informalfigure PgWide=1> + <mediaobject> + <imageobject> + <imagedata fileref="menu_edit.gif" format="gif" Scalefit=1 Align="Center"> + </imageobject> + </mediaobject> + </informalfigure> + <para> +The <guimenu>Edit</guimenu> menu contains the usual entries for +text manipulation: <guimenuitem>Cut</guimenuitem>, +<guimenuitem>Copy</guimenuitem>, <guimenuitem>Paste</guimenuitem>, +<guimenuitem>Clear</guimenuitem> and <guimenuitem>Select +All</guimenuitem>. These all operate on the central text window. By +default this window cannot be edited so the cut, paste and clear +operations are disabled. If the user wants to edit the contents of the +text window then the <guimenuitem>Read Only</guimenuitem> checkbutton +should be toggled. + </para> + <para> +The <guimenuitem>Preferences</guimenuitem> menu item brings up a +miscellaneous preferences dialog. One of the preferences relates to +online help: the I/O auxiliary does not currently have a built-in html +viewer; instead it will execute an external browser of some sort. With +the example settings shown, the I/O auxiliary will first attempt to +interact with an existing mozilla session. If that fails it will try +to run a new mozilla instance, or as a last result use the Gnome help +viewer. + </para> + <informalfigure PgWide=1> + <mediaobject> + <imageobject> + <imagedata fileref="preferences.gif" format="gif" Scalefit=1 Align="Center"> + </imageobject> + </mediaobject> + </informalfigure> + <para> +The <guimenu>View</guimenu> menu contains the <guimenuitem>System +Filters</guimenuitem> entry, used to edit the settings for the current +<link linkend="synth-gui-text">filters</link>. + </para> + <informalfigure PgWide=1> + <mediaobject> + <imageobject> + <imagedata fileref="menu_view.gif" format="gif" Scalefit=1 Align="Center"> + </imageobject> + </mediaobject> + </informalfigure> + <para> +The <guimenu>Help</guimenu> menu can be used to activate online help +for eCos generally, for the synthetic target as a whole, and for +specific devices supported by the generic target. The Preferences +dialog can be used to select the browser that will be used. + </para> + <informalfigure PgWide=1> + <mediaobject> + <imageobject> + <imagedata fileref="menu_help.gif" format="gif" Scalefit=1 Align="Center"> + </imageobject> + </mediaobject> + </informalfigure> + <note><para> +At the time of writing there is no well-defined toplevel index file +for all eCos documentation. Hence the relevant menu item is disabled. +Documentation for the synthetic target and the supported devices +is stored as part of the package itself so can usually be found fairly +easily. It may be necessary to set the <envar>ECOS_REPOSITORY</envar> +environment variable. + </para></note> + + </refsect1> + + <refsect1 id="synth-gui-text"><title>The Main Text Window</title> + <para> +The central text window holds the console output from the eCos +application: the screen shot above shows DHCP initialization data from +the TCP/IP stack, and some output from the <function>main</function> +thread at the bottom. Some devices can insert text of their own, for +example the ethernet device support can be configured to show details +of incoming and outgoing packets. Mixing the output from the eCos +application and the various devices can make it easier to understand +the order in which events occur. + </para> + <para> +The appearance of text from different sources can be controlled by +means of filters, and it is also possible to hide some of the text. +For example, if tracing is enabled in the eCos configuration then the +trace output can be given its own colour scheme, making it stand out +from the rest of the output. In addition the trace output is generally +voluminous so it can be hidden by default, made visible only to find +out more about what was happening when a particular problem occurred. +Similarly the ethernet device support can output details of the +various packets being transferred, and using a different background +colour for this output again makes it easier to distinguish from +console output. + </para> + <para> +The default appearance for most filters is controlled via the +<link linkend="synth-running-tdf">target definition file</link>. An +example entry might be: + </para> + <programlisting> + filter trace {^TRACE:.*} -foreground HotPink1 -hide 1 +</programlisting> + <para> +The various colours and the hide flag for each filter can be changed +at run-time, using the <guimenuitem>System Filters</guimenuitem> item +on the <guimenu>View</guimenu> menu. This will bring up a dialog like +the following: + </para> + <informalfigure PgWide=1> + <mediaobject> + <imageobject> + <imagedata fileref="filters.gif" format="gif" Scalefit=1 Align="Center"> + </imageobject> + </mediaobject> + </informalfigure> + <para> +It should be noted that the text window is line-oriented, not +character-oriented. If an eCos application sends a partial line of +text then that will remain buffered until a newline character is +received, rather than being displayed immediately. This avoids +confusion when there is concurrent output from several sources. + </para> + <para> +By default the text window is read-only. This means it will not allow +cut, paste and clear operations, and keyboard input will be ignored. +The <guimenu>Edit</guimenu> menu has a checkbutton <guimenuitem>Read +Only</guimenuitem> which can be toggled to allow write operations. For +example, a user could type in a reminder of what was happening at this +time, or paste in part of a gdb session. Such keyboard input does not +get forwarded to the eCos application: if the latter requires keyboard +input then that should happen via a separate keyboard device. + </para> + </refsect1> + + <refsect1 id="synth-gui-layout"><title>Positioning Optional Windows</title> + <para> +Some devices may create their own subwindows, for example to monitor +ethernet traffic or to provide additional I/O facilities such as +emulated LED's or buttons. Usually the target definition file can be +used to control the <link linkend="synth-gui-layout">layout</link> of +these windows. This requires an understanding of the overall layout of +the display. + </para> + <informalfigure PgWide=1> + <mediaobject> + <imageobject> + <imagedata fileref="layout.gif" format="gif" Scalefit=1 Align="Center"> + </imageobject> + </mediaobject> + </informalfigure> + <para> +Subwindows are generally packed in one of eight frames surrounding the +central text window: <varname>.main.nw</varname>, +<varname>.main.n</varname>, <varname>.main.ne</varname>, +<varname>.main.w</varname>, <varname>.main.e</varname>, +<varname>.main.sw</varname>, <varname>.main.s</varname>, and +<varname>.main.se</varname>. To position a row of LED's above the text +window and towards the left, a target definition file could contain an +entry such as: + </para> + <programlisting> +synth_device led { + pack -in .main.n -side left + … +} +</programlisting> + <para> +Similarly, to put a traffic monitor window on the right of the text +window would involve something like: + </para> + <programlisting> + … + monitor_pack -in .main.e -side bottom + … +</programlisting> + <para> +Often it will be sufficient to specify a container frame and one of +<constant>left</constant>, <constant>right</constant>, +<constant>top</constant> or <constant>bottom</constant>. Full control +over the positioning requires an understanding of Tcl/Tk and in +particular the packing algorithm, and an appropriate reference work +should be consulted. + </para> + </refsect1> + + <refsect1 id="synth-gui-global-config"><title>Global Settings</title> + <note><para> +This section still to be written - it should document the interaction +between X resources and ecosynth, and how users can control settings +such as the main foreground and background colours. + </para></note> + </refsect1> + +</refentry> + +<!-- }}} --> +<!-- {{{ The console device --> + +<refentry id="synth-console"> + <refmeta> + <refentrytitle>The Console Device</refentrytitle> + </refmeta> + <refnamediv> + <refname>The console device </refname> + <refpurpose>Show output from the eCos application</refpurpose> + </refnamediv> + + <refsect1 id="synth-console-description"><title>Description</title> + <para> +The eCos application can generate text output in a variety of ways, +including calling <function>printf</function> or +<function>diag_printf</function>. When the I/O auxiliary is enabled +the eCos startup code will instantiate a console device to process all +such output. If operating in text mode the output will simply go to +standard output, or to a logfile if the <option>-l</option> command +line option is specified. If operating in graphical mode the output +will go to the central text window, and optionally to a logfile as +well. In addition it is possible to control the appearance of the main +text via the target definition file, and to install extra filters for +certain types of text. + </para> + <para> +It should be noted that the console device is line-oriented, not +character-oriented. This means that outputting partial lines is not +supported, and some functions such as <function>fflush</function> and +<function>setvbuf</function> will not operate as expected. This +limitation prevents much possible confusion when using filters to +control the appearance of the text window, and has some performance +benefits - especially when the eCos application generates a great deal +of output such as when tracing is enabled. For most applications this +is not a problem, but it is something that developers should be aware +of. + </para> + <para> +The console device is output-only, it does not provide any support for +keyboard input. If the application requires keyboard input then that +should be handled by a separate eCos device package and matching +host-side code. + </para> + </refsect1> + + <refsect1 id="synth-console-install"><title>Installation</title> + <para> +The eCos side of the console device is implemented by the +architectural HAL itself, in the source file +<filename>synth_diag.c</filename>, rather than in a separate device +package. Similarly the host-side implementation, +<function>console.tcl</function>, is part of the architectural HAL's +host-side support. It gets installed automatically alongside the I/O +auxiliary itself, so no separate installation procedure is required. + </para> + </refsect1> + + <refsect1 id="synth-console-tdf"><title>Target Definition File</title> + <para> +The <link linkend="synth-running-tdf">target definition file</link> +can contain a number of entries related to the console device. These +are all optional, they only control the appearance of text output. If +such control is desired then the relevant options should appear in the +body of a <command>synth_device</command> entry: + </para> + <programlisting> +synth_device console { + … +} +</programlisting> + <para> +The first option is <command>appearance</command>, used to control the +appearance of any text generated by the eCos application that does not +match one of the installed filters. This option takes the same +argument as any other filter, for example: + </para> + <programlisting> +synth_device console { + appearance -foreground white -background black + … +} +</programlisting> + <para> +Any number of additional filters can be created with a +<command>filter</command> option, for example: + </para> + <programlisting> +synth_device console { + … + filter trace {^TRACE:.*} -foreground HotPink1 -hide 1 + … +} +</programlisting> + <para> +The first argument gives the new filter a name which will be used in +the <link linkend="synth-gui-text">filters dialog</link>. Filter names +should be unique. The second argument is a Tcl regular expression. The +console support will match each line of eCos output against this +regular expression, and if a match is found then the filter will be +used for this line of text. The above example matches any line of +output that begins with <literal>TRACE:</literal>, which corresponds +to the eCos infrastructure's tracing facilities. The remaining options +control the desired appearance for matched text. If some eCos output +matches the regular expressions for several different filters then +only the first match will be used. + </para> + </refsect1> + + <refsect1 id="synth-console-target-config"><title>Target-side + Configuration Options</title> + <para> +There are no target-side configuration options related to the console +device. + </para> + </refsect1> + + <refsect1 id="synth-console-arguments"><title>Command Line Arguments</title> + <para> +The console device does not use any command-line arguments. + </para> + </refsect1> + + <refsect1 id="synth-console-hooks"><title>Hooks</title> + <para> +The console device does not provide any hooks. + </para> + </refsect1> + + <refsect1><title>Additional Tcl Procedures</title> + <para> +The console device does not provide any additional Tcl procedures that +can be used by other scripts. </para> </refsect1> @@ -315,7 +1286,7 @@ behaviour of the final system, not the d #include <cyg/hal/hal_io.h </funcsynopsisinfo> <funcprototype> - <funcdef>int <function>cyg_hal_sys_xyz</function></funcdef> + <funcdef>int <function>cyg_hal_sys_xyzzy</function></funcdef> <varargs> </funcprototype> </funcsynopsis> @@ -410,6 +1381,1179 @@ GNU C library sources. </refentry> <!-- }}} --> +<!-- {{{ New devices - target-side --> + +<refentry id="synth-new-target"> + <refmeta> + <refentrytitle>Writing New Devices - target</refentrytitle> + </refmeta> + <refnamediv> + <refname>Writing New Devices</refname> + <refpurpose>extending the synthetic target, target-side</refpurpose> + </refnamediv> + + <refsynopsisdiv> + <funcsynopsis> + <funcsynopsisinfo> +#include <cyg/hal/hal_io.h + </funcsynopsisinfo> + + <funcprototype> + <funcdef>int <function>synth_auxiliary_instantiate</function></funcdef> + <paramdef>const char* <parameter>package</parameter></paramdef> + <paramdef>const char* <parameter>version</parameter></paramdef> + <paramdef>const char* <parameter>device</parameter></paramdef> + <paramdef>const char* <parameter>instance</parameter></paramdef> + <paramdef>const char* <parameter>data</parameter></paramdef> + </funcprototype> + <funcprototype> + <funcdef>void <function>synth_auxiliary_xchgmsg</function></funcdef> + <paramdef>int <parameter>device_id</parameter></paramdef> + <paramdef>int <parameter>request</parameter></paramdef> + <paramdef>int <parameter>arg1</parameter></paramdef> + <paramdef>int <parameter>arg2</parameter></paramdef> + <paramdef>const unsigned char* <parameter>txdata</parameter></paramdef> + <paramdef>int <parameter>txlen</parameter></paramdef> + <paramdef>int* <parameter>reply</parameter></paramdef> + <paramdef>unsigned char* <parameter>rxdata</parameter></paramdef> + <paramdef>int* <parameter>rxlen</parameter></paramdef> + <paramdef>int <parameter>max_rxlen</parameter></paramdef> + </funcprototype> + </funcsynopsis> + </refsynopsisdiv> + + <refsect1 id="synth-new-target-description"><title>Description</title> + <para> +In some ways writing a device driver for the synthetic target is very +similar to writing one for a real target. Obviously it has to provide +the standard interface for that class of device, so for example an +ethernet device has to provide <function>can_send</function>, +<function>send</function>, <function>recv</function> and similar +functions. Many devices will involve interrupts, so the driver +contains ISR and DSR functions and will call +<function>cyg_drv_interrupt_create</function>, +<function>cyg_drv_interrupt_acknowledge</function>, and related +functions. + </para> + <para> +In other ways writing a device driver for the synthetic target is very +different. Usually the driver will not have any direct access to the +underlying hardware. In fact for some devices the I/O may not involve +real hardware, instead everything is emulated by widgets on the +graphical display. Therefore the driver cannot just peek and poke +device registers, instead it must interact with host-side code by +exchanging message. The synthetic target HAL provides a function +<function>synth_auxiliary_xchgmsg</function> for this purpose. + </para> + <para> +Initialization of a synthetic target device driver is also very +different. On real targets the device hardware already exists when the +driver's initialization routine runs. On the synthetic target it is +first necessary to instantiate the device inside the I/O auxiliary, by +a call to <function>synth_auxiliary_instantiate</function>. That +function performs a special message exchange with the I/O auxiliary, +causing it to load a Tcl script for the desired type of device and run +an instantiation procedure within that script. + </para> + <para> +Use of the I/O auxiliary is optional: if the user does not specify +<option>--io</option> on the command line then the auxiliary will not +be started and hence most I/O operations will not be possible. Device +drivers should allow for this possibility, for example by just +discarding any data that gets written. The HAL exports a flag +<varname>synth_auxiliary_running</varname> which should be checked. + </para> + </refsect1> + + <refsect1 id="synth-new-target-instantiate"><title>Instantiating a Device</title> + <para> +Device instantiation should happen during the C++ prioritized static +constructor phase of system initialization, before control switches to +<function>cyg_user_start</function> and general application code. This +ensures that there is a clearly defined point at which the I/O +auxiliary knows that all required devices have been loaded. It can +then perform various consistency checks and clean-ups, run the user's +<filename>mainrc.tcl</filename> script, and make the main window +visible. + </para> + <para> +For standard devices generic eCos I/O code will call the device +initialization routines at the right time, iterating through the +<varname>DEVTAB</varname> table in a static constructor. The same +holds for network devices and file systems. For more custom devices +code like the following can be used: + </para> + <programlisting> +#include <cyg/infra/cyg_type.h> +class mydev_init { + public: + mydev_init() { + … + } +}; +static mydev_init mydev_init_object CYGBLD_ATTRIB_INIT_PRI(CYG_INIT_IO); +</programlisting> + <para> +Some care has to be taken because the object +<varname>mydev_init_object</varname> will typically not be referenced +by other code, and hence may get eliminated at link-time. If the code +is part of an eCos package then problems can be avoided by putting the +relevant file in <filename>libextras.a</filename>: + </para> + <programlisting> +cdl_package CYGPKG_DEVS_MINE { + … + compile -library=libextras.a init.cxx +} +</programlisting> + <para> +For devices inside application code the same can be achieved by +linking the relevant module as a <filename>.o</filename> file rather +than putting it in a <filename>.a</filename> library. + </para> + <para> +In the device initialization routine the main operation is a call to +<function>synth_auxiliary_instantiate</function>. This takes five +arguments, all of which should be strings: + </para> + <variablelist> + <varlistentry> + <term><varname>package</varname></term> + <listitem><para> +For device drivers which are eCos packages this should be a directory +path relative to the eCos repository, for example +<literal>devs/eth/synth/ecosynth</literal>. This will allow the I/O +auxiliary to find the various host-side support files for this package +within the install tree. If the device is application-specific and not +part of an eCos package then a NULL pointer can be used, causing the +I/O auxiliary to search for the support files in the current directory +and then in <filename class="directory">~/.ecos/synth</filename> +instead. + </para></listitem> + </varlistentry> + <varlistentry> + <term><varname>version</varname></term> + <listitem><para> +For eCos packages this argument should be the version of the package +that is being used, for example <literal>current</literal>. A simple +way to get this version is to use the +<function>SYNTH_MAKESTRING</function> macro on the package name. +If the device is application-specific then a NULL pointer should be +used. + </para></listitem> + </varlistentry> + <varlistentry> + <term><varname>device</varname></term> + <listitem><para> +This argument specifies the type of device being instantiated, for +example <literal>ethernet</literal>. More specifically the I/O +auxiliary will append a <filename>.tcl</filename> suffix, giving +the name of a Tcl script that will handle all I/O requests for the +device. If the application requires several instances of a type +of device then the script will only be loaded once, but the script +will contain an instantiation procedure that will be called for each +device instance. + </para></listitem> + </varlistentry> + <varlistentry> + <term><varname>instance</varname></term> + <listitem><para> +If it is possible to have multiple instances of a device then this +argument identifies the particular instance, for example +<literal>eth0</literal> or <literal>eth1</literal>. Otherwise a NULL +pointer can be used. + </para></listitem> + </varlistentry> + <varlistentry> + <term><varname>data</varname></term> + <listitem><para> +This argument can be used to pass additional initialization data from +eCos to the host-side support. This is useful for devices where eCos +configury must control certain aspects of the device, rather than +host-side configury such as the target definition file, because eCos +has compile-time dependencies on some or all of the relevant options. +An example might be an emulated frame buffer where eCos has been +statically configured for a particular screen size, orientation and +depth. There is no fixed format for this string, it will be +interpreted only by the device-specific host-side Tcl script. However +the string length should be limited to a couple of hundred bytes to +avoid possible buffer overflow problems. + </para></listitem> + </varlistentry> + </variablelist> + <para> +Typical usage would look like: + </para> + <programlisting> + if (!synth_auxiliary_running) { + return; + } + id = synth_auxiliary_instantiate("devs/eth/synth/ecosynth", + SYNTH_MAKESTRING(CYGPKG_DEVS_ETH_ECOSYNTH), + "ethernet", + "eth0", + (const char*) 0); +</programlisting> + <para> +The return value will be a device identifier which can be used for +subsequent calls to <function>synth_auxiliary_xchgmsg</function>. If +the device could not be instantiated then <literal>-1</literal> will +be returned. It is the responsibility of the host-side software to +issue suitable diagnostics explaining what went wrong, so normally the +target-side code should fail silently. + </para> + <para> +Once the desired device has been instantiated, often it will be +necessary to do some additional initialization by a message exchange. +For example an ethernet device might need information from the +host-side about the MAC address, the <link +linkend="synth-new-target-interrupts">interrupt vector</link>, and +whether or not multicasting is supported. + </para> + </refsect1> + + <refsect1 id="synth-new-target-xchgmsg"><title>Communicating with a Device</title> + <para> +Once a device has been instantiated it is possible to perform I/O by +sending messages to the appropriate Tcl script running inside the +auxiliary, and optionally getting back replies. I/O operations are +always initiated by the eCos target-side, it is not possible for the +host-side software to initiate data transfers. However the host-side +can raise interrupts, and the interrupt handler inside the target can +then exchange one or more messages with the host. + </para> + <para> +There is a single function to perform I/O operations, +<function>synth_auxiliary_xchgmsg</function>. This takes the following +arguments: + </para> + <variablelist> + <varlistentry> + <term><varname>device_id</varname></term> + <listitem><para> +This should be one of the identifiers returned by a previous +call to <function>synth_auxiliary_instantiate</function>, specifying the +particular device which should perform some I/O. + </para></listitem> + </varlistentry> + <varlistentry> + <term><varname>request</varname></term> + <listitem><para> +Request are just signed 32-bit integers that identify the particular +I/O operation being requested. There is no fixed set of codes, instead +each type of device can define its own. + </para></listitem> + </varlistentry> + <varlistentry> + <term><varname>arg1</varname></term> + <term><varname>arg2</varname></term> + <listitem><para> +For some requests it is convenient to pass one or two additional +parameters alongside the request code. For example an ethernet device +could define a multicast-all request, with <varname>arg1</varname> +controlling whether this mode should be enabled or disabled. Both +<varname>arg1</varname> and <varname>arg2</varname> should be signed +32-bit integers, and their values are interpreted only by the +device-specific Tcl script. + </para></listitem> + </varlistentry> + <varlistentry> + <term><varname>txdata</varname></term> + <term><varname>txlen</varname></term> + <listitem><para> +Some I/O operations may involve sending additional data, for example +an ethernet packet. Alternatively a control operation may require many +more parameters than can easily be encoded in <varname>arg1</varname> +and <varname>arg2</varname>, so those parameters have to be placed in +a suitable buffer and extracted at the other end. +<varname>txdata</varname> is an arbitrary buffer of +<varname>txlen</varname> bytes that should be sent to the host-side. +There is no specific upper bound on the number of bytes that can be +sent, but usually it is a good idea to allocate the transmit buffer +statically and keep transfers down to at most several kilobytes. + </para></listitem> + </varlistentry> + <varlistentry> + <term><varname>reply</varname></term> + <listitem><para> +If the host-side is expected to send a reply message then +<varname>reply</varname> should be a pointer to an integer variable +and will be updated with a reply code, a simple 32-bit integer. The +synthetic target HAL code assumes that the host-side and target-side +agree on the protocol being used: if the host-side will not send a +reply to this message then the <varname>reply</varname> argument +should be a NULL pointer; otherwise the host-side must always send +a reply code and the <varname>reply</varname> argument must be valid. + </para></listitem> + </varlistentry> + <varlistentry> + <term><varname>rxdata</varname></term> + <term><varname>rxlen</varname></term> + <listitem><para> +Some operations may involve additional data coming from the host-side, +for example an incoming ethernet packet. <varname>rxdata</varname> +should be a suitably-sized buffer, and <varname>rxlen</varname> a +pointer to an integer variable that will end up containing the number +of bytes that were actually received. These arguments will only be +used if the host-side is expected to send a reply and hence the +<varname>reply</varname> argument was not NULL. + </para></listitem> + </varlistentry> + <varlistentry> + <term><varname>max_rxlen</varname></term> + <listitem><para> +If a reply to this message is expected and that reply may involve +additional data, <varname>max_rxlen</varname> limits the size of that +reply. In other words, it corresponds to the size of the +<varname>rxdata</varname> buffer. + </para></listitem> + </varlistentry> + </variablelist> + <para> +Most I/O operations involve only some of the arguments. For example +transmitting an ethernet packet would use the +<varname>request</varname>, <varname>txdata</varname> and +<varname>txlen</varname> fields (in addition to +<varname>device_id</varname> which is always required), but would not +involve <varname>arg1</varname> or <varname>arg2</varname> and no +reply would be expected. Receiving an ethernet packet would involve +<varname>request</varname>, <varname>rxdata</varname>, +<varname>rxlen</varname> and <varname>max_rxlen</varname>; in addition +<varname>reply</varname> is needed to get any reply from the host-side +at all, and could be used to indicate whether or not any more packets +are buffered up. A control operation such as enabling multicast mode +would involve <varname>request</varname> and <varname>arg1</varname>, +but none of the remaining arguments. + </para> + </refsect1> + + <refsect1 id="synth-new-target-interrupts"><title>Interrupt Handling</title> + <para> +Interrupt handling in the synthetic target is much the same as on a +real target. An interrupt object is created using +<function>cyg_drv_interrupt_create</function>, attached, and unmasked. +The emulated device - in other words the Tcl script running inside the +I/O auxiliary - can raise an interrupt. Subject to interrupts being +disabled and the appropriate vector being masked, the system will +invoke the specified ISR function. The synthetic target HAL +implementation does have some limitations: there is no support for +nested interrupts, interrupt priorities, or a separate interrupt +stack. Supporting those might be appropriate when targetting a +simulator that attempts to model real hardware accurately, but not for +the simple emulation provided by the synthetic target. + </para> + <para> +Of course the actual implementation of the ISR and DSR functions will +be rather different for a synthetic target device driver. For real +hardware the device driver will interact with the device by reading +and writing device registers, managing DMA engines, and the like. A +synthetic target driver will instead call +<function>synth_auxiliary_xchgmsg</function> to perform the I/O +operations. + </para> + <para> +There is one other significant difference between interrupt handling +on the synthetic target and on real hardware. Usually the eCos code +will know which interrupt vectors are used for which devices. That +information is fixed when the target hardware is designed. With the +synthetic target interrupt vectors are assigned to devices on the host +side, either via the target definition file or dynamically when the +device is instantiated. Therefore the initialization code for a +target-side device driver will need to request interrupt vector +information from the host-side, via a message exchange. Such interrupt +vectors will be in the range 1 to 31 inclusive, with interrupt 0 being +reserved for the real-time clock. + </para> + </refsect1> + +</refentry> + +<!-- }}} --> +<!-- {{{ New devices - host-side --> + +<refentry id="synth-new-host"> + <refmeta> + <refentrytitle>Writing New Devices - host</refentrytitle> + </refmeta> + <refnamediv> + <refname>Writing New Devices</refname> + <refpurpose>extending the synthetic target, host-side</refpurpose> + </refnamediv> + + <refsect1 id="synth-new-host-description"><title>Description</title> + <para> +On the host-side adding a new device means writing a Tcl/Tk script +that will handle instantiation and subsequent requests from the +target-side. These scripts all run in the same full interpreter, +extended with various commands provided by the main I/O auxiliary +code, and running in an overall GUI framework. Some knowledge of +programming with Tcl/Tk is required to implement host-side device +support. + </para> + <para> +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 +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 +advanced emulation could organize the buttons with the right layout, +perhaps even matching the colour scheme, the shapes, and the relative +sizes. With other devices it may be necessary for the Tcl script to +interact with an external program, because the required functionality +cannot easily be accessed from a Tcl script. For example interacting +with a raw ethernet device involves some <function>ioctl</function> +calls, which is easier to do in a C program. Therefore the +<filename>ethernet.tcl</filename> script which implements the +host-side ethernet support spawns a separate program +<filename>rawether</filename>, written in C, that performs the +low-level I/O. Raw ethernet access usually also requires root +privileges, and running a small program <filename>rawether</filename> +with such privileges is somewhat less of a security risk than the +whole eCos application, the I/O auxiliary, and various dynamically +loaded Tcl scripts. + </para> + <para> +Because all scripts run in a single interpreter, some care has +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 +namespace, so for example the <filename>ethernet.tcl</filename> script +creates a namespace <varname>ethernet::</varname> and all variables +and procedures reside in this namespace. Similarly the I/O auxiliary +itself makes use of a <varname>synth::</varname> namespace. + </para> + </refsect1> + + <refsect1 id="synth-new-host-build"><title>Building and Installation</title> + <para> +When an eCos device driver or application code instantiates a device, +the I/O auxiliary will attempt to load a matching Tcl script. The +third argument to <function>synth_auxiliary_instantiate</function> +specifies the type of device, for example <literal>ethernet</literal>, +and the I/O auxiliary will append a <filename>.tcl</filename> suffix +and look for a script <filename>ethernet.tcl</filename>. + </para> + <para> +If the device being instantiated is application-specific rather than +part of an eCos package, the I/O auxiliary will look first in the +current directory, then in <filename +class="directory">~/.ecos/synth</filename>. If it is part of an eCos +package then the auxiliary will expect to find the Tcl script and any +support files below <filename +class="directory">libexec/ecos</filename> in the install tree - note +that the same install tree must be used for the I/O auxiliary itself +and for any device driver support. The directory hierarchy below +<filename class="directory">libexec/ecos</filename> matches the +structure of the eCos repository, allowing multiple versions of a +package to be installed to allow for incompatible protocol changes. + </para> + <para> +The preferred way to build host-side software is to use +<command>autoconf</command> and <command>automake</command>. Usually +this involves little more than copying the +<filename>acinclude.m4</filename>, <filename>configure.in</filename> +and <filename>Makefile.am</filename> files from an existing package, +for example the synthetic target ethernet driver, and then making +minor edits. In <filename>acinclude.m4</filename> it may be necessary +to adjust the path to the root of the repository. +<filename>configure.in</filename> may require a similar change, and +the <function>AC_INIT</function> macro invocation will have to be +changed to match one of the files in the new package. A critical macro +in this file is <filename>ECOS_PACKAGE_DIRS</filename> which will set +up the correct install directory. <filename>Makefile.am</filename> may +require some more changes, for example to specify the data files that +should be installed (including the Tcl script). These files should +then be processed using <command>aclocal</command>, +<command>autoconf</command> and <command>automake</command> in that +order. Actually building the software then just involves +<command>configure</command>, <command>make</command> and +<command>make install</command>, as per the instructions in the +toplevel <filename>README.host</filename> file. + </para> + <para> +To assist developers, if the environment variable +<envar>ECOSYNTH_DEVEL</envar> is set then a slightly different +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 +source tree, and if the script there is more recent than the installed +version it will be used in preference. This allows developers to +modify the master copy without having to run <command>make +install</command> all the time. + </para> + <para> +If a script needs to know where it has been installed it can examine +the Tcl variable <varname>synth::device_install_dir</varname> . This +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 +variable. + </para> + </refsect1> + + <refsect1 id="synth-new-host-instantiation"><title>Instantiation</title> + <para> +The I/O auxiliary will <command>source</command> the device-specific +Tcl script when the eCos application first attempts to instantiate a +device of that type. The script should return a procedure that will be +invoked to instantiate a device. + </para> + <programlisting> +namespace eval ethernet { + … + proc instantiate { id instance data } { + … + return ethernet::handle_request + } +} +return ethernet::instantiate +</programlisting> + <para> +The <varname>id</varname> argument is a unique identifier for this +device instance. It will also be supplied on subsequent calls to the +request handler, and will match the return value of +<function>synth_auxiliary_instantiate</function> on the target side. A +common use for this value is as an array index to support multiple +instances of this types of device. The <varname>instance</varname> and +<varname>data</varname> arguments match the corresponding arguments to +<function>synth_auxiliary_instantiate</function> on the target side, so +a typical value for <varname>instance</varname> would be +<literal>eth0</literal>, and <varname>data</varname> is used to pass +arbitrary initialization parameters from target to host. + </para> + <para> +The actual work done by the instantiation procedure is obviously +device-specific. It may involve allocating an <link +linkend="synth-new-host-interrupts">interrupt vector</link>, adding a +device-specific subwindow to the display, opening a real Linux device, +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 +the above. + </para> + <para> +If the device is successfully instantiated then the return value +should be a handler for subsequent I/O requests. Otherwise the return +value should be an empty string, and on the target-side the +<function>synth_auxiliary_instantiate</function> call will return +<literal>-1</literal>. The script is responsible for providing +<link linkend="synth-new-host-output">diagnostics</link> explaining +why the device could not be instantiated. + </para> + </refsect1> + + <refsect1 id="synth-new-host-requests"><title>Handling Requests</title> + <para> +When the target-side calls +<function>synth_auxiliary_xchgmsg</function>, the I/O auxiliary will +end up calling the request handler for the appropriate device instance +returned during instantiation: + </para> + <programlisting> +namespace eval ethernet { + … + proc handle_request { id request arg1 arg2 txdata txlen max_rxlen } { + … + if { <some condition> } { + synth::send_reply <error code> 0 "" + return + } + … + synth::send_reply <reply code> $packet_len $packet + } + … +} +</programlisting> + <para> +The <varname>id</varname> argument is the same device id that was +passed to the instantiate function, and is typically used as an array +index to access per-device data. The <varname>request</varname>, +<varname>arg1</varname>, <varname>arg2</varname>, and +<varname>max_rxlen</varname> are the same values that were passed to +<function>synth_auxiliary_xchgmsg</function> on the target-side, +although since this is a Tcl script obviously the numbers have been +converted to strings. The <varname>txdata</varname> buffer is raw data +as transmitted by the target, or an empty string if the I/O operation +does not involve any additional data. The Tcl procedures +<command>binary scan</command>, <command>string index</command> and +<command>string range</command> may be found especially useful when +manipulating this buffer. <varname>txlen</varname> is provided for +convenience, although <command>string length $txdata</command> would +give the same information. + </para> + <para> +The code for actually processing the request is of course device +specific. If the target does not expect a reply then the request +handler should just return when finished. If a reply is expected then +there should be a call to <command>synth::send_reply</command>. The +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 +of the reply data, and the third argument is the reply data itself. +For some devices the Tcl procedure <command>binary format</command> +may prove useful. If the reply involves just a code and no additional +data, the second and third arguments should be <literal>0</literal> +and an empty string respectively. + </para> + <para> +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 +target-side expects, will all be detected by the I/O auxiliary and +result in run-time error messages. + </para> + <para> +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 +example because some I/O operation has completed, then an interrupt +should be raised. + </para> + </refsect1> + + <refsect1 id="synth-new-host-interrupts"><title>Interrupts</title> + <para> +The I/O auxiliary provides a number of procedures for interrupt +handling. + </para> + <programlisting> +synth::interrupt_allocate <name> +synth::interrupt_get_max +synth::interrupt_get_devicename <vector> +synth::interrupt_raise <vector> +</programlisting> + <para> +<command>synth::interrupt_allocate</command> is normally called during +device instantiation, and returns the next free interrupt vector. This +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 +vector. Interrupt vector <literal>0</literal> is used within the +target-side code for the real-time clock, so the allocated vectors +will start at <literal>1</literal>. The argument identifies the +device, for example <literal>eth0</literal>. This is not actually used +internally, but can be accessed by user-initialization scripts that +provide some sort of interrupt monitoring facility (typically via the +<literal>interrupt</literal> <link +linkend="synth-new-host-hooks">hook</link>). It is possible for a +single device to allocate multiple interrupt vectors, but the +synthetic target supports a maximum of 32 such vectors. + </para> + <para> +<command>synth::interrupt_get_max</command> returns the highest +interrupt vector that has been allocated, or <literal>0</literal> if +there have been no calls to +<command>synth::interrupt_allocate</command>. +<command>synth::interrupt_get_devicename</command> returns the string +that was passed to <command>synth::interrupt_allocate</command> when +the vector was allocated. + </para> + <para> +<command>synth::interrupt_raise</command> can be called any time after +initialization. The argument should be the vector returned by +<command>synth::interrupt_allocate</command> for this device. It will +activate the normal eCos interrupt handling mechanism so, subject to +interrupts being enabled and this particular interrupt not being +masked out, the appropriate ISR will run. + </para> + <note><para> +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 +devices effectively depends on the order in which the eCos devices get +initialized, and that may change if the eCos application is rebuilt. A +future extension may allow devices to allocate specific vectors, thus +making things more deterministic. However that will introduce new +problems, in particular the code will have to start worrying about +requests for vectors that have already been allocated. + </para></note> + </refsect1> + + <refsect1 id="synth-new-host-args"><title>Flags and Command Line Arguments</title> + <para> +The generic I/O auxiliary code will process the standard command line +arguments, and will set various flag variables accordingly. Some of +these should be checked by device-specific scripts. + </para> + <variablelist> + <varlistentry> + <term><varname>synth::flag_gui</varname></term> + <listitem><para> +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 +layout are only available in graphical mode. + </para> + <programlisting> + if { $synth::flag_gui } { + … + } +</programlisting></listitem> + </varlistentry> + <varlistentry> + <term><varname>synth::flag_verbose</varname></term> + <listitem><para> +The user has requested additional information during startup. Each +device driver can decide how much additional information, if any, +should be produced. + </para></listitem> + </varlistentry> + <varlistentry> + <term><varname>synth::flag_keep_going</varname></term> + <listitem><para> +The user has specified <option>-k</option> or +<option>--keep-going</option>, so even if an error occurs the I/O +auxiliary and the various device driver scripts should continue running +if at all possible. Diagnostics should still be generated. + </para></listitem> + </varlistentry> + </variablelist> + <para> +Some scripts may want to support additional command line arguments. +This facility should be used with care since there is no way to +prevent two different scripts from trying to use the same argument. +The following Tcl procedures are available: + </para> + <programlisting> +synth::argv_defined <name> +synth::argv_get_value <name> +</programlisting> + <para> +<command>synth::argv_defined</command> returns a boolean to indicate +whether or not a particular argument is present. If the argument is +the name part of a name/value pair, an <literal>=</literal> character +should be appended. Typical uses might be: + </para> + <programlisting> + if { [synth::argv_defined "-o13"] } { + … + } + + if { [synth::argv_defined "-mark="] } { + … + } +</programlisting> + <para> +The first call checks for a flag <literal>-o13</literal> or +<literal>--o13</literal> - the code treats options with single and +double hyphens interchangeably. The second call checks for an argument +of the form <literal>-mark=<value></literal> or a pair of +arguments <literal>-mark <value></literal>. The value part of a +name/value pair can be obtained using +<command>synth::argv_get_value</command>; + </para> + <programlisting> + variable speed 1 + if { [synth::argv_defined "-mark="] } { + set mark [synth::argv_get_value "-mark="] + if { ![string is integer $mark] || ($mark < 1) || ($mark > 9) } { + <issue diagnostic> + } else { + set speed $mark + } + } +</programlisting> + <para> +<command>synth::argv_get_value</command> should only be used after a +successful call to <command>synth::argv_defined</command>. +At present there is no support for some advanced forms of command line +argument processing. For example it is not possible to repeat a +certain option such as <option>-v</option> or +<option>--verbose</option>, with each occurrence increasing the level +of verbosity. + </para> + <para> +If a script is going to have its own set of command-line arguments +then it should give appropriate details if the user specifies +<option>--help</option>. This involves a hook function: + </para> + <programlisting> +namespace eval my_device { + proc help_hook { } { + puts " -o13 : activate the omega 13 device" + puts " -mark <speed> : set speed. Valid values are 1 to 9." + } + + synth::hook_add "help" my_device::help_hook +} +</programlisting> + </refsect1> + + <refsect1 id="synth-new-host-tdf"><title>The Target Definition File</title> + <para> +Most device scripts will want to check entries in the target +definition file for run-time configuration information. The Tcl +procedures for this are as follows: + </para> + <programlisting> +synth::tdf_has_device <name> +synth::tdf_get_devices +synth::tdf_has_option <devname> <option> +synth::tdf_get_option <devname> <option> +synth::tdf_get_options <devname> <option> +synth::tdf_get_all_options <devname> +</programlisting> + <para> +<command>synth::tdf_has_device</command> can be used to check whether +or not the target definition file had an entry +<literal>synth_device <name></literal>. Usually the name +will match the type of device, so the +<filename>console.tcl</filename> script will look for a target +definition file entry <literal>console</literal>. +<command>synth::tdf_get_devices</command> returns a list of all +device entries in the target definition file. + </para> + <para> +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. +<command>synth::tdf_has_option</command> just checks for the presence, +returning a boolean: + </para> + <programlisting> + if { [synth::tdf_has_option "console" "appearance"] } { + … + } +</programlisting> + <para> +<command>synth::tdf_get_option</command> returns a list of all the +arguments for a given option. For example, if the target definition +file contains an entry: + </para> + <programlisting> +synth_device console { + appearance -foreground white -background black + filter trace {^TRACE:.*} -foreground HotPink1 -hide 1 + filter xyzzy {.*xyzzy.*} -foreground PapayaWhip +} +</programlisting> + <para> +A call +<command>synth::tdf_get_option console appearance</command> +will return the list <literal>{-foreground white -background +black}</literal>. This list can be manipulated using standard Tcl routines +such as <command>llength</command> and <command>lindex</command>. Some +options can occur multiple times in one entry, for example +<option>filter</option> in the <literal>console</literal> entry. +<command>synth::tdf_get_options</command> returns a list of lists, +with one entry for each option occurrence. +<command>synth::tdf_get_all_options</command> returns a list of lists +of all options. This time each entry will include the option name as +well. + </para> + <para> +The I/O auxiliary will not issue warnings about entries in the target +definition file for devices which were not loaded, unless the +<option>-v</option> or <option>--verbose</option> command line +argument was used. This makes it easier to use a single target +definition file for different applications. However the auxiliary will +issue warnings about options within an entry that were ignored, +because often these indicate a typing mistake of some sort. Hence a +script should always call <command>synth::tdf_has_option</command>, +<command>synth:;tdf_get_option</command> or +<command>synth::tdf_get_options</command> for all valid options, even +if some of the options preclude the use of others. + </para> + </refsect1> + + <refsect1 id="synth-new-host-hooks"><title>Hooks</title> + <para> +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 +further I/O. This is supported using hooks: + </para> + <programlisting> +namespace eval my_device { + … + proc handle_ecos_exit { arg_list } { + … + } + synth::hook_add "ecos_exit" my_device::handle_ecos_exit +} +</programlisting> + <para> +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 +user initialization scripts that want to monitor some types of I/O. +The available Tcl procedures for manipulating hooks are: + </para> + <programlisting> +synth::hook_define <name> +synth::hook_defined <name> +synth::hook_add <name> <function> +synth::hook_call <name> <args> +</programlisting> + <para> +<command>synth::hook_define</command> creates a new hook with the +specified name. This hook must not already exist. +<command>synth::hook_defined</command> can be used to check for the +existence of a hook. <command>synth::hook_add</command> allows other +scripts to register a callback function for this hook, and +<command>synth::hook_call</command> allows the owner script to invoke +all such callback functions. A hook must already be defined before a +callback can be attached. Therefore typically device scripts will only +use standard hooks and their own hooks, not hooks created by some +other device, because the order of device initialization is not +sufficiently defined. User scripts run from +<filename>mainrc.tcl</filename> can use any hooks that have been +defined. + </para> + <para> +<command>synth::hook_call</command> takes an arbitrary list of +arguments, for example: + </para> + <programlisting> + synth::hook_call "ethernet_rx" "eth0" $packet +</programlisting> + <para> +The callback function will always be invoked with a single argument, +a list of the arguments that were passed to +<command>synth::hook_call</command>: + </para> + <programlisting> + proc rx_callback { arg_list } { + set device [lindex $arg_list 0] + set packet [lindex $arg_list 1] + } +</programlisting> + <para> +Although it might seem more appropriate to use Tcl's +<command>eval</command> procedure and have the callback functions +invoked with the right number of arguments rather than a single list, +that would cause serious problems if any of the data contained special +characters such as <literal>[</literal> or <literal>$</literal>. The +current implementation of hooks avoids such problems, at the cost of +minor inconvenience when writing callbacks. + </para> + <para> +A number of hooks are defined as standard. Some devices will add +additional hooks, and the device-specific documentation should be +consulted for those. User scripts can add their own hooks if desired. + </para> + <variablelist> + <varlistentry> + <term><literal>exit</literal></term> + <listitem><para> +This hook is called just before the I/O auxiliary exits. Hence it +provides much the same functionality as <function>atexit</function> in +C programs. The argument list passed to the callback function will be +empty. + </para></listitem> + </varlistentry> + <varlistentry> + <term><literal>ecos_exit</literal></term> + <listitem><para> +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 +running then there is no point in raising interrupts or storing +incoming packets. The callback argument list will be empty. + </para></listitem> + </varlistentry> + <varlistentry> + <term><literal>ecos_initialized</literal></term> + <listitem><para> +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 +instantiated. A script could now check how many instances there are of +a given type of device, for example ethernet devices, and create a +little monitor window showing traffic on all the devices. The +<literal>ecos_initialized</literal> callbacks will be run just before +the user's <filename>mainrc.tcl</filename> script. The callback +argument list will be empty. + </para></listitem> + </varlistentry> + <varlistentry> + <term><literal>help</literal></term> + <listitem><para> +This hook is also invoked once static constructors have been run, but +only if the user specified <option>-h</option> or +<option>--help</option>. Any scripts that add their own command line +arguments should add a callback to this hook which outputs details of +the additional arguments. The callback argument list will be empty. + </para></listitem> + </varlistentry> + <varlistentry> + <term><literal>interrupt</literal></term> + <listitem><para> +Whenever a device calls <command>synth::interrupt_raise</command> the +<literal>interrupt</literal> hook will be called with a single +argument, the interrupt vector. The main use for this is to allow +user scripts to monitor interrupt traffic. + </para></listitem> + </varlistentry> + </variablelist> + </refsect1> + + <refsect1 id="synth-new-host-output"><title>Output and Filters</title> + <para> +Scripts can use conventional facilities for sending text output to the +user, for example calling <command>puts</command> or directly +manipulating the central text widget +<varname>.main.centre.text</varname>. However in nearly all cases it +is better to use output facilities provided by the I/O auxiliary +itself: + </para> + <programlisting> +synth::report <msg> +synth::report_warning <msg> +synth::report_error <msg> +synth::internal_error <msg> +synth::output <msg> <filter> +</programlisting> + <para> +<command>synth::report</command> is intended for messages related to +the operation of the I/O auxiliary itself, especially additional +output resulting from <option>-v</option> or +<option>--verbose</option>. If running in text mode the output will go +to standard output. If running in graphical mode the output will go to +the central text window. In both modes, use of <option>-l</option> or +<option>--logfile</option> will modify the behaviour. + </para> + <para> +<command>synth::report_warning</command>, +<command>synth::report_error</command> and +<command>synth::internal_error</command> have the obvious meaning, +including prepending strings such as <literal>Warning:</literal> and +<literal>Error:</literal>. When the eCos application informs the I/O +auxiliary that all static constructors have run, if at that point +there have been any calls to <command>synth::error</command> then the +I/O auxiliary will exit. This can be suppressed with command line +arguments <option>-k</option> or <option>--keep-going</option>. +<command>synth::internal_error</command> will output some information +about the current state of the I/O auxiliary and then exit +immediately. Of course it should never be necessary to call this +function. + </para> + <para> +<command>synth::output</command> is the main routine for outputting +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 +be used to control the appearance of this output. A typical use would +be: + </para> + <programlisting> + synth::output $line "console" +</programlisting> + <para> +This outputs a single line of text using the +<literal>console</literal> filter. If running in graphical mode the +default appearance of this text can be modified with the +<option>appearance</option> option in the +<command>synth_device console</command> entry of the target +definition file. The <guimenuitem>System filters</guimenuitem> menu +option can be used to change the appearance at run-time. + </para> + <para> +Filters should be created before they are used. The procedures +available for this are: + </para> + <programlisting> +synth::filter_exists <name> +synth::filter_get_list +synth::filter_add <name> [options] +synth::filter_parse_options <options> <parsed_options> <message> +synth::filter_add_parsed <name> <parsed_options> +</programlisting> + <para> +<command>synth::filter_exists</command> can be used to check whether +or not a particular filter already exists: creating two filters with +the same name is not allowed. +<command>synth::filter_get_list</command> returns a list of the +current known filters. <command>synth::filter_add</command> can be +used to create a new filter. The first argument names the new filter, +and the remaining arguments control the initial appearance. A typical +use might be: + </para> + <programlisting> + synth::filter_add "my_device_tx" -foreground yellow -hide 1 +</programlisting> + <para> +It is assumed that the supplied arguments are valid, which typically +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 +I/O auxiliary provides a parsing utility. Typical usage would be: + </para> + <programlisting> + array set parsed_options [list] + set message "" + if { ![synth::filter_parse_options $console_appearance parsed_options message] } { + synth::report_error \ + "Invalid entry in target definition file $synth::target_definition\ + \n synth_device \"console\", entry \"appearance\"\n$message" + } else { + synth::filter_add_parsed "console" parsed_options + } +</programlisting> + <para> +On success <varname>parsed_options</varname> will be updated with an +internal representation of the desired appearance, which can then be +used in a call to <command>synth::filter_add_parsed</command>. On +failure <varname>message</varname> will be updated with details of the +parsing error that occurred. + </para> + </refsect1> + + <refsect1 id="synth-new-host-gui"><title>The Graphical Interface</title> + <para> +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 +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, +or even creating entire new toplevel windows. These may be simple +monitor windows, displaying additional information about what is going +on in the system in a graphical format. Alternatively they may emulate +actual I/O operations, for example button widgets could be used to +emulate real physical buttons. + </para> + <para> +The I/O auxiliary does not provide many procedures related to the +graphical interface. Instead it is expected that scripts will just +update the widget hierarchy directly. + </para> + <informalfigure PgWide=1> + <mediaobject> + <imageobject> + <imagedata fileref="layout.gif" format="gif" Scalefit=1 Align="Center"> + </imageobject> + </mediaobject> + </informalfigure> + <para> +So adding a new item to the <guimenu>Help</guimenu> menu involves a +<command>.menubar.help add</command> operation with suitable +arguments. Adding a new button to the toolbar involves creating a +child window in <varname>.toolbar</varname> and packing it +appropriately. Scripts can create their own subwindows and then pack +it into one of <varname>.main.nw</varname>, +<varname>.main.n</varname>, <varname>.main.ne</varname>, +<varname>.main.w</varname>, <varname>.main.e</varname>, +<varname>.main.sw</varname>, <varname>.main.s</varname> or +<varname>.main.se</varname>. Normally the user should be allowed to +<link linkend="synth-gui-layout">control</link> this via the target +definition file. The central window <varname>.main.centre</varname> +should normally be left alone by other scripts since it gets used for +text output. + </para> + <para> +The following graphics-related utilities may be found useful: + </para> + <programlisting> +synth::load_image <image name> <filename> +synth::register_ballon_help <widget> <message> +synth::handle_help <URL> +</programlisting> + <para> +<command>synth::load_image</command> can be used to add a new image to +the current interpreter. If the specified file has a +<filename>.xbm</filename> extension then the image will be a +monochrome bitmap, otherwise it will be a colour image of some sort. +A boolean will be returned to indicate success or failure, and +suitable diagnostics will be generated if necessary. + </para> + <para> +<command>synth::register_balloon_help</command> provides balloon help +for a specific widget, usually a button on the toolbar. + </para> + <para> +<command>synth::handle_help</command> is a utility routine that can be +installed as the command for displaying online help, for example: + </para> + <programlisting> + .menubar.help add command -label "my device" -command \ + [list synth::handle_help "file://$path"] +</programlisting> + </refsect1> + +</refentry> + +<!-- }}} --> <!-- {{{ Porting --> <refentry id="synth-porting"> @@ -418,7 +2562,7 @@ GNU C library sources. </refmeta> <refnamediv> <refname>Porting</refname> - <refpurpose>The eCos synthetic target</refpurpose> + <refpurpose>Adding support for other hosts</refpurpose> </refnamediv> <refsect1 id="synth-porting-description"><title>Description</title> @@ -430,7 +2574,7 @@ straightforward, for example a port to L an x86. Porting to Unix or Unix-like operating systems other than Linux may be possible, but would involve more effort. Porting to a completely different operating system such as Windows would be very -difficult. The text below completes the eCos Porting Guide. +difficult. The text below complements the eCos Porting Guide. </para> </refsect1> @@ -445,28 +2589,28 @@ Most of the changes should be pretty obv processor some new data types will be needed in the <filename>basetype.h</filename> header file. It will also be necessary to update the toplevel <filename>ecos.db</filename> database with an -entry for the new HAL package, and a new target entry will be needed -as well. +entry for the new HAL package, and a new target entry will be needed. </para> <para> -Obviously a different processor will have different register sets -and calling conventions, so the code for saving and restoring thread +Obviously a different processor will have different register sets and +calling conventions, so the code for saving and restoring thread contexts and for implementing <function>setjmp</function> and <function>longjmp</function> will need to be updated. The exact way of -performing Linux system calls will also vary: on i386linux this -usually involves pushing some registers on the stack and then -executing an <literal>int 0x080</literal> trap instruction, but -on a different processor the arguments might be passed in registers -instead and certainly a different trap instruction will be used. The -startup code is also written in assembler, but needs to do little more -than jump to the main <function>linux_entry</function> function -provided by the architectural synthetic target HAL package. +performing Linux system calls will vary: on x86 linux this usually +involves pushing some registers on the stack and then executing an +<literal>int 0x080</literal> trap instruction, but on a different +processor the arguments might be passed in registers instead and +certainly a different trap instruction will be used. The startup code +is written in assembler, but needs to do little more than extract the +process' argument and environment variables and then jump to the main +<function>linux_entry</function> function provided by the +architectural synthetic target HAL package. </para> <para> The header file <filename>hal_io.h</filename> provided by the architectural HAL package provides various structure definitions, function prototypes, and macros related to system calls. These are -correct for i386linux, but there may be problems on other processors. +correct for x86 linux, but there may be problems on other processors. For example a structure field that is currently defined as a 32-bit number may in fact may be a 64-bit number instead. </para> @@ -484,7 +2628,10 @@ but usually eCos applications can and sh <para> Other HAL functionality such as interrupt handling, diagnostics, and the system clock are provided by the architectural HAL package and -should work on different processors with few if any changes. +should work on different processors with few if any changes. There may +be some problems in the code that interacts with the I/O auxiliary +because of lurking assumptions about endianness or the sizes of +various data types. </para> <para> When porting to other processors, a number of sources of information @@ -499,11 +2646,11 @@ provides the startup code and the system <refsect1 id="synth-porting-unix"><title>Other Unix Platforms</title> <para> Porting to a Unix or Unix-like operating system other than Linux would -be somewhat more involved. The first requirement involves toolchains: -the GNU compilers, gcc and g++, must definitely be used; use of other -GNU tools such as the linker may be needed as well, because eCos -depends on functionality such as prioritizing C++ static constructors, -and other linkers may not implement this or may implement it in a +be somewhat more involved. The first requirement is toolchains: the +GNU compilers, gcc and g++, must definitely be used; use of other GNU +tools such as the linker may be needed as well, because eCos depends +on functionality such as prioritizing C++ static constructors, and +other linkers may not implement this or may implement it in a different and incompatible way. A closely related requirement is the use of ELF format for binary executables: if the operating system still uses an older format such as COFF then there are likely to be @@ -529,6 +2676,13 @@ simple system calls, and instead wrapper implemented at the variant HAL level. </para> <para> +The generic I/O auxiliary code should be fairly portable to other Unix +platforms. However some of the device drivers may contain code that is +specific to Linux, for example the <literal>PF_PACKET</literal> socket +address family and the ethertap virtual tunnelling interface. These +may prove quite difficult to port. + </para> + <para> The remaining porting task is to implement one or more platform HAL packages, one per processor type that is supported. This should involve much the same work as a port to <link @@ -541,14 +2695,6 @@ However there is still a good chance tha been ported already, so its source code may contain much useful information. </para> - <caution><para> -Users should be aware that future enhancements to the synthetic target -code, especially in areas related to I/O, may be much more closely -tied to Linux. For example access to ethernet facilities might be -implemented using the <literal>PF_PACKET</literal> socket address -family, or the virtual tunnelling interface. Porting such code to -other Unix operating systems may prove rather more difficult. - </para></caution> </refsect1> <refsect1 id="synth-porting-other"><title>Windows Platforms</title>
new file mode 100644 --- /dev/null +++ b/packages/hal/synth/arch/current/host/Makefile.am @@ -0,0 +1,92 @@ +## Process this file with automake to produce Makefile.in +## ===================================================================== +## +## Makefile.am +## +## Build support for the host-side synthetic target support, +## the arch package. +## +## +## ===================================================================== +######COPYRIGHTBEGIN#### +# +# ---------------------------------------------------------------------------- +# Copyright (C) 2002 Bart Veer +# +# This file is part of the eCos synthetic target support. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the Free +# Software Foundation; either version 2 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, write to the Free Software Foundation, Inc., +# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# ---------------------------------------------------------------------------- +# +######COPYRIGHTEND#### +## ===================================================================== +#######DESCRIPTIONBEGIN#### +## +## Author(s): bartv +## Contact(s): bartv +## Date: 2002/08/06 +## Version: 0.01 +## +######DESCRIPTIONEND#### +## ===================================================================== + +AUTOMAKE_OPTIONS = 1.3 foreign + +## Only some platforms are supported. Having the configure script throw +## an error when attempting to configure on an unsupported platform +## would be a mistake, since that would prevent any configury from +## the toplevel on unsupported platforms. Instead an automake conditional +## is used, leading to null makefiles on unsupported platforms. + +if SUPPORTED + +AM_CFLAGS = @ecos_CFLAGS@ -DECOSYNTH_VERSION=\"@VERSION@\" \ + -DECOS_REPOSITORY=\"@ECOS_REPOSITORY@\" \ + -DLIBEXECDIR=\"$(libexecdir)\" \ + -DPACKAGE_DIR=\"@PACKAGE_DIR@\" \ + -DPACKAGE_VERSION=\"@PACKAGE_VERSION@\" \ + -DPACKAGE_INSTALL=\"@PACKAGE_INSTALL@\" +AM_CXXFLAGS = @ecos_CXXFLAGS@ +INCLUDES = @ecos_INCLUDES@ +LIBS = @ecos_LIBS@ @ecos_LDADD@ + +## The synthetic target support consists of a single program ecosynth, +## a number of Tcl scripts, and some additional data files. These are +## all installed in a single directory $(libexec)/ecos/<package>_<version>/ +## Neither the ecosynth executable nor any of the scripts are directly +## executable, instead ecosynth gets fork()'d/execve()'d by the eCos +## application so $(libexec) is appropriate. Strictly speaking the +## Tcl scripts and data files are architecture-independent so should +## probably be installed in an analogous directory below $(datadir), +## but that would add more directories for little real gain. The scripts +## are treated as data files since they should not be executed directly, +## i.e. they should not be installed with the execute bit set. + +synthdir = $(libexecdir)/ecos/@PACKAGE_INSTALL@ +synth_PROGRAMS = ecosynth +synth_DATA = ecosynth.tcl default.tdf user_initrc.tcl user_mainrc.tcl \ + console.tcl \ + ecosicon.xbm ecosiconmask.xbm tick_yes.xbm tick_no.xbm \ + save.xbm cut.xbm copy.xbm paste.xbm help.xbm running1.ppm \ + saveall.xbm + +ecosynth_SOURCES = ecosynth.c +ecosynth_LDADD = @ecos_tk_libs@ + +## Manual dependencies +ecosynth.$(OBJEXT) : Makefile ../src/synth_protocol.h + +endif
new file mode 100644 --- /dev/null +++ b/packages/hal/synth/arch/current/host/Makefile.in @@ -0,0 +1,449 @@ +# Makefile.in generated automatically by automake 1.4-p5 from Makefile.am + +# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +######COPYRIGHTBEGIN#### +# +# ---------------------------------------------------------------------------- +# Copyright (C) 2002 Bart Veer +# +# This file is part of the eCos synthetic target support. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the Free +# Software Foundation; either version 2 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, write to the Free Software Foundation, Inc., +# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# ---------------------------------------------------------------------------- +# +######COPYRIGHTEND#### +#######DESCRIPTIONBEGIN#### +######DESCRIPTIONEND#### + + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DESTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = . + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_alias = @host_alias@ +host_triplet = @host@ +CC = @CC@ +CXX = @CXX@ +ECOS_REPOSITORY = @ECOS_REPOSITORY@ +EXEEXT = @EXEEXT@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MSVC_SRCDIR = @MSVC_SRCDIR@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_DIR = @PACKAGE_DIR@ +PACKAGE_INSTALL = @PACKAGE_INSTALL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +VERSION = @VERSION@ +ecos_CFLAGS = @ecos_CFLAGS@ +ecos_CXXFLAGS = @ecos_CXXFLAGS@ +ecos_INCLUDES = @ecos_INCLUDES@ +ecos_LDADD = @ecos_LDADD@ +ecos_LIBS = @ecos_LIBS@ +ecos_infra_incdir = @ecos_infra_incdir@ +ecos_infra_libdir = @ecos_infra_libdir@ +ecos_libcdl_incdir = @ecos_libcdl_incdir@ +ecos_libcdl_libdir = @ecos_libcdl_libdir@ +ecos_tk_libs = @ecos_tk_libs@ + +AUTOMAKE_OPTIONS = 1.3 foreign + +@SUPPORTED_TRUE@AM_CFLAGS = @SUPPORTED_TRUE@@ecos_CFLAGS@ -DECOSYNTH_VERSION=\"@VERSION@\" \ +@SUPPORTED_TRUE@ -DECOS_REPOSITORY=\"@ECOS_REPOSITORY@\" \ +@SUPPORTED_TRUE@ -DLIBEXECDIR=\"$(libexecdir)\" \ +@SUPPORTED_TRUE@ -DPACKAGE_DIR=\"@PACKAGE_DIR@\" \ +@SUPPORTED_TRUE@ -DPACKAGE_VERSION=\"@PACKAGE_VERSION@\" \ +@SUPPORTED_TRUE@ -DPACKAGE_INSTALL=\"@PACKAGE_INSTALL@\" +@SUPPORTED_TRUE@AM_CXXFLAGS = @SUPPORTED_TRUE@@ecos_CXXFLAGS@ +@SUPPORTED_TRUE@INCLUDES = @SUPPORTED_TRUE@@ecos_INCLUDES@ +@SUPPORTED_TRUE@LIBS = @SUPPORTED_TRUE@@ecos_LIBS@ @ecos_LDADD@ + +@SUPPORTED_TRUE@synthdir = @SUPPORTED_TRUE@$(libexecdir)/ecos/@PACKAGE_INSTALL@ +@SUPPORTED_TRUE@synth_PROGRAMS = @SUPPORTED_TRUE@ecosynth +@SUPPORTED_TRUE@synth_DATA = @SUPPORTED_TRUE@ecosynth.tcl default.tdf user_initrc.tcl user_mainrc.tcl \ +@SUPPORTED_TRUE@ console.tcl \ +@SUPPORTED_TRUE@ ecosicon.xbm ecosiconmask.xbm tick_yes.xbm tick_no.xbm \ +@SUPPORTED_TRUE@ save.xbm cut.xbm copy.xbm paste.xbm help.xbm running1.ppm \ +@SUPPORTED_TRUE@ saveall.xbm + +@SUPPORTED_TRUE@ecosynth_SOURCES = @SUPPORTED_TRUE@ecosynth.c +@SUPPORTED_TRUE@ecosynth_LDADD = @SUPPORTED_TRUE@@ecos_tk_libs@ +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +mkinstalldirs = $(SHELL) $(top_srcdir)/../../../../../../acsupport/mkinstalldirs +CONFIG_CLEAN_FILES = +@SUPPORTED_TRUE@synth_PROGRAMS = ecosynth$(EXEEXT) +PROGRAMS = $(synth_PROGRAMS) + + +DEFS = @DEFS@ -I. -I$(srcdir) +CPPFLAGS = @CPPFLAGS@ +LDFLAGS = @LDFLAGS@ +@SUPPORTED_TRUE@ecosynth_OBJECTS = ecosynth.$(OBJEXT) +@SUPPORTED_TRUE@ecosynth_DEPENDENCIES = +ecosynth_LDFLAGS = +CFLAGS = @CFLAGS@ +COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ +DATA = $(synth_DATA) + +DIST_COMMON = Makefile.am Makefile.in acinclude.m4 aclocal.m4 configure \ +configure.in + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = gtar +GZIP_ENV = --best +DEP_FILES = .deps/ecosynth.P +SOURCES = $(ecosynth_SOURCES) +OBJECTS = $(ecosynth_OBJECTS) + +all: all-redirect +.SUFFIXES: +.SUFFIXES: .S .c .o .obj .s +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES) + cd $(top_builddir) \ + && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status + +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ configure.in acinclude.m4 + cd $(srcdir) && $(ACLOCAL) + +config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck +$(srcdir)/configure: @MAINTAINER_MODE_TRUE@$(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES) + cd $(srcdir) && $(AUTOCONF) + +mostlyclean-synthPROGRAMS: + +clean-synthPROGRAMS: + -test -z "$(synth_PROGRAMS)" || rm -f $(synth_PROGRAMS) + +distclean-synthPROGRAMS: + +maintainer-clean-synthPROGRAMS: + +install-synthPROGRAMS: $(synth_PROGRAMS) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(synthdir) + @list='$(synth_PROGRAMS)'; for p in $$list; do \ + if test -f $$p; then \ + echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(synthdir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \ + $(INSTALL_PROGRAM) $$p $(DESTDIR)$(synthdir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ + else :; fi; \ + done + +uninstall-synthPROGRAMS: + @$(NORMAL_UNINSTALL) + list='$(synth_PROGRAMS)'; for p in $$list; do \ + rm -f $(DESTDIR)$(synthdir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ + done + +# FIXME: We should only use cygpath when building on Windows, +# and only if it is available. +.c.obj: + $(COMPILE) -c `cygpath -w $<` + +.s.o: + $(COMPILE) -c $< + +.S.o: + $(COMPILE) -c $< + +mostlyclean-compile: + -rm -f *.o core *.core + -rm -f *.$(OBJEXT) + +clean-compile: + +distclean-compile: + -rm -f *.tab.c + +maintainer-clean-compile: + +ecosynth$(EXEEXT): $(ecosynth_OBJECTS) $(ecosynth_DEPENDENCIES) + @rm -f ecosynth$(EXEEXT) + $(LINK) $(ecosynth_LDFLAGS) $(ecosynth_OBJECTS) $(ecosynth_LDADD) $(LIBS) + +install-synthDATA: $(synth_DATA) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(synthdir) + @list='$(synth_DATA)'; for p in $$list; do \ + if test -f $(srcdir)/$$p; then \ + echo " $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(synthdir)/$$p"; \ + $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(synthdir)/$$p; \ + else if test -f $$p; then \ + echo " $(INSTALL_DATA) $$p $(DESTDIR)$(synthdir)/$$p"; \ + $(INSTALL_DATA) $$p $(DESTDIR)$(synthdir)/$$p; \ + fi; fi; \ + done + +uninstall-synthDATA: + @$(NORMAL_UNINSTALL) + list='$(synth_DATA)'; for p in $$list; do \ + rm -f $(DESTDIR)$(synthdir)/$$p; \ + done + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + here=`pwd` && cd $(srcdir) \ + && mkid -f$$here/ID $$unique $(LISP) + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ + || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS) + +mostlyclean-tags: + +clean-tags: + +distclean-tags: + -rm -f TAGS ID + +maintainer-clean-tags: + +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + -rm -rf $(distdir) + GZIP=$(GZIP_ENV) $(TAR) zxf $(distdir).tar.gz + mkdir $(distdir)/=build + mkdir $(distdir)/=inst + dc_install_base=`cd $(distdir)/=inst && pwd`; \ + cd $(distdir)/=build \ + && ../configure --srcdir=.. --prefix=$$dc_install_base \ + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) dvi \ + && $(MAKE) $(AM_MAKEFLAGS) check \ + && $(MAKE) $(AM_MAKEFLAGS) install \ + && $(MAKE) $(AM_MAKEFLAGS) installcheck \ + && $(MAKE) $(AM_MAKEFLAGS) dist + -rm -rf $(distdir) + @banner="$(distdir).tar.gz is ready for distribution"; \ + dashes=`echo "$$banner" | sed s/./=/g`; \ + echo "$$dashes"; \ + echo "$$banner"; \ + echo "$$dashes" +dist: distdir + -chmod -R a+r $(distdir) + GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir) + -rm -rf $(distdir) +dist-all: distdir + -chmod -R a+r $(distdir) + GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir) + -rm -rf $(distdir) +distdir: $(DISTFILES) + -rm -rf $(distdir) + mkdir $(distdir) + -chmod 777 $(distdir) + here=`cd $(top_builddir) && pwd`; \ + top_distdir=`cd $(distdir) && pwd`; \ + distdir=`cd $(distdir) && pwd`; \ + cd $(top_srcdir) \ + && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --foreign Makefile + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + if test -d $$d/$$file; then \ + cp -pr $$d/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ + done + +DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :) + +-include $(DEP_FILES) + +mostlyclean-depend: + +clean-depend: + +distclean-depend: + -rm -rf .deps + +maintainer-clean-depend: + +%.o: %.c + @echo '$(COMPILE) -c $<'; \ + $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $< + @-cp .deps/$(*F).pp .deps/$(*F).P; \ + tr ' ' '\012' < .deps/$(*F).pp \ + | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \ + >> .deps/$(*F).P; \ + rm .deps/$(*F).pp + +%.lo: %.c + @echo '$(LTCOMPILE) -c $<'; \ + $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $< + @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \ + < .deps/$(*F).pp > .deps/$(*F).P; \ + tr ' ' '\012' < .deps/$(*F).pp \ + | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \ + >> .deps/$(*F).P; \ + rm -f .deps/$(*F).pp +info-am: +info: info-am +dvi-am: +dvi: dvi-am +check-am: all-am +check: check-am +installcheck-am: +installcheck: installcheck-am +install-exec-am: +install-exec: install-exec-am + +install-data-am: install-synthPROGRAMS install-synthDATA +install-data: install-data-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-am +uninstall-am: uninstall-synthPROGRAMS uninstall-synthDATA +uninstall: uninstall-am +all-am: Makefile $(PROGRAMS) $(DATA) +all-redirect: all-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install +installdirs: + $(mkinstalldirs) $(DESTDIR)$(synthdir) $(DESTDIR)$(synthdir) + + +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + +maintainer-clean-generic: +mostlyclean-am: mostlyclean-synthPROGRAMS mostlyclean-compile \ + mostlyclean-tags mostlyclean-depend mostlyclean-generic + +mostlyclean: mostlyclean-am + +clean-am: clean-synthPROGRAMS clean-compile clean-tags clean-depend \ + clean-generic mostlyclean-am + +clean: clean-am + +distclean-am: distclean-synthPROGRAMS distclean-compile distclean-tags \ + distclean-depend distclean-generic clean-am + +distclean: distclean-am + -rm -f config.status + +maintainer-clean-am: maintainer-clean-synthPROGRAMS \ + maintainer-clean-compile maintainer-clean-tags \ + maintainer-clean-depend maintainer-clean-generic \ + distclean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +maintainer-clean: maintainer-clean-am + -rm -f config.status + +.PHONY: mostlyclean-synthPROGRAMS distclean-synthPROGRAMS \ +clean-synthPROGRAMS maintainer-clean-synthPROGRAMS \ +uninstall-synthPROGRAMS install-synthPROGRAMS mostlyclean-compile \ +distclean-compile clean-compile maintainer-clean-compile \ +uninstall-synthDATA install-synthDATA tags mostlyclean-tags \ +distclean-tags clean-tags maintainer-clean-tags distdir \ +mostlyclean-depend distclean-depend clean-depend \ +maintainer-clean-depend info-am info dvi-am dvi check check-am \ +installcheck-am installcheck install-exec-am install-exec \ +install-data-am install-data install-am install uninstall-am uninstall \ +all-redirect all-am all installdirs mostlyclean-generic \ +distclean-generic clean-generic maintainer-clean-generic clean \ +mostlyclean distclean maintainer-clean + + +@SUPPORTED_TRUE@ecosynth.$(OBJEXT) : Makefile ../src/synth_protocol.h + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT:
new file mode 100644 --- /dev/null +++ b/packages/hal/synth/arch/current/host/acinclude.m4 @@ -0,0 +1,46 @@ +dnl Process this file with aclocal to get an aclocal.m4 file. Then +dnl process that with autoconf. +dnl ==================================================================== +dnl +dnl acinclude.m4 +dnl +dnl ==================================================================== +dnl####COPYRIGHTBEGIN#### +dnl +dnl ---------------------------------------------------------------------------- +dnl Copyright (C) 2002 Bart Veer +dnl +dnl This file is part of the eCos host tools. +dnl +dnl This program is free software; you can redistribute it and/or modify it +dnl under the terms of the GNU General Public License as published by the Free +dnl Software Foundation; either version 2 of the License, or (at your option) +dnl any later version. +dnl +dnl This program is distributed in the hope that it will be useful, but WITHOUT +dnl ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +dnl FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +dnl more details. +dnl +dnl You should have received a copy of the GNU General Public License along with +dnl this program; if not, write to the Free Software Foundation, Inc., +dnl 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +dnl +dnl ---------------------------------------------------------------------------- +dnl +dnl####COPYRIGHTEND#### +dnl ==================================================================== +dnl#####DESCRIPTIONBEGIN#### +dnl +dnl Author(s): bartv +dnl Contact(s): bartv +dnl Date: 2002/08/06 +dnl Version: 0.01 +dnl +dnl####DESCRIPTIONEND#### +dnl ==================================================================== + +dnl Access shared macros. +dnl AM_CONDITIONAL needs to be mentioned here or else aclocal does not +dnl incorporate the macro into aclocal.m4 +sinclude(../../../../../../acsupport/acinclude.m4)
new file mode 100644 --- /dev/null +++ b/packages/hal/synth/arch/current/host/aclocal.m4 @@ -0,0 +1,184 @@ +dnl aclocal.m4 generated automatically by aclocal 1.4-p5 + +dnl Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl This program is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without +dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A +dnl PARTICULAR PURPOSE. + +dnl Process this file with aclocal to get an aclocal.m4 file. Then +dnl process that with autoconf. +dnl ==================================================================== +dnl +dnl acinclude.m4 +dnl +dnl ==================================================================== +dnl####COPYRIGHTBEGIN#### +dnl +dnl ---------------------------------------------------------------------------- +dnl Copyright (C) 2002 Bart Veer +dnl +dnl This file is part of the eCos host tools. +dnl +dnl This program is free software; you can redistribute it and/or modify it +dnl under the terms of the GNU General Public License as published by the Free +dnl Software Foundation; either version 2 of the License, or (at your option) +dnl any later version. +dnl +dnl This program is distributed in the hope that it will be useful, but WITHOUT +dnl ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +dnl FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +dnl more details. +dnl +dnl You should have received a copy of the GNU General Public License along with +dnl this program; if not, write to the Free Software Foundation, Inc., +dnl 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +dnl +dnl ---------------------------------------------------------------------------- +dnl +dnl####COPYRIGHTEND#### +dnl ==================================================================== +dnl#####DESCRIPTIONBEGIN#### +dnl +dnl Author(s): bartv +dnl Contact(s): bartv +dnl Date: 2002/08/06 +dnl Version: 0.01 +dnl +dnl####DESCRIPTIONEND#### +dnl ==================================================================== + +dnl Access shared macros. +dnl AM_CONDITIONAL needs to be mentioned here or else aclocal does not +dnl incorporate the macro into aclocal.m4 +sinclude(../../../../../../acsupport/acinclude.m4) + +# Define a conditional. + +AC_DEFUN([AM_CONDITIONAL], +[AC_SUBST($1_TRUE) +AC_SUBST($1_FALSE) +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi]) + +# Do all the work for Automake. This macro actually does too much -- +# some checks are only needed if your package does certain things. +# But this isn't really a big deal. + +# serial 1 + +dnl Usage: +dnl AM_INIT_AUTOMAKE(package,version, [no-define]) + +AC_DEFUN([AM_INIT_AUTOMAKE], +[AC_REQUIRE([AC_PROG_INSTALL]) +PACKAGE=[$1] +AC_SUBST(PACKAGE) +VERSION=[$2] +AC_SUBST(VERSION) +dnl test to see if srcdir already configured +if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) +fi +ifelse([$3],, +AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) +AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])) +AC_REQUIRE([AM_SANITY_CHECK]) +AC_REQUIRE([AC_ARG_PROGRAM]) +dnl FIXME This is truly gross. +missing_dir=`cd $ac_aux_dir && pwd` +AM_MISSING_PROG(ACLOCAL, aclocal, $missing_dir) +AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir) +AM_MISSING_PROG(AUTOMAKE, automake, $missing_dir) +AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir) +AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir) +AC_REQUIRE([AC_PROG_MAKE_SET])]) + +# +# Check to make sure that the build environment is sane. +# + +AC_DEFUN([AM_SANITY_CHECK], +[AC_MSG_CHECKING([whether build environment is sane]) +# Just in case +sleep 1 +echo timestamp > conftestfile +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null` + if test "[$]*" = "X"; then + # -L didn't work. + set X `ls -t $srcdir/configure conftestfile` + fi + if test "[$]*" != "X $srcdir/configure conftestfile" \ + && test "[$]*" != "X conftestfile $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken +alias in your environment]) + fi + + test "[$]2" = conftestfile + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +rm -f conftest* +AC_MSG_RESULT(yes)]) + +dnl AM_MISSING_PROG(NAME, PROGRAM, DIRECTORY) +dnl The program must properly implement --version. +AC_DEFUN([AM_MISSING_PROG], +[AC_MSG_CHECKING(for working $2) +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if ($2 --version) < /dev/null > /dev/null 2>&1; then + $1=$2 + AC_MSG_RESULT(found) +else + $1="$3/missing $2" + AC_MSG_RESULT(missing) +fi +AC_SUBST($1)]) + +# Add --enable-maintainer-mode option to configure. +# From Jim Meyering + +# serial 1 + +AC_DEFUN([AM_MAINTAINER_MODE], +[AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) + dnl maintainer-mode is disabled by default + AC_ARG_ENABLE(maintainer-mode, +[ --enable-maintainer-mode enable make rules and dependencies not useful + (and sometimes confusing) to the casual installer], + USE_MAINTAINER_MODE=$enableval, + USE_MAINTAINER_MODE=no) + AC_MSG_RESULT($USE_MAINTAINER_MODE) + AM_CONDITIONAL(MAINTAINER_MODE, test $USE_MAINTAINER_MODE = yes) + MAINT=$MAINTAINER_MODE_TRUE + AC_SUBST(MAINT)dnl +] +) +
new file mode 100644 --- /dev/null +++ b/packages/hal/synth/arch/current/host/configure @@ -0,0 +1,2013 @@ +#! /bin/sh + +# Guess values for system-dependent variables and create Makefiles. +# Generated automatically using autoconf version 2.13 +# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. + +# Defaults: +ac_help= +ac_default_prefix=/usr/local +# Any additions from configure.in: +ac_help="$ac_help + --enable-maintainer-mode enable make rules and dependencies not useful + (and sometimes confusing) to the casual installer" +ac_help="$ac_help + --enable-debug do a debug rather than a release build" +ac_help="$ac_help + --enable-ansi do an ANSI rather than a unicode build" +ac_help="$ac_help + --with-tcl-version=<vsn> version of Tcl to be used" +ac_help="$ac_help + --with-tcl-header=<path> location of Tcl header" +ac_help="$ac_help + --with-tcl-lib=<path> location of Tcl libraries" +ac_help="$ac_help + --with-tcl=<path> location of Tcl header and libraries" + +# Initialize some variables set by options. +# The variables have the same names as the options, with +# dashes changed to underlines. +build=NONE +cache_file=./config.cache +exec_prefix=NONE +host=NONE +no_create= +nonopt=NONE +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +target=NONE +verbose= +x_includes=NONE +x_libraries=NONE +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datadir='${prefix}/share' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +libdir='${exec_prefix}/lib' +includedir='${prefix}/include' +oldincludedir='/usr/include' +infodir='${prefix}/info' +mandir='${prefix}/man' + +# Initialize some other variables. +subdirs= +MFLAGS= MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} +# Maximum number of lines to put in a shell here document. +ac_max_here_lines=12 + +ac_prev= +for ac_option +do + + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + + case "$ac_option" in + -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) ac_optarg= ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case "$ac_option" in + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir="$ac_optarg" ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build="$ac_optarg" ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file="$ac_optarg" ;; + + -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir="$ac_optarg" ;; + + -disable-* | --disable-*) + ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + eval "enable_${ac_feature}=no" ;; + + -enable-* | --enable-*) + ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "enable_${ac_feature}='$ac_optarg'" ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix="$ac_optarg" ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he) + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat << EOF +Usage: configure [options] [host] +Options: [defaults in brackets after descriptions] +Configuration: + --cache-file=FILE cache test results in FILE + --help print this message + --no-create do not create output files + --quiet, --silent do not print \`checking...' messages + --version print the version of autoconf that created configure +Directory and file names: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [same as prefix] + --bindir=DIR user executables in DIR [EPREFIX/bin] + --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] + --libexecdir=DIR program executables in DIR [EPREFIX/libexec] + --datadir=DIR read-only architecture-independent data in DIR + [PREFIX/share] + --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data in DIR + [PREFIX/com] + --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] + --libdir=DIR object code libraries in DIR [EPREFIX/lib] + --includedir=DIR C header files in DIR [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] + --infodir=DIR info documentation in DIR [PREFIX/info] + --mandir=DIR man documentation in DIR [PREFIX/man] + --srcdir=DIR find the sources in DIR [configure dir or ..] + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM + run sed PROGRAM on installed program names +EOF + cat << EOF +Host type: + --build=BUILD configure for building on BUILD [BUILD=HOST] + --host=HOST configure for HOST [guessed] + --target=TARGET configure for TARGET [TARGET=HOST] +Features and packages: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --x-includes=DIR X include files are in DIR + --x-libraries=DIR X library files are in DIR +EOF + if test -n "$ac_help"; then + echo "--enable and --with options recognized:$ac_help" + fi + exit 0 ;; + + -host | --host | --hos | --ho) + ac_prev=host ;; + -host=* | --host=* | --hos=* | --ho=*) + host="$ac_optarg" ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir="$ac_optarg" ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir="$ac_optarg" ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir="$ac_optarg" ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir="$ac_optarg" ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst \ + | --locals | --local | --loca | --loc | --lo) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* \ + | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + localstatedir="$ac_optarg" ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir="$ac_optarg" ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir="$ac_optarg" ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix="$ac_optarg" ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix="$ac_optarg" ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix="$ac_optarg" ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name="$ac_optarg" ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir="$ac_optarg" ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir="$ac_optarg" ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site="$ac_optarg" ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir="$ac_optarg" ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir="$ac_optarg" ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target="$ac_optarg" ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers) + echo "configure generated by autoconf version 2.13" + exit 0 ;; + + -with-* | --with-*) + ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "with_${ac_package}='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`echo $ac_option|sed -e 's/-*without-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + eval "with_${ac_package}=no" ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes="$ac_optarg" ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries="$ac_optarg" ;; + + -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } + ;; + + *) + if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then + echo "configure: warning: $ac_option: invalid host type" 1>&2 + fi + if test "x$nonopt" != xNONE; then + { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } + fi + nonopt="$ac_option" + ;; + + esac +done + +if test -n "$ac_prev"; then + { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } +fi + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +# File descriptor usage: +# 0 standard input +# 1 file creation +# 2 errors and warnings +# 3 some systems may open it to /dev/tty +# 4 used on the Kubota Titan +# 6 checking for... messages and results +# 5 compiler messages saved in config.log +if test "$silent" = yes; then + exec 6>/dev/null +else + exec 6>&1 +fi +exec 5>./config.log + +echo "\ +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. +" 1>&5 + +# Strip out --no-create and --no-recursion so they do not pile up. +# Also quote any args containing shell metacharacters. +ac_configure_args= +for ac_arg +do + case "$ac_arg" in + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) ;; + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) + ac_configure_args="$ac_configure_args '$ac_arg'" ;; + *) ac_configure_args="$ac_configure_args $ac_arg" ;; + esac +done + +# NLS nuisances. +# Only set these to C if already set. These must not be set unconditionally +# because not all systems understand e.g. LANG=C (notably SCO). +# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! +# Non-C LC_CTYPE values break the ctype check. +if test "${LANG+set}" = set; then LANG=C; export LANG; fi +if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi +if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi +if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo > confdefs.h + +# A filename unique to this package, relative to the directory that +# configure is in, which we can look for to find out if srcdir is correct. +ac_unique_file=ecosynth.c + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then its parent. + ac_prog=$0 + ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` + test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r $srcdir/$ac_unique_file; then + if test "$ac_srcdir_defaulted" = yes; then + { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } + else + { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } + fi +fi +srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` + +# Prefer explicitly selected file to automatically selected ones. +if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi +fi +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + echo "loading site script $ac_site_file" + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + echo "loading cache $cache_file" + . $cache_file +else + echo "creating cache $cache_file" + > $cache_file +fi + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +ac_exeext= +ac_objext=o +if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then + # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. + if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then + ac_n= ac_c=' +' ac_t=' ' + else + ac_n=-n ac_c= ac_t= + fi +else + ac_n= ac_c='\c' ac_t= +fi + + + +ac_aux_dir= +for ac_dir in ../../../../../../acsupport $srcdir/../../../../../../acsupport; do + if test -f $ac_dir/install-sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f $ac_dir/install.sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { echo "configure: error: can not find install-sh or install.sh in ../../../../../../acsupport $srcdir/../../../../../../acsupport" 1>&2; exit 1; } +fi +ac_config_guess=$ac_aux_dir/config.guess +ac_config_sub=$ac_aux_dir/config.sub +ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. + + + + echo $ac_n "checking that a separate build tree is being used""... $ac_c" 1>&6 +echo "configure:563: checking that a separate build tree is being used" >&5 + ecos_cwd=`/bin/pwd` + if test "${srcdir}" = "." ; then + srcdir=${ecos_cwd} + fi + if test "${ecos_cwd}" = "${srcdir}" ; then + echo "$ac_t""no" 1>&6 + { echo "configure: error: This configure script should not be run inside the source tree. Instead please use a separate build tree" 1>&2; exit 1; } + else + echo "$ac_t""yes" 1>&6 + fi + + +# Make sure we can run config.sub. +if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then : +else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; } +fi + +echo $ac_n "checking host system type""... $ac_c" 1>&6 +echo "configure:582: checking host system type" >&5 + +host_alias=$host +case "$host_alias" in +NONE) + case $nonopt in + NONE) + if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then : + else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; } + fi ;; + *) host_alias=$nonopt ;; + esac ;; +esac + +host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias` +host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$host" 1>&6 + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# ./install, which can be erroneously created by make from ./install.sh. +echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 +echo "configure:614: checking for a BSD compatible install" >&5 +if test -z "$INSTALL"; then +if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":" + for ac_dir in $PATH; do + # Account for people who put trailing slashes in PATH elements. + case "$ac_dir/" in + /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + if test -f $ac_dir/$ac_prog; then + if test $ac_prog = install && + grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + else + ac_cv_path_install="$ac_dir/$ac_prog -c" + break 2 + fi + fi + done + ;; + esac + done + IFS="$ac_save_IFS" + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL="$ac_cv_path_install" + else + # As a last resort, use the slow shell script. We don't cache a + # path for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the path is relative. + INSTALL="$ac_install_sh" + fi +fi +echo "$ac_t""$INSTALL" 1>&6 + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +echo $ac_n "checking whether build environment is sane""... $ac_c" 1>&6 +echo "configure:667: checking whether build environment is sane" >&5 +# Just in case +sleep 1 +echo timestamp > conftestfile +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t $srcdir/configure conftestfile` + fi + if test "$*" != "X $srcdir/configure conftestfile" \ + && test "$*" != "X conftestfile $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + { echo "configure: error: ls -t appears to fail. Make sure there is not a broken +alias in your environment" 1>&2; exit 1; } + fi + + test "$2" = conftestfile + ) +then + # Ok. + : +else + { echo "configure: error: newly created file is older than distributed files! +Check your system clock" 1>&2; exit 1; } +fi +rm -f conftest* +echo "$ac_t""yes" 1>&6 +if test "$program_transform_name" = s,x,x,; then + program_transform_name= +else + # Double any \ or $. echo might interpret backslashes. + cat <<\EOF_SED > conftestsed +s,\\,\\\\,g; s,\$,$$,g +EOF_SED + program_transform_name="`echo $program_transform_name|sed -f conftestsed`" + rm -f conftestsed +fi +test "$program_prefix" != NONE && + program_transform_name="s,^,${program_prefix},; $program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s,\$\$,${program_suffix},; $program_transform_name" + +# sed with no file args requires a program. +test "$program_transform_name" = "" && program_transform_name="s,x,x," + +echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6 +echo "configure:724: checking whether ${MAKE-make} sets \${MAKE}" >&5 +set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftestmake <<\EOF +all: + @echo 'ac_maketemp="${MAKE}"' +EOF +# GNU make sometimes prints "make[1]: Entering...", which would confuse us. +eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=` +if test -n "$ac_maketemp"; then + eval ac_cv_prog_make_${ac_make}_set=yes +else + eval ac_cv_prog_make_${ac_make}_set=no +fi +rm -f conftestmake +fi +if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then + echo "$ac_t""yes" 1>&6 + SET_MAKE= +else + echo "$ac_t""no" 1>&6 + SET_MAKE="MAKE=${MAKE-make}" +fi + + +PACKAGE=eCos_synthetic_target_arch + +VERSION=0.1 + +if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then + { echo "configure: error: source directory already configured; run "make distclean" there first" 1>&2; exit 1; } +fi + + + +missing_dir=`cd $ac_aux_dir && pwd` +echo $ac_n "checking for working aclocal""... $ac_c" 1>&6 +echo "configure:763: checking for working aclocal" >&5 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (aclocal --version) < /dev/null > /dev/null 2>&1; then + ACLOCAL=aclocal + echo "$ac_t""found" 1>&6 +else + ACLOCAL="$missing_dir/missing aclocal" + echo "$ac_t""missing" 1>&6 +fi + +echo $ac_n "checking for working autoconf""... $ac_c" 1>&6 +echo "configure:776: checking for working autoconf" >&5 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (autoconf --version) < /dev/null > /dev/null 2>&1; then + AUTOCONF=autoconf + echo "$ac_t""found" 1>&6 +else + AUTOCONF="$missing_dir/missing autoconf" + echo "$ac_t""missing" 1>&6 +fi + +echo $ac_n "checking for working automake""... $ac_c" 1>&6 +echo "configure:789: checking for working automake" >&5 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (automake --version) < /dev/null > /dev/null 2>&1; then + AUTOMAKE=automake + echo "$ac_t""found" 1>&6 +else + AUTOMAKE="$missing_dir/missing automake" + echo "$ac_t""missing" 1>&6 +fi + +echo $ac_n "checking for working autoheader""... $ac_c" 1>&6 +echo "configure:802: checking for working autoheader" >&5 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (autoheader --version) < /dev/null > /dev/null 2>&1; then + AUTOHEADER=autoheader + echo "$ac_t""found" 1>&6 +else + AUTOHEADER="$missing_dir/missing autoheader" + echo "$ac_t""missing" 1>&6 +fi + +echo $ac_n "checking for working makeinfo""... $ac_c" 1>&6 +echo "configure:815: checking for working makeinfo" >&5 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (makeinfo --version) < /dev/null > /dev/null 2>&1; then + MAKEINFO=makeinfo + echo "$ac_t""found" 1>&6 +else + MAKEINFO="$missing_dir/missing makeinfo" + echo "$ac_t""missing" 1>&6 +fi + + +echo $ac_n "checking whether to enable maintainer-specific portions of Makefiles""... $ac_c" 1>&6 +echo "configure:829: checking whether to enable maintainer-specific portions of Makefiles" >&5 + # Check whether --enable-maintainer-mode or --disable-maintainer-mode was given. +if test "${enable_maintainer_mode+set}" = set; then + enableval="$enable_maintainer_mode" + USE_MAINTAINER_MODE=$enableval +else + USE_MAINTAINER_MODE=no +fi + + echo "$ac_t""$USE_MAINTAINER_MODE" 1>&6 + + +if test $USE_MAINTAINER_MODE = yes; then + MAINTAINER_MODE_TRUE= + MAINTAINER_MODE_FALSE='#' +else + MAINTAINER_MODE_TRUE='#' + MAINTAINER_MODE_FALSE= +fi + MAINT=$MAINTAINER_MODE_TRUE + + + +case "${host}" in + i[34567]86-*-linux-gnu* ) SUPPORTED="yes";; + * ) SUPPORTED="no" +esac + + +if test "${SUPPORTED}" = "yes"; then + SUPPORTED_TRUE= + SUPPORTED_FALSE='#' +else + SUPPORTED_TRUE='#' + SUPPORTED_FALSE= +fi + +if test "${SUPPORTED}" = "yes" ; then + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:870: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="gcc" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:900: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_prog_rejected=no + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + break + fi + done + IFS="$ac_save_ifs" +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# -gt 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + set dummy "$ac_dir/$ac_word" "$@" + shift + ac_cv_prog_CC="$@" + fi +fi +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$CC"; then + case "`uname -s`" in + *win32* | *WIN32*) + # Extract the first word of "cl", so it can be a program name with args. +set dummy cl; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:951: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="cl" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + ;; + esac + fi + test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } +fi + +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 +echo "configure:983: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +cat > conftest.$ac_ext << EOF + +#line 994 "configure" +#include "confdefs.h" + +main(){return(0);} +EOF +if { (eval echo configure:999: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + ac_cv_prog_cc_works=yes + # If we can't run a trivial program, we are probably using a cross compiler. + if (./conftest; exit) 2>/dev/null; then + ac_cv_prog_cc_cross=no + else + ac_cv_prog_cc_cross=yes + fi +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_cv_prog_cc_works=no +fi +rm -fr conftest* +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 +if test $ac_cv_prog_cc_works = no; then + { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } +fi +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 +echo "configure:1025: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 +cross_compiling=$ac_cv_prog_cc_cross + +echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 +echo "configure:1030: checking whether we are using GNU C" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.c <<EOF +#ifdef __GNUC__ + yes; +#endif +EOF +if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1039: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then + ac_cv_prog_gcc=yes +else + ac_cv_prog_gcc=no +fi +fi + +echo "$ac_t""$ac_cv_prog_gcc" 1>&6 + +if test $ac_cv_prog_gcc = yes; then + GCC=yes +else + GCC= +fi + +ac_test_CFLAGS="${CFLAGS+set}" +ac_save_CFLAGS="$CFLAGS" +CFLAGS= +echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 +echo "configure:1058: checking whether ${CC-cc} accepts -g" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + echo 'void f(){}' > conftest.c +if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then + ac_cv_prog_cc_g=yes +else + ac_cv_prog_cc_g=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 +if test "$ac_test_CFLAGS" = set; then + CFLAGS="$ac_save_CFLAGS" +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi + + for ac_prog in $CCC c++ g++ gcc CC cxx cc++ cl +do +# Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1094: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CXX'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CXX"; then + ac_cv_prog_CXX="$CXX" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CXX="$ac_prog" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CXX="$ac_cv_prog_CXX" +if test -n "$CXX"; then + echo "$ac_t""$CXX" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +test -n "$CXX" && break +done +test -n "$CXX" || CXX="gcc" + + +echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works""... $ac_c" 1>&6 +echo "configure:1126: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works" >&5 + +ac_ext=C +# CXXFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='${CXX-g++} -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cxx_cross + +cat > conftest.$ac_ext << EOF + +#line 1137 "configure" +#include "confdefs.h" + +int main(){return(0);} +EOF +if { (eval echo configure:1142: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + ac_cv_prog_cxx_works=yes + # If we can't run a trivial program, we are probably using a cross compiler. + if (./conftest; exit) 2>/dev/null; then + ac_cv_prog_cxx_cross=no + else + ac_cv_prog_cxx_cross=yes + fi +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_cv_prog_cxx_works=no +fi +rm -fr conftest* +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +echo "$ac_t""$ac_cv_prog_cxx_works" 1>&6 +if test $ac_cv_prog_cxx_works = no; then + { echo "configure: error: installation or configuration problem: C++ compiler cannot create executables." 1>&2; exit 1; } +fi +echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 +echo "configure:1168: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "$ac_t""$ac_cv_prog_cxx_cross" 1>&6 +cross_compiling=$ac_cv_prog_cxx_cross + +echo $ac_n "checking whether we are using GNU C++""... $ac_c" 1>&6 +echo "configure:1173: checking whether we are using GNU C++" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_gxx'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.C <<EOF +#ifdef __GNUC__ + yes; +#endif +EOF +if { ac_try='${CXX-g++} -E conftest.C'; { (eval echo configure:1182: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then + ac_cv_prog_gxx=yes +else + ac_cv_prog_gxx=no +fi +fi + +echo "$ac_t""$ac_cv_prog_gxx" 1>&6 + +if test $ac_cv_prog_gxx = yes; then + GXX=yes +else + GXX= +fi + +ac_test_CXXFLAGS="${CXXFLAGS+set}" +ac_save_CXXFLAGS="$CXXFLAGS" +CXXFLAGS= +echo $ac_n "checking whether ${CXX-g++} accepts -g""... $ac_c" 1>&6 +echo "configure:1201: checking whether ${CXX-g++} accepts -g" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_cxx_g'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + echo 'void f(){}' > conftest.cc +if test -z "`${CXX-g++} -g -c conftest.cc 2>&1`"; then + ac_cv_prog_cxx_g=yes +else + ac_cv_prog_cxx_g=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_prog_cxx_g" 1>&6 +if test "$ac_test_CXXFLAGS" = set; then + CXXFLAGS="$ac_save_CXXFLAGS" +elif test $ac_cv_prog_cxx_g = yes; then + if test "$GXX" = yes; then + CXXFLAGS="-g -O2" + else + CXXFLAGS="-g" + fi +else + if test "$GXX" = yes; then + CXXFLAGS="-O2" + else + CXXFLAGS= + fi +fi + +for ac_declaration in \ + ''\ + '#include <stdlib.h>' \ + 'extern "C" void std::exit (int) throw (); using std::exit;' \ + 'extern "C" void std::exit (int); using std::exit;' \ + 'extern "C" void exit (int) throw ();' \ + 'extern "C" void exit (int);' \ + 'void exit (int);' +do + cat > conftest.$ac_ext <<EOF +#line 1242 "configure" +#include "confdefs.h" +#include <stdlib.h> +$ac_declaration +int main() { +exit (42); +; return 0; } +EOF +if { (eval echo configure:1250: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + : +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + continue +fi +rm -f conftest* + cat > conftest.$ac_ext <<EOF +#line 1260 "configure" +#include "confdefs.h" +$ac_declaration +int main() { +exit (42); +; return 0; } +EOF +if { (eval echo configure:1267: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + break +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 +fi +rm -f conftest* +done +if test -n "$ac_declaration"; then + echo '#ifdef __cplusplus' >>confdefs.h + echo $ac_declaration >>confdefs.h + echo '#endif' >>confdefs.h +fi + + + echo $ac_n "checking for object suffix""... $ac_c" 1>&6 +echo "configure:1284: checking for object suffix" >&5 +if eval "test \"`echo '$''{'ac_cv_objext'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + rm -f conftest* +echo 'int i = 1;' > conftest.$ac_ext +if { (eval echo configure:1290: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + for ac_file in conftest.*; do + case $ac_file in + *.c) ;; + *) ac_cv_objext=`echo $ac_file | sed -e s/conftest.//` ;; + esac + done +else + { echo "configure: error: installation or configuration problem; compiler does not work" 1>&2; exit 1; } +fi +rm -f conftest* +fi + +echo "$ac_t""$ac_cv_objext" 1>&6 +OBJEXT=$ac_cv_objext +ac_objext=$ac_cv_objext + + echo $ac_n "checking for Cygwin environment""... $ac_c" 1>&6 +echo "configure:1308: checking for Cygwin environment" >&5 +if eval "test \"`echo '$''{'ac_cv_cygwin'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 1313 "configure" +#include "confdefs.h" + +int main() { + +#ifndef __CYGWIN__ +#define __CYGWIN__ __CYGWIN32__ +#endif +return __CYGWIN__; +; return 0; } +EOF +if { (eval echo configure:1324: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_cygwin=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_cygwin=no +fi +rm -f conftest* +rm -f conftest* +fi + +echo "$ac_t""$ac_cv_cygwin" 1>&6 +CYGWIN= +test "$ac_cv_cygwin" = yes && CYGWIN=yes +echo $ac_n "checking for mingw32 environment""... $ac_c" 1>&6 +echo "configure:1341: checking for mingw32 environment" >&5 +if eval "test \"`echo '$''{'ac_cv_mingw32'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 1346 "configure" +#include "confdefs.h" + +int main() { +return __MINGW32__; +; return 0; } +EOF +if { (eval echo configure:1353: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_mingw32=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_mingw32=no +fi +rm -f conftest* +rm -f conftest* +fi + +echo "$ac_t""$ac_cv_mingw32" 1>&6 +MINGW32= +test "$ac_cv_mingw32" = yes && MINGW32=yes + + +echo $ac_n "checking for executable suffix""... $ac_c" 1>&6 +echo "configure:1372: checking for executable suffix" >&5 +if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$CYGWIN" = yes || test "$MINGW32" = yes; then + ac_cv_exeext=.exe +else + rm -f conftest* + echo 'int main () { return 0; }' > conftest.$ac_ext + ac_cv_exeext= + if { (eval echo configure:1382: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then + for file in conftest.*; do + case $file in + *.c | *.o | *.obj) ;; + *) ac_cv_exeext=`echo $file | sed -e s/conftest//` ;; + esac + done + else + { echo "configure: error: installation or configuration problem: compiler cannot create executables." 1>&2; exit 1; } + fi + rm -f conftest* + test x"${ac_cv_exeext}" = x && ac_cv_exeext=no +fi +fi + +EXEEXT="" +test x"${ac_cv_exeext}" != xno && EXEEXT=${ac_cv_exeext} +echo "$ac_t""${ac_cv_exeext}" 1>&6 +ac_exeext=$EXEEXT + + + ecos_CFLAGS="" + ecos_CXXFLAGS="" + ecos_LDADD="" + ecos_INCLUDES="" + ecos_LIBS="" + + + + + + + + + + + + echo $ac_n "checking "for Visual C++"""... $ac_c" 1>&6 +echo "configure:1420: checking "for Visual C++"" >&5 + MSVC="no"; + if test "${CC}" = "cl" ; then + MSVC="yes" + CXX="cl" + + + + if test "${MSVC}" = "yes" ; then + MSVC_SRCDIR=`cygpath -w ${MSVC_SRCDIR} | tr \\\\\\\\ /` + fi + + + ecos_INCLUDES="${ecos_INCLUDES} \"-I${msvc_srcdir}\"" + ecos_LDADD="-link" + ecos_LIBS="advapi32.lib" + fi + + +if test "${MSVC}" = "yes"; then + MSVC_TRUE= + MSVC_FALSE='#' +else + MSVC_TRUE='#' + MSVC_FALSE= +fi + if test "${MSVC}" = "yes" ; then + echo "$ac_t""unfortunately yes" 1>&6 + else + echo "$ac_t""no" 1>&6 + fi + + + + + + + + echo $ac_n "checking "the default compiler flags"""... $ac_c" 1>&6 +echo "configure:1459: checking "the default compiler flags"" >&5 + + ecosflags_enable_debug="no" + # Check whether --enable-debug or --disable-debug was given. +if test "${enable_debug+set}" = set; then + enableval="$enable_debug" + case "${enableval}" in + yes) ecosflags_enable_debug="yes" ;; + *) ecosflags_enable_debug="no" ;; + esac +fi + + + ecosflags_enable_ansi="no" + if test "${MSVC}" = "yes" ; then + # Check whether --enable-ansi or --disable-ansi was given. +if test "${enable_ansi+set}" = set; then + enableval="$enable_ansi" + case "${enableval}" in + yes) ecosflags_enable_ansi="yes" ;; + *) ecosflags_enable_ansi="no" ;; + esac +fi + + fi + + if test "${GCC}" = "yes" ; then + ecos_CFLAGS="${ecos_CFLAGS} -pipe -Wall -Wpointer-arith -Wbad-function-cast -Wcast-qual -Wstrict-prototypes -Wmissing-prototypes -Wnested-externs" + ecos_CXXFLAGS="${ecos_CXXFLAGS} -pipe -Wall -Wpointer-arith -Wbad-function-cast -Wcast-qual -Wstrict-prototypes -Wmissing-prototypes -Wnested-externs -Woverloaded-virtual" + elif test "${MSVC}" = "yes" ; then + ecos_CFLAGS="${ecos_CFLAGS} -nologo -W3" + ecos_CXXFLAGS="${ecos_CXXFLAGS} -nologo -W3 -GR -GX" + else + { echo "configure: error: "default flags for ${CC} are not known"" 1>&2; exit 1; } + fi + + if test "${ecosflags_enable_debug}" = "yes" ; then + if test "${GCC}" = "yes" ; then + ecos_CFLAGS="${ecos_CFLAGS} -g -O0" + ecos_CXXFLAGS="${ecos_CXXFLAGS} -g -O0" + elif test "${MSVC}" = "yes" ; then + ecos_CFLAGS="${ecos_CFLAGS} -MDd -Zi" + ecos_CXXFLAGS="${ecos_CXXFLAGS} -MDd -Zi" + fi + else + if test "${GCC}" = "yes" ; then + ecos_CFLAGS="${ecos_CFLAGS} -O0" + ecos_CXXFLAGS="${ecos_CXXFLAGS} -O0" + elif test "${MSVC}" = "yes" ; then + ecos_CFLAGS="${ecos_CFLAGS} -MD -O2" + ecos_CXXFLAGS="${ecos_CXXFLAGS} -MD -O2" + fi + fi + + CFLAGS="${ac_save_CFLAGS}" + CXXFLAGS="${ac_save_CXXFLAGS}" + + echo "$ac_t""done" 1>&6 + + + + + + + + ecos_tcl_version="" + ecos_tcl_incdir="" + ecos_tcl_libdir="" + ecos_tk_libs="" + + + echo $ac_n "checking for Tcl version""... $ac_c" 1>&6 +echo "configure:1531: checking for Tcl version" >&5 + # Check whether --with-tcl-version or --without-tcl-version was given. +if test "${with_tcl_version+set}" = set; then + withval="$with_tcl_version" + + ecos_tcl_version=${with_tcl_version} + +else + + if test "${MSVC}" = "yes" ; then + ecos_tcl_version=80 + elif test "${ac_cv_cygwin}" = "yes" ; then + ecos_tcl_version=80 + else + ecos_tcl_version="" + fi + +fi + + echo "$ac_t""${ecos_tcl_version}" 1>&6 + + echo $ac_n "checking for Tcl installation""... $ac_c" 1>&6 +echo "configure:1553: checking for Tcl installation" >&5 + + # Check whether --with-tcl-header or --without-tcl-header was given. +if test "${with_tcl_header+set}" = set; then + withval="$with_tcl_header" + : +fi + + # Check whether --with-tcl-lib or --without-tcl-lib was given. +if test "${with_tcl_lib+set}" = set; then + withval="$with_tcl_lib" + : +fi + + # Check whether --with-tcl or --without-tcl was given. +if test "${with_tcl+set}" = set; then + withval="$with_tcl" + : +fi + + + + if test "${MSVC}" = "yes" ; then + + if test "${with_tcl_header+set}" = set ; then + ecos_tcl_incdir=${with_tcl_header} + elif test "${with_tcl+set}" = set ; then + ecos_tcl_incdir="${with_tcl}/include" + else + { echo "configure: error: You must specify a Tcl installation with either --with-tcl=<path> or --with-tcl-header=<path>" 1>&2; exit 1; } + fi + + if test \! -r "${ecos_tcl_incdir}/tcl.h" ; then + { echo "configure: error: unable to locate Tcl header file tcl.h" 1>&2; exit 1; } + fi + ecos_msvc_tcl_incdir="${ecos_tcl_incdir}" + + + + if test "${MSVC}" = "yes" ; then + ecos_msvc_tcl_incdir=`cygpath -w ${ecos_msvc_tcl_incdir} | tr \\\\\\\\ /` + fi + + ecos_INCLUDES="${ecos_INCLUDES} \"-I${ecos_msvc_tcl_incdir}\"" + + if test "${with_tcl_lib+set}" = set; then + ecos_tcl_libdir=${with_tcl_lib} + elif test "${with_tcl+set}" = set; then + ecos_tcl_libdir="${with_tcl}/lib" + else + { echo "configure: error: You must specify a Tcl installation with either --with-tcl=<path> or --with-tcl-lib=<path>" 1>&2; exit 1; } + fi + + + + if test "${MSVC}" = "yes" ; then + ecos_tcl_libdir=`cygpath -w ${ecos_tcl_libdir} | tr \\\\\\\\ /` + fi + + ecos_LIBS="${ecos_LIBS} tcl${ecos_tcl_version}.lib" + ecos_LDADD="${ecos_LDADD} \"-libpath=${ecos_tcl_libdir}\"" + + ecos_tk_libs="" + + else + possibles="${with_tcl_header} ${with_tcl}/include ${prefix}/include /usr/include/tcl${ecos_tcl_version} /usr/include" + + ecos_tcl_incdir="" + for i in ${possibles}; do + if test -r "$i/"tcl.h""; then + ecos_tcl_incdir=$i + break + fi + done + + if test \! -r "${ecos_tcl_incdir}/tcl.h" ; then + { echo "configure: error: unable to locate Tcl header file tcl.h" 1>&2; exit 1; } + else + if test "${ecos_tcl_incdir}" != "/usr/include" ; then + ecos_INCLUDES="${ecos_INCLUDES} -I${ecos_tcl_incdir}" + fi + fi + possibles="${with_tcl_lib} ${with_tcl}/lib ${libdir} ${prefix}/lib /usr/lib/tcl$${ecos_tcl_version} /usr/lib" + + ecos_tcl_libdir="" + for i in ${possibles}; do + if test -r "$i/"tclConfig.sh""; then + ecos_tcl_libdir=$i + break + fi + done + + if test \! -r "${ecos_tcl_libdir}/tclConfig.sh" ; then + { echo "configure: error: unable to locate Tcl config file tclConfig.sh" 1>&2; exit 1; } + else + . ${ecos_tcl_libdir}/tclConfig.sh + ecos_LIBS="${ecos_LIBS} -ltcl${ecos_tcl_version} ${TCL_LIBS}" + fi + + possible_tk_libdir=`echo ${ecos_tcl_libdir} | sed -e 's,tcl,tk,'` + possibles="${ecos_tcl_libdir} ${possible_tk_libdir}" + + ecos_tk_libdir="" + for i in ${possibles}; do + if test -r "$i/"tkConfig.sh""; then + ecos_tk_libdir=$i + break + fi + done + + if test \! -r "${ecos_tk_libdir}/tkConfig.sh" ; then + { echo "configure: error: unable to locate Tk config file tkConfig.sh" 1>&2; exit 1; } + else + . ${ecos_tk_libdir}/tkConfig.sh + ecos_tk_libs="-ltk${ecos_tcl_version} ${TK_LIBS}" + for lib in ${TCL_LIBS} ; do + ecos_tk_libs=`echo ${ecos_tk_libs} | sed -e "s!${lib}!!"` + done + fi + fi + + echo "$ac_t""-I${ecos_tcl_incdir} -L${ecos_tcl_libdir}" 1>&6 + + + + if test "${TK_MAJOR_VERSION}" = "8" ; then + if test ${TK_MINOR_VERSION} -lt 3 ; then + { echo "configure: error: The synthetic target support requires at least version 8.3 of Tcl/Tk" 1>&2; exit 1; } + fi + fi + + + package_dir=`cd ${srcdir} && /bin/pwd` + PACKAGE_VERSION=`dirname ${package_dir}` + PACKAGE_VERSION=`basename ${PACKAGE_VERSION}` + + package_dir=`dirname ${package_dir}` + package_dir=`dirname ${package_dir}` + + possibles="${package_dir}/.. ${package_dir}/../.. ${package_dir}/../../.. ${package_dir}/../../../.." + possibles="${possibles} ${package_dir}/../../../../.. ${package_dir}/../../../../../.." + + repository_root="" + for i in ${possibles}; do + if test -d "$i/"acsupport""; then + repository_root=$i + break + fi + done + + if test "${repository_root}" = "" ; then + { echo "configure: error: Failed to identify this package's position within the eCos repository" 1>&2; exit 1; } + fi + ECOS_REPOSITORY=`cd "${repository_root}/packages/pkgconf/.." && /bin/pwd` + + PACKAGE_DIR=`echo ${package_dir} | sed -e "s:${ECOS_REPOSITORY}/::"` + + PACKAGE_INSTALL="${PACKAGE_DIR}/${PACKAGE_VERSION}" + + + + + + +fi + + +trap '' 1 2 15 +cat > confcache <<\EOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs. It is not useful on other systems. +# If it contains results you don't want to keep, you may remove or edit it. +# +# By default, configure uses ./config.cache as the cache file, +# creating it if it does not exist already. You can give configure +# the --cache-file=FILE option to use a different cache file; that is +# what configure does when it calls configure scripts in +# subdirectories, so they share the cache. +# Giving --cache-file=/dev/null disables caching, for debugging configure. +# config.status only pays attention to the cache file if you give it the +# --recheck option to rerun configure. +# +EOF +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +(set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote substitution + # turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + -e "s/'/'\\\\''/g" \ + -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' + ;; + esac >> confcache +if cmp -s $cache_file confcache; then + : +else + if test -w $cache_file; then + echo "updating cache $cache_file" + cat confcache > $cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# Any assignment to VPATH causes Sun make to only execute +# the first set of double-colon rules, so remove it if not needed. +# If there is a colon in the path, we need to keep it. +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' +fi + +trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 + +# Transform confdefs.h into DEFS. +# Protect against shell expansion while executing Makefile rules. +# Protect against Makefile macro expansion. +cat > conftest.defs <<\EOF +s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g +s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g +s%\[%\\&%g +s%\]%\\&%g +s%\$%$$%g +EOF +DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '` +rm -f conftest.defs + + +# Without the "./", some shells look in PATH for config.status. +: ${CONFIG_STATUS=./config.status} + +echo creating $CONFIG_STATUS +rm -f $CONFIG_STATUS +cat > $CONFIG_STATUS <<EOF +#! /bin/sh +# Generated automatically by configure. +# Run this file to recreate the current configuration. +# This directory was configured as follows, +# on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# +# $0 $ac_configure_args +# +# Compiler output produced by configure, useful for debugging +# configure, is in ./config.log if it exists. + +ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" +for ac_option +do + case "\$ac_option" in + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" + exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; + -version | --version | --versio | --versi | --vers | --ver | --ve | --v) + echo "$CONFIG_STATUS generated by autoconf version 2.13" + exit 0 ;; + -help | --help | --hel | --he | --h) + echo "\$ac_cs_usage"; exit 0 ;; + *) echo "\$ac_cs_usage"; exit 1 ;; + esac +done + +ac_given_srcdir=$srcdir +ac_given_INSTALL="$INSTALL" + +trap 'rm -fr `echo "Makefile:Makefile.in" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 +EOF +cat >> $CONFIG_STATUS <<EOF + +# Protect against being on the right side of a sed subst in config.status. +sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g; + s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF +$ac_vpsub +$extrasub +s%@SHELL@%$SHELL%g +s%@CFLAGS@%$CFLAGS%g +s%@CPPFLAGS@%$CPPFLAGS%g +s%@CXXFLAGS@%$CXXFLAGS%g +s%@FFLAGS@%$FFLAGS%g +s%@DEFS@%$DEFS%g +s%@LDFLAGS@%$LDFLAGS%g +s%@LIBS@%$LIBS%g +s%@exec_prefix@%$exec_prefix%g +s%@prefix@%$prefix%g +s%@program_transform_name@%$program_transform_name%g +s%@bindir@%$bindir%g +s%@sbindir@%$sbindir%g +s%@libexecdir@%$libexecdir%g +s%@datadir@%$datadir%g +s%@sysconfdir@%$sysconfdir%g +s%@sharedstatedir@%$sharedstatedir%g +s%@localstatedir@%$localstatedir%g +s%@libdir@%$libdir%g +s%@includedir@%$includedir%g +s%@oldincludedir@%$oldincludedir%g +s%@infodir@%$infodir%g +s%@mandir@%$mandir%g +s%@host@%$host%g +s%@host_alias@%$host_alias%g +s%@host_cpu@%$host_cpu%g +s%@host_vendor@%$host_vendor%g +s%@host_os@%$host_os%g +s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g +s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g +s%@INSTALL_DATA@%$INSTALL_DATA%g +s%@PACKAGE@%$PACKAGE%g +s%@VERSION@%$VERSION%g +s%@ACLOCAL@%$ACLOCAL%g +s%@AUTOCONF@%$AUTOCONF%g +s%@AUTOMAKE@%$AUTOMAKE%g +s%@AUTOHEADER@%$AUTOHEADER%g +s%@MAKEINFO@%$MAKEINFO%g +s%@SET_MAKE@%$SET_MAKE%g +s%@MAINTAINER_MODE_TRUE@%$MAINTAINER_MODE_TRUE%g +s%@MAINTAINER_MODE_FALSE@%$MAINTAINER_MODE_FALSE%g +s%@MAINT@%$MAINT%g +s%@SUPPORTED_TRUE@%$SUPPORTED_TRUE%g +s%@SUPPORTED_FALSE@%$SUPPORTED_FALSE%g +s%@CC@%$CC%g +s%@CXX@%$CXX%g +s%@OBJEXT@%$OBJEXT%g +s%@EXEEXT@%$EXEEXT%g +s%@ecos_CFLAGS@%$ecos_CFLAGS%g +s%@ecos_CXXFLAGS@%$ecos_CXXFLAGS%g +s%@ecos_LDADD@%$ecos_LDADD%g +s%@ecos_INCLUDES@%$ecos_INCLUDES%g +s%@ecos_LIBS@%$ecos_LIBS%g +s%@MSVC_SRCDIR@%$MSVC_SRCDIR%g +s%@MSVC_TRUE@%$MSVC_TRUE%g +s%@MSVC_FALSE@%$MSVC_FALSE%g +s%@ecos_tk_libs@%$ecos_tk_libs%g +s%@ECOS_REPOSITORY@%$ECOS_REPOSITORY%g +s%@PACKAGE_DIR@%$PACKAGE_DIR%g +s%@PACKAGE_VERSION@%$PACKAGE_VERSION%g +s%@PACKAGE_INSTALL@%$PACKAGE_INSTALL%g + +CEOF +EOF + +cat >> $CONFIG_STATUS <<\EOF + +# Split the substitutions into bite-sized pieces for seds with +# small command number limits, like on Digital OSF/1 and HP-UX. +ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. +ac_file=1 # Number of current file. +ac_beg=1 # First line for current file. +ac_end=$ac_max_sed_cmds # Line after last line for current file. +ac_more_lines=: +ac_sed_cmds="" +while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file + else + sed "${ac_end}q" conftest.subs > conftest.s$ac_file + fi + if test ! -s conftest.s$ac_file; then + ac_more_lines=false + rm -f conftest.s$ac_file + else + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f conftest.s$ac_file" + else + ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" + fi + ac_file=`expr $ac_file + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_cmds` + fi +done +if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat +fi +EOF + +cat >> $CONFIG_STATUS <<EOF + +CONFIG_FILES=\${CONFIG_FILES-"Makefile:Makefile.in"} +EOF +cat >> $CONFIG_STATUS <<\EOF +for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. + + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" + # A "../" for each directory in $ac_dir_suffix. + ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` + else + ac_dir_suffix= ac_dots= + fi + + case "$ac_given_srcdir" in + .) srcdir=. + if test -z "$ac_dots"; then top_srcdir=. + else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; + /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; + *) # Relative path. + srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" + top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + + case "$ac_given_INSTALL" in + [/$]*) INSTALL="$ac_given_INSTALL" ;; + *) INSTALL="$ac_dots$ac_given_INSTALL" ;; + esac + + echo creating "$ac_file" + rm -f "$ac_file" + configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." + case "$ac_file" in + *Makefile*) ac_comsub="1i\\ +# $configure_input" ;; + *) ac_comsub= ;; + esac + + ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` + sed -e "$ac_comsub +s%@configure_input@%$configure_input%g +s%@srcdir@%$srcdir%g +s%@top_srcdir@%$top_srcdir%g +s%@INSTALL@%$INSTALL%g +" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file +fi; done +rm -f conftest.s* + +EOF +cat >> $CONFIG_STATUS <<EOF + +EOF +cat >> $CONFIG_STATUS <<\EOF + +exit 0 +EOF +chmod +x $CONFIG_STATUS +rm -fr confdefs* $ac_clean_files +test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 +
new file mode 100644 --- /dev/null +++ b/packages/hal/synth/arch/current/host/configure.in @@ -0,0 +1,93 @@ +dnl Process this file with autoconf to produce a configure script. +dnl ==================================================================== +dnl +dnl configure.in +dnl +dnl configure script for eCos synthetic target architectural +dnl host-side support +dnl +dnl ==================================================================== +dnl####COPYRIGHTBEGIN#### +dnl +dnl ---------------------------------------------------------------------------- +dnl Copyright (C) 2002 Bart Veer +dnl +dnl This file is part of the eCos synthetic target support. +dnl +dnl This program is free software; you can redistribute it and/or modify it +dnl under the terms of the GNU General Public License as published by the Free +dnl Software Foundation; either version 2 of the License, or (at your option) +dnl any later version. +dnl +dnl This program is distributed in the hope that it will be useful, but WITHOUT +dnl ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +dnl FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +dnl more details. +dnl +dnl You should have received a copy of the GNU General Public License along with +dnl this program; if not, write to the Free Software Foundation, Inc., +dnl 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +dnl +dnl ---------------------------------------------------------------------------- +dnl +dnl####COPYRIGHTEND#### +dnl ==================================================================== +dnl#####DESCRIPTIONBEGIN#### +dnl +dnl Author(s): bartv +dnl Contact(s): bartv +dnl Date: 2002/08/06 +dnl Version: 0.01 +dnl +dnl####DESCRIPTIONEND#### +dnl ==================================================================== + + +AC_INIT(ecosynth.c) + +dnl Pick up the support files from the top-level acsupport directory. +AC_CONFIG_AUX_DIR(../../../../../../acsupport) + +ECOS_CHECK_BUILD_ne_SRC +AC_CANONICAL_HOST +AM_INIT_AUTOMAKE(eCos_synthetic_target_arch,0.1,0) +AM_MAINTAINER_MODE + +dnl The current version of the synthetic target is implemented only for +dnl x86 Linux platforms, so a test is appropriate here. However +dnl it is not a good idea for the configure script to report an error: +dnl that would prevent any top-level configury working for other +dnl platforms. Instead an automake conditional is used to suppress adding +dnl targets to the build. +case "${host}" in + i[[34567]]86-*-linux-gnu* ) SUPPORTED="yes";; + * ) SUPPORTED="no" +esac +AM_CONDITIONAL(SUPPORTED, test "${SUPPORTED}" = "yes") + +if test "${SUPPORTED}" = "yes" ; then + AC_PROG_CC + AC_PROG_CXX + AC_OBJEXT + AC_EXEEXT + ECOS_PROG_MSVC + ECOS_PROG_STANDARD_COMPILER_FLAGS + + ECOS_PATH_TCL + dnl Check that the version of tk is sufficiently recent. + dnl For example the text widget's tag -elide facility was + dnl added between 8.2 and 8.3. Initial development of + dnl the synthetic target used 8.3.1 + if test "${TK_MAJOR_VERSION}" = "8" ; then + if test ${TK_MINOR_VERSION} -lt 3 ; then + AC_MSG_ERROR([The synthetic target support requires at least version 8.3 of Tcl/Tk]) + fi + fi + ECOS_PACKAGE_DIRS +fi + +dnl There is no real need for a config.h file at this time, since the code +dnl is specific to x86 Linux. This may change in future. +dnl AM_CONFIG_HEADER(config.h:config.h.in) + +AC_OUTPUT(Makefile:Makefile.in)
new file mode 100644 --- /dev/null +++ b/packages/hal/synth/arch/current/host/console.tcl @@ -0,0 +1,198 @@ +# {{{ Banner + +# ============================================================================ +# +# console.tcl +# +# Console output support for the eCos synthetic target I/O auxiliary +# +# ============================================================================ +# ####COPYRIGHTBEGIN#### +# +# ---------------------------------------------------------------------------- +# Copyright (C) 2002 Bart Veer +# +# This file is part of the eCos host tools. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the Free +# Software Foundation; either version 2 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, write to the Free Software Foundation, Inc., +# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# ---------------------------------------------------------------------------- +# +# ####COPYRIGHTEND#### +# ============================================================================ +# #####DESCRIPTIONBEGIN#### +# +# Author(s): bartv +# Contact(s): bartv +# Date: 2002/08/07 +# Version: 0.01 +# Description: +# Implementation of the console device. This script should only ever +# be run from inside the ecosynth auxiliary. +# +# ####DESCRIPTIONEND#### +# ============================================================================ + +# }}} + +# The console device is pretty simple. There can only ever be one +# instance of the console, and it does not take any initialization +# data from the target or from command-line arguments. It does +# look for entries in the target definition file, to set up +# colours for console output, and to install additional regexp-based +# filters. The only type of request that can go to the console device +# is to write some text. + +namespace eval ::console { + + variable _pending_output "" + variable filter_count 0 + array set filters [list] + + proc instantiate { id name data } { + # There is only console so no name is expected, and the target + # cannot provide any initialization data. + if { ("" != $name) || ("" != $data) } { + synth::report_error "The target has passed invalid data when instantiating the console device.\n" + return "" + } + + # There are no command line arguments to be processed and consumed. + + # Look for and consume target definition entries related to the console. + # These are only actually applicable when running in GUI mode, but + # should always be consumed. + set console_appearance "" + + if { [synth::tdf_has_device "console"] } { + if { [synth::tdf_has_option "console" "appearance"] } { + set console_appearance [synth::tdf_get_option "console" "appearance"] + } + + if { [synth::tdf_has_option "console" "filter"] } { + set tdf_filters [synth::tdf_get_options "console" "filter"] + foreach filter $tdf_filters { + if { 2 > [llength $filter] } { + set msg "Invalid entry in target definition file $synth::target_definition\n" + append msg " Device console, option filter takes at least two arguments, a name and a regular expression.\n" + synth::report_error $msg + } else { + # Attempt some minimal validation of the regexp + set name [lindex $filter 0] + set regexp [lindex $filter 1] + set error "" + if { [catch { regexp -- $regexp "Hello world\n" } error] } { + set msg "Invalid entry in target definition file $synth::target_definition\n" + append msg " Device console, filter $name, invalid regular expression\n $error\n" + synth::report_error $msg + } else { + set ::console::filters($::console::filter_count,name) $name + set ::console::filters($::console::filter_count,regexp) $regexp + set ::console::filters($::console::filter_count,appearance) [lrange $filter 2 end] + incr ::console::filter_count + } + } + } + } + } + + # If the GUI is enabled then set up a filter for the console, and + # any additional filters specified in the target definition file + # for e.g. trace output. + if { $synth::flag_gui } { + if { [synth::filter_exists "console" ] } { + synth::report_warning "The console device script [info script] cannot create a filter for \"console\".\nThis filter already exists.\n" + } elseif { "" == $console_appearance } { + synth::filter_add "console" + } else { + array set parsed_options [list] + set message "" + if { ![synth::filter_parse_options $console_appearance parsed_options message] } { + synth::report_error \ + "Invalid entry in target definition file $synth::target_definition\ + \n synth_device \"console\", entry \"appearance\"\n$message" + } else { + synth::filter_add_parsed "console" parsed_options + } + } + + for { set i 0 } { $i < $::console::filter_count } { incr i } { + set name $::console::filters($i,name) + set appearance $::console::filters($i,appearance) + array unset parsed_options + array set parsed_options [list] + + if { [synth::filter_exists $name] } { + synth::report_warning "The console device script [info script] cannot create a filter for \"$name\".\nThis filter already exists.\n" + } else { + set message "" + if { ![synth::filter_parse_options $appearance parsed_options message] } { + synth::report_error \ + "Invalid entry in target definition file $synth::target_definition\ + \n synth_device \"console\", entry filter $name\n$message" + } else { + synth::filter_add_parsed $name parsed_options + } + } + } + } + + # An instantiation function should return a handler for further requests + # to this device instance. + return console::handle_request + } + + proc handle_request { id reqcode arg1 arg2 reqdata reqlen reply_len } { + # Unfortunately the main eCos diagnostic code assumes it is + # talking to a tty in raw mode, since typically the output + # will go via the gdb output window. Hence it will have inserted + # carriage returns which are best filtered out here. + set reqdata [string map {"\r" " "} $reqdata] + + # The output should be processed one line at a time, to make it + # easier to write the regexp filters. + append console::_pending_output $reqdata + while { -1 != [string first "\n" $console::_pending_output] } { + set regexp_matched 0 + set index [string first "\n" $console::_pending_output] + set line [string range $console::_pending_output 0 $index] + set ::console::_pending_output [string range $console::_pending_output [expr $index + 1] end] + + for { set i 0 } { !$regexp_matched && ($i < $console::filter_count) } { incr i } { + if { [regexp -- $console::filters($i,regexp) $line] } { + synth::output $line $console::filters($i,name) + set regexp_matched 1 + } + } + if { ! $regexp_matched } { + synth::output $line "console" + } + } + } + + # Deal with the case where eCos has exited after sending only part + # of a line, which is still pending. In practice this has no + # effect at present because the data is still buffered inside + # eCos. + proc _flush { arg_list } { + if { "" != $console::_pending_output } { + synth::output "$console::_pending_output\n" "console" + } + } + synth::hook_add "ecos_exit" console::_flush + +} + +return console::instantiate
new file mode 100644 --- /dev/null +++ b/packages/hal/synth/arch/current/host/copy.xbm @@ -0,0 +1,6 @@ +#define copy_width 16 +#define copy_height 15 +static unsigned char copy_bits[] = { + 0x00, 0x00, 0x7e, 0x00, 0xc2, 0x00, 0x42, 0x01, 0xda, 0x0f, 0x82, 0x30, + 0xfa, 0xd0, 0x82, 0xf6, 0xfa, 0x80, 0x82, 0xbe, 0xfe, 0x80, 0x80, 0xbe, + 0x80, 0x80, 0x80, 0xff, 0x00, 0x00};
new file mode 100644 --- /dev/null +++ b/packages/hal/synth/arch/current/host/cut.xbm @@ -0,0 +1,6 @@ +#define cut_width 16 +#define cut_height 15 +static unsigned char cut_bits[] = { + 0x00, 0x00, 0x20, 0x02, 0x20, 0x02, 0x20, 0x02, 0x60, 0x03, 0x40, 0x01, + 0xc0, 0x01, 0x80, 0x00, 0xc0, 0x00, 0x40, 0x07, 0x70, 0x09, 0x48, 0x09, + 0x48, 0x09, 0x48, 0x06, 0x30, 0x00};
new file mode 100644 --- /dev/null +++ b/packages/hal/synth/arch/current/host/default.tdf @@ -0,0 +1,43 @@ +# Default synthetic target hardware definition file. This file gets +# installed alongside ecosynth.tcl and other support files in the +# directory $(libexecdir)/ecos/hal_synth_arch_<version>. +# +# The synthetic target support will look for the target definition +# file in various places: first the current directory, then +# ~/.ecos/synth, finally the install location as above. It assumes the +# file is called "default.tdf", unless this is overwritten on the +# command line using the -t or --target option. Typically users will +# make a copy of the default target definition in an appropriate +# location and then modify this copy as required. +# +# This file only contains support for those devices supported by the +# core package: the console, ... Additional devices such as the +# ethernet support which live in separate eCos packages may have their +# own example fragments which can be inserted in the user's own target +# definition file, directly or via e.g. a Tcl "source" command. +# +# This file is executed in a Tcl interpreter with an additional +# command "synth_device", so Tcl syntax applies and the full +# functionality provided by Tcl interpreters is available if desired. + +# ---------------------------------------------------------------------------- +# The console device. This serves as the destination for low-level +# eCos text output, for example from the diag_printf() function, +# and is intended primarily for diagnostics and debugging. +# +# The appearance of normal console output can be controlled by +# the "appearance" option. This takes the standard arguments for +# text filters, for example -foreground and -background. +# +# It is also possible to install new filters for specific types +# of output, for example eCos tracing output. Each such filter +# is defined by a name, a regular expression, and details of +# the desired appearance. Every line of console output generated +# by eCos is matched against the various regular expressions, +# and the first match found controls the appearance of the +# output. + +synth_device console { + # appearance -foreground white -background black + filter trace {^TRACE:.*} -foreground HotPink1 -hide 1 +} \ No newline at end of file
new file mode 100644 --- /dev/null +++ b/packages/hal/synth/arch/current/host/ecosicon.xbm @@ -0,0 +1,10 @@ +#define ecosicon_width 40 +#define ecosicon_height 16 +static unsigned char ecosicon_bits[] = { + 0xfc, 0xff, 0xab, 0xaa, 0x2a, 0xfe, 0xff, 0x53, 0x55, 0x55, 0xff, 0xff, + 0xab, 0xaa, 0xaa, 0x87, 0x1f, 0x52, 0x50, 0x40, 0x03, 0x0f, 0x28, 0x20, + 0x80, 0x71, 0xc6, 0x11, 0x41, 0x14, 0x79, 0xe6, 0x8b, 0x22, 0xaa, 0x01, + 0xe6, 0x17, 0x45, 0x40, 0x01, 0xe6, 0x8f, 0xa2, 0x80, 0xf9, 0xe7, 0x13, + 0x45, 0x15, 0x79, 0xc6, 0x09, 0x22, 0x8a, 0x03, 0x0e, 0x10, 0x50, 0x00, + 0x07, 0x1f, 0x2a, 0xa8, 0x80, 0xff, 0xff, 0x53, 0x55, 0x55, 0xfe, 0xff, + 0xab, 0xaa, 0x2a, 0xfc, 0xff, 0x53, 0x55, 0x15};
new file mode 100644 --- /dev/null +++ b/packages/hal/synth/arch/current/host/ecosiconmask.xbm @@ -0,0 +1,10 @@ +#define ecosiconmask_width 40 +#define ecosiconmask_height 16 +static unsigned char ecosiconmask_bits[] = { + 0xfc, 0xff, 0xff, 0xff, 0x3f, 0xfe, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, + 0xff, 0xff, 0x7f, 0xfc, 0xff, 0xff, 0xff, 0x3f};
new file mode 100644 --- /dev/null +++ b/packages/hal/synth/arch/current/host/ecosynth.c @@ -0,0 +1,364 @@ +//============================================================================ +// +// ecosynth.c +// +// The eCos synthetic target I/O auxiliary +// +//============================================================================ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 2002 Bart Veer +// +// This file is part of the eCos host tools. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// ---------------------------------------------------------------------------- +// +//####COPYRIGHTEND#### +//============================================================================ +//#####DESCRIPTIONBEGIN#### +// +// Author(s): bartv +// Contact(s): bartv +// Date: 2002-08-05 +// Version: 0.01 +// Description: +// +// The main module for the eCos synthetic target auxiliary. This +// program is fork'ed and execve'd during the initialization phase of +// any synthetic target application, and is primarily responsible for +// I/O operations. This program should never be run directly by a +// user. +// +//####DESCRIPTIONEND#### +//============================================================================ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <signal.h> +#include <limits.h> +#include <unistd.h> +#include <assert.h> +#include <fcntl.h> +#include <sys/param.h> +#include <sys/types.h> +#include <tcl.h> +#include <tk.h> + +// The protocol between host and target is defined by a private +// target-side header. +#include "../src/synth_protocol.h" + +// ---------------------------------------------------------------------------- +// Statics etc. +#define PROGNAME "Synthetic target auxiliary" + +static int no_windows = 0; // -nw arg + +static pid_t parent_pid; + +// ---------------------------------------------------------------------------- +// Overview. +// +// When a synthetic target application is executed, whether directly +// or from inside gdb, it can fork() and execve() the synthetic +// target auxiliary: this program, ecosynth. For now this is disabled +// by default but can be enabled using a --io option on the command line. +// In future it may be enabled by default, but can be suppressed using +// --nio. +// +// stdin, stdout, and stderr will be inherited from the eCos application, so +// that attempts to use printf() or fprintf(stderr, ) from inside the +// auxiliary or its helper applications work as expected. In addition file +// descriptor 3 will be a pipe from the eCos application, and file descriptor +// 4 will be a pipe to the application. The protocol defined in +// ../src/synth_protocol.h runs over these pip +// +// argv[] and environ are also as per the application, with the exception +// of argv[0] which is the full path to this application. +// +// The bulk of the hard work is done inside Tcl. The C++ code is +// responsible only for initialization and for implementing some +// additional commands, for example to send a SIGIO signal to the +// parent when there is a new pending interrupt. The primary script is +// ecosynth.tcl which should be installed alongside the executable. +// +// This code makes use of the standard Tcl initialization facilities: +// +// 1) main() calls Tcl_Main() with the command-line arguments and an +// application-specific initialization routine ecosynth_appinit(). +// +// 2) Tcl_Main() goes through the initialization sequence in generic/tclMain.c. +// There is one slight complication: Tcl_main() interprets arguments in +// a way that makes sense for tclsh, but not for ecosynth. Specially if +// argv[1] exists and does not begin with a - then it will be interpreted +// as a script to be executed. Hence argv[] is re-allocated and the name +// of a suitable script is inserted. +// +// 3) ecosynth_appinit() initializes the Tcl interpreter, and optionally +// the Tk interpreter as well. This is controlled by the presence of +// a -nw argument on the command line. This initialization routine +// also takes care of adding some commands to the Tcl interpreter. +// +// 4) Tcl_Main() will now proceed to execute the startup script, which +// is eccentric.tcl installed in the libexec directory. + +static int ecosynth_appinit(Tcl_Interp*); + +int +main(int argc, char** argv) +{ + char ecosynth_tcl_path[_POSIX_PATH_MAX]; + char** new_argv; + int i; + + parent_pid = getppid(); + + // The various core Tcl scripts are installed in the same + // directory as ecosynth. The Tcl script itself will check whether + // there is a newer version of itself in the source tree and + // switch to that instead. + assert((strlen(LIBEXECDIR) + strlen(PACKAGE_INSTALL) + 20) < _POSIX_PATH_MAX); + strcpy(ecosynth_tcl_path, LIBEXECDIR); + strcat(ecosynth_tcl_path, "/ecos/"); + strcat(ecosynth_tcl_path, PACKAGE_INSTALL); + strcat(ecosynth_tcl_path, "/ecosynth.tcl"); + + // Installation sanity checks. + if (0 != access(ecosynth_tcl_path, F_OK)) { + fprintf(stderr, PROGNAME ": error, a required Tcl script has not been installed.\n"); + fprintf(stderr, " The script is \"%s\"\n", ecosynth_tcl_path); + exit(EXIT_FAILURE); + } + if (0 != access(ecosynth_tcl_path, R_OK)) { + fprintf(stderr, PROGNAME ": error, no read access to a required Tcl script.\n"); + fprintf(stderr, " The script is \"%s\"\n", ecosynth_tcl_path); + exit(EXIT_FAILURE); + } + + // Look for options -nw and -w. This information is needed by the appinit() routine. + no_windows = 0; + for (i = 1; i < argc; i++) { + if ((0 == strcmp("-nw", argv[i])) || (0 == strcmp("--nw", argv[i])) || + (0 == strcmp("-no-windows", argv[i])) || (0 == strcmp("--no-windows", argv[i]))) { + no_windows = 1; + } else if ((0 == strcmp("-w", argv[i])) || (0 == strcmp("--w", argv[i])) || + (0 == strcmp("-windows", argv[i])) || (0 == strcmp("--windows", argv[i]))) { + no_windows = 0; + } + } + + new_argv = malloc((argc+2) * sizeof(char*)); + if (NULL == new_argv) { + fprintf(stderr, PROGNAME ": internal error, out of memory.\n"); + exit(EXIT_FAILURE); + } + new_argv[0] = argv[0]; + new_argv[1] = ecosynth_tcl_path; + for (i = 1; i < argc; i++) { + new_argv[i+1] = argv[i]; + } + new_argv[i+1] = NULL; + + // Ignore SIGINT requests. Those can happen if e.g. the application is + // ctrl-C'd or if a gdb session is interrupted because this process is + // a child of the eCos application. Instead the normal code for handling + // application termination needs to run. + signal(SIGINT, SIG_IGN); + + // Similarly ignore SIGTSTP if running in graphical mode, it would + // be inappropriate for the GUI to freeze if the eCos application is + // suspended. If running in text mode then it is better for both + // the application and the I/O auxiliary to freeze, halting any further + // output. + if (!no_windows) { + signal(SIGTSTP, SIG_IGN); + } + + Tcl_Main(argc+1, new_argv, &ecosynth_appinit); + return EXIT_SUCCESS; +} + + +// ---------------------------------------------------------------------------- +// Commands for the Tcl interpreter. These are few and far between because +// as much work as possible is done in Tcl. + +// Send a SIGIO signal to the parent process. This is done whenever a new +// interrupt is pending. There is a possibility of strange behaviour if +// the synthetic target application is exiting at just the wrong moment +// and this process has become a zombie. An alternative approach would +// involve loading the Extended Tcl extension. +static int +ecosynth_send_SIGIO(ClientData clientData __attribute__ ((unused)), + Tcl_Interp* interp, + int argc, + char** argv __attribute__ ((unused))) +{ + if (1 != argc) { + Tcl_SetResult(interp, "wrong # args: should be \"usbtest::_send_SIGIO\"" , TCL_STATIC); + return TCL_ERROR; + } + + (void) kill(parent_pid, SIGIO); + return TCL_OK; +} + +// Similarly send a SIGKILL (-9) to the parent process. This allows the GUI +// code to kill of the eCos application +static int +ecosynth_send_SIGKILL(ClientData clientData __attribute__ ((unused)), + Tcl_Interp* interp, + int argc, + char** argv __attribute__ ((unused))) +{ + if (1 != argc) { + Tcl_SetResult(interp, "wrong # args: should be \"usbtest::_send_SIGIO\"" , TCL_STATIC); + return TCL_ERROR; + } + + (void) kill(parent_pid, SIGKILL); + return TCL_OK; +} + + +// ---------------------------------------------------------------------------- +// Application-specific initialization. + +static int +ecosynth_appinit(Tcl_Interp* interp) +{ + Tcl_Channel from_app; + Tcl_Channel to_app; + + // Tcl library initialization. This has the effect of executing init.tcl, + // thus setting up package load paths etc. Not all of that initialization + // is necessarily appropriate for ecosynth, but some devices may well want + // to load in additional packages or whatever. + if (Tcl_Init(interp) == TCL_ERROR) { + return TCL_ERROR; + } + // Optionally initialize Tk as well. This can be suppressed by an + // argument -nw. Possibly this could be done by the Tcl script + // instead using dynamic loading. + // + // There is a problem with the way that Tk does its argument processing. + // By default it will accept abbreviations for the standard wish arguments, + // so if the user specifies e.g. -v then the Tk code will interpret this + // as an abbreviation for -visual, and will probably complain because + // -visual takes an argument whereas ecosynth's -v is just a flag. + // + // The Tk argument processing can be suppressed simply by temporarily + // getting rid of the argv variable. The disadvantage is that some + // standard arguments now have to be processed explicitly: + // + // -colormap map ignored, of little interest these days + // -display display currently ignored. This would have to be + // implemented at the C level, not the Tcl level, + // since Tk_Init() will start interacting with the + // X server. Its implementation would involve a + // setenv() call. + // -geometry geom implemented in the Tcl code using "wm geometry" + // -name name ignored for now. + // -sync ignored, of little interest to typical users + // -use id ignored, probably of little interest for now + // -visual visual ignored, of little interest these days + // + // so actually the only extra work that is required is for the Tcl code + // to process -geometry. + if (!no_windows) { + Tcl_Obj* argv = Tcl_GetVar2Ex(interp, "argv", NULL, TCL_GLOBAL_ONLY); + Tcl_IncrRefCount(argv); + Tcl_UnsetVar(interp, "argv", TCL_GLOBAL_ONLY); + if (Tk_Init(interp) == TCL_ERROR) { + return TCL_ERROR; + } + Tcl_SetVar2Ex(interp, "argv", NULL, argv, TCL_GLOBAL_ONLY); + Tcl_DecrRefCount(argv); + } + + // Create the synth:: namespace. Currently this does not seem to be possible from + // inside C. + if (TCL_OK != Tcl_Eval(interp, + "namespace eval synth {\n" + " variable channel_from_app 0\n" + " variable channel_to_app 0\n" + "}\n")) { + fprintf(stderr, PROGNAME ": internal error, failed to create Tcl synth:: namespace\n"); + fprintf(stderr, " Please check Tcl version (8.3 or later required).\n"); + exit(EXIT_FAILURE); + } + + // The pipe to/from the application is exposed to Tcl, allowing + // the main communication to be handled at the Tcl level and + // specifically via the event loop. This requires two additional + // Tcl channels to be created for file descriptors 3 and 4. + from_app = Tcl_MakeFileChannel((ClientData) 3, TCL_READABLE); + if (NULL == from_app) { + fprintf(stderr, PROGNAME ": internal error, failed to create Tcl channel for pipe from application.\n"); + exit(EXIT_FAILURE); + } + Tcl_RegisterChannel(interp, from_app); + + // The channel name will be something like file0. Add a variable to the + // interpreter to store this name. + if (NULL == Tcl_SetVar(interp, "synth::_channel_from_app", Tcl_GetChannelName(from_app), TCL_GLOBAL_ONLY)) { + fprintf(stderr, PROGNAME ": internal error, failed to create Tcl variable from application channel 0\n"); + exit(EXIT_FAILURE); + } + + // Repeat for the channel to the application. + to_app = Tcl_MakeFileChannel((ClientData) 4, TCL_WRITABLE); + if (NULL == to_app) { + fprintf(stderr, PROGNAME ": internal error, failed to create Tcl channel for pipe to application.\n"); + exit(EXIT_FAILURE); + } + Tcl_RegisterChannel(interp, to_app); + if (NULL == Tcl_SetVar(interp, "synth::_channel_to_app", Tcl_GetChannelName(to_app), TCL_GLOBAL_ONLY)) { + fprintf(stderr, PROGNAME ": internal error, failed to create Tcl variable from application channel 1\n"); + exit(EXIT_FAILURE); + } + + // The auxiliary may spawn additional programs, via + // device-specific scripts. Those programs should not have + // direct access to the pipe - that would just lead to + // confusion. + fcntl(3, F_SETFD, FD_CLOEXEC); + fcntl(4, F_SETFD, FD_CLOEXEC); + + // Add synthetic target-specific commands to the Tcl interpreter. + Tcl_CreateCommand(interp, "synth::_send_SIGIO", &ecosynth_send_SIGIO, (ClientData)NULL, (Tcl_CmdDeleteProc*) NULL); + Tcl_CreateCommand(interp, "synth::_send_SIGKILL", &ecosynth_send_SIGKILL, (ClientData)NULL, (Tcl_CmdDeleteProc*) NULL); + + // Define additional variables. + + // The version, from the AM_INIT_AUTOMAKE() macro in configure.in + Tcl_SetVar(interp, "synth::_ecosynth_version", ECOSYNTH_VERSION, TCL_GLOBAL_ONLY); + + // The parent process id, i.e. that for the eCos application itself. + Tcl_SetVar2Ex(interp, "synth::_ppid", NULL, Tcl_NewIntObj(getppid()), TCL_GLOBAL_ONLY); + + // The various directories + Tcl_SetVar(interp, "synth::_ecosynth_repository", ECOS_REPOSITORY, TCL_GLOBAL_ONLY); + Tcl_SetVar(interp, "synth::_ecosynth_libexecdir", LIBEXECDIR, TCL_GLOBAL_ONLY); + Tcl_SetVar(interp, "synth::_ecosynth_package_dir", PACKAGE_DIR, TCL_GLOBAL_ONLY); + Tcl_SetVar(interp, "synth::_ecosynth_package_version", PACKAGE_VERSION, TCL_GLOBAL_ONLY); + Tcl_SetVar(interp, "synth::_ecosynth_package_install", PACKAGE_INSTALL, TCL_GLOBAL_ONLY); + + return TCL_OK; +}
new file mode 100644 --- /dev/null +++ b/packages/hal/synth/arch/current/host/ecosynth.tcl @@ -0,0 +1,3292 @@ +# {{{ Banner + +# ============================================================================ +# +# ecosynth.tcl +# +# The eCos synthetic target I/O auxiliary +# +# ============================================================================ +# ####COPYRIGHTBEGIN#### +# +# ---------------------------------------------------------------------------- +# Copyright (C) 2002 Bart Veer +# +# This file is part of the eCos host tools. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the Free +# Software Foundation; either version 2 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, write to the Free Software Foundation, Inc., +# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# ---------------------------------------------------------------------------- +# +# ####COPYRIGHTEND#### +# ============================================================================ +# #####DESCRIPTIONBEGIN#### +# +# Author(s): bartv +# Contact(s): bartv +# Date: 2002/08/05 +# Version: 0.01 +# Description: +# The main script for the eCos synthetic target auxiliary. This should +# only ever be invoked from inside ecosynth. +# +# ####DESCRIPTIONEND#### +# ============================================================================ + +# }}} + +# {{{ Overview + +# When an eCos synthetic target application runs it will usually +# fork/execve an auxiliary program, ecosynth, to provide certain +# I/O functionality. This happens as part of hardware initialization. +# +# The ecosynth executable in turn runs this ecosynth.tcl script which +# either does most of the real work or delegates it to other scripts. +# Those other scripts may in turn exec other programs to perform any +# I/O operations that cannot easily be done at the Tcl level. For +# example performing low-level ethernet operations generally requires +# working at the C level or equivalent, so a separate executable would +# be appropriate. The ecosynth executable will transfer control to +# this script after the appinit() call, which should have performed +# certain initialization steps. +# +# 1) the Tcl interpreter will be fully initialized. +# +# 2) usually Tk will have been loaded and initialized as well. This +# can be suppressed using a command-line option -nw. +# +# 3) there will be a namespace synth:: for use by ecosynth.tcl +# Auxiliary scripts are expected to use their own namespace +# where possible. +# +# 4) there will be two channels synth::_channel_from_app and +# synth::_channel_to_app. These correspond to a pipe between +# the eCos application and the auxiliary. The application will +# send requests using this pipe and expect replies. I/O +# operations are always initiated by a request from the +# application, but the auxiliary can raise an interrupt via +# the SIGIO signal. +# +# Other standard channels stdin, stdout and stderr will have +# been inherited from the eCos application. +# +# 5) some Tcl commands implemented in C will have been added to the +# interpreter. The most notable is synth::_send_SIGIO, used to +# raise an interrupt within the application. +# +# 6) similarly some variables will have been added to the interpreter. +# +# +# Configuring everything can get somewhat complicated. It is the eCos +# application that knows what I/O facilities within the auxiliary it +# wants to access, but it may not know all the details. The eCos +# component architecture makes things a bit more complicated still, +# generic code such as this ecosynth.tcl script has no way of knowing +# what I/O facilities might be provided by some package or other. +# +# For example, a target-side ethernet driver may want to send outgoing +# ethernet packets to some script or program on the host and receive +# incoming ethernet packets. However it does not necessarily know what +# the host-side should do with those ethernet packets, e.g. use a +# spare Linux ethernet device, use the Linux kernel's ethertap +# facility, ... Although that kind of information could be handled by +# target-side configury, host-side configuration files will often be +# more appropriate. Specifically it would allow a single eCos +# synthetic target application to run in a variety of environments, +# using different ways to provide the I/O, with no need to do any +# reconfiguring or rebuilding of the target side. +# +# +# The basic approach that is taken is: +# +# 1) the eCos application tells the auxiliary what I/O facilities +# it is interested in. This should happen as a result +# of static constructors or of device driver initialization +# routines. The application has no control over the implementation +# of the I/O facilities, it just expects something on the other +# end to respond sensibly to requests. +# +# For example, a synthetic target ethernet driver will supply +# an initialization routine via its NETDEVTAB_ENTRY. This +# routine will send a request to the auxiliary asking for a +# device of type ethernet, id "eth0", provided by +# CYGPKG_DEVS_ETH_ECOSYNTH, version current. The auxiliary will +# now attempt to load a suitable Tcl script ethernet.tcl from a +# location determined using the package name and version. +# +# 2) there is a primary target definition file which can be +# specified as the final argument on the command line, with +# "default" being the default value. The code will look for +# this file with or without a .tdf extension, first in the +# current directory, then in ~/.ecos/synth/. This file is +# actually a Tcl script that gets executed in the current +# interpreter. However typically it will only contain +# entries such as: +# +# synth_device eth0 { +# ... +# } +# +# 3) There are additional optional configuration files +# ~/.ecos/synth/initrc.tcl and ~/.ecos/synth/mainrc.tcl which can +# be used for further customization. initrc.tcl will get run +# early on, mainrc.tcl will get run once initialization is +# complete. Specifically the target-side code will send an +# appropriate request after invoking all the static constructors. +# At this time the auxiliary will run mainrc.tcl, and in addition +# it may issue warnings about unused arguments etc. +# +# 4) there may also be separate configuration files for GUI +# preferences etc. These are distinct from the initrc and +# mainrc files in that they are generated rather than +# hand-written. + +# }}} +# {{{ Basic initialization + +# ---------------------------------------------------------------------------- +# There should be two channels corresponding to the pipe between the +# eCos application and the auxiliary. These should be configured +# appropriately. If either channel does not exist then that is a +# very good indication that the system is not properly initialized, +# i.e. that this script is not being run by the ecosynth executable +# and by implication that no eCos application is involved. + +if {([info exists synth::_channel_to_app] == 0) || + ([info exists synth::_channel_from_app] == 0) || + ([info exists synth::_ecosynth_version] == 0) || + ([info exists synth::_ppid] == 0) || + ([info exists synth::_ecosynth_repository] == 0) || + ([info exists synth::_ecosynth_libexecdir] == 0) || + ([info exists synth::_ecosynth_package_dir] == 0) || + ([info exists synth::_ecosynth_package_version] == 0) || + ([info exists synth::_ecosynth_package_install] == 0) || + ([info commands synth::_send_SIGIO] == "") || + ([info commands synth::_send_SIGKILL] == "") } { + + puts stderr "ecosynth.tcl: the current interpreter has not been properly initialized." + puts stderr " This script should only be invoked by the ecosynth executable when" + puts stderr " an eCos synthetic target application is run." + exit 1 +} + +# Is the script currently being executed the most recent version? +# This check should only happen if an environment variable +# ECOSYNTH_DEVEL is set, because the installed tools may have come +# from somewhere other than the current repository. +if { [info exists ::env(ECOSYNTH_DEVEL)] } { + set _orig_name [file join $synth::_ecosynth_repository $synth::_ecosynth_package_dir $synth::_ecosynth_package_version \ + "host" [file tail [info script]]] + if { [file exists $_orig_name] && [file readable $_orig_name] && ($_orig_name != [info script]) } { + if { [file mtime $_orig_name] >= [file mtime [info script]] } { + puts "$_orig_name is more recent than install: executing that." + source $_orig_name + return + } + } + unset _orig_name +} + +fconfigure $synth::_channel_to_app -buffering none +fconfigure $synth::_channel_from_app -encoding binary +fconfigure $synth::_channel_to_app -encoding binary +fconfigure $synth::_channel_from_app -translation binary +fconfigure $synth::_channel_to_app -translation binary + +# Define additional globals and procedures inside the synth:: namespace. +# Variables and functions that begin with an _ are considered internal +# and should not be used directly. +namespace eval synth { + + # Unfortunately the name of the eCos executable is lost at this stage. + # Within the eCos application it was held in argv[0], but that has been + # overridden with the name of the auxiliary. However we have access to the + # parent process id so we can use /proc to get the required information. + variable ecos_appname "" + catch { + set synth::ecos_appname [file readlink "/proc/[set synth::_ppid]/exe"] + set synth::ecos_appname [file tail $synth::ecos_appname] + } + + # The install location can be determined from the script name. + # This is used for e.g. loading bitmaps, even if ECOSYNTH_DEVEL + # is set, because some of the files may be generated. + # ECOSYNTH_DEVEL only affects Tcl scripts. + variable install_dir [file join $synth::_ecosynth_libexecdir "ecos" $synth::_ecosynth_package_install] + + # Is the eCos application still running? This is worth keeping + # track of so that send_reply and raise_interrupt do not try to + # interact with a program that is no longer running. + variable ecos_running 1 + + # This variable is used to enter the event loop + variable _ecosynth_exit 0 + + # Is GUI mode enabled? + variable flag_gui [expr { "" != [info commands "tk"] } ] + + # When running in GUI mode the GUI should stay up even after the application + # has exited, so that the user can take a good look around. When running in + # non-GUI mode this program should exit as soon it has finished cleaning up. + variable flag_immediate_exit [expr { 0 == $synth::flag_gui} ] + + # Is the GUI ready to accept output? + variable flag_gui_ready 0 + + # Flags and variables related to command-line arguments + variable flag_help 0 + variable flag_keep_going 0 + variable flag_no_rc 0 + variable flag_verbose 0 + variable flag_debug 0 + variable logfile "" + variable target_definition "" + variable geometry "<none>" +} + +# }}} +# {{{ Hooks & atexit support + +# ---------------------------------------------------------------------------- +# A lot of the flexibility of ecosynth is provided by hooks. Device scripts +# and, more importantly, the per-user initrc and mainrc scripts can install +# hooks that get called when an event occurs, for example when the eCos +# applications attempts to transmit an ethernet packet. +# +# A special hook is used to implement atexit handling. This involves redefining +# the "exit" command so that it will invoke the appropriate hooks first. + +namespace eval synth { + # All hooks are held in an array, indexed by the hook name, with each + # array entry being a list of functions to be invoked. + array set _hooks [list] + + proc hook_define { name } { + if { [info exists synth::_hooks($name)] } { + synth::report_error "Attempt to create hook $name which already exists.\n" + } else { + set synth::_hooks($name) [list] + } + } + + proc hook_defined { name } { + return [info exists synth::_hooks($name)] + } + + proc hook_add { name function } { + if { ! [info exists synth::_hooks($name)] } { + synth::report_error "Attempt to attach a function to an unknown hook $name\n" + set synth::_hooks($name) [list] + } + lappend synth::_hooks($name) $function + } + + proc hook_call { name args } { + if { ! [info exists synth::_hooks($name) ] } { + synth::report_error "Attempt to invoke unknown hook $name\n" + } else { + foreach function $synth::_hooks($name) { + $function $args + } + } + } + + # Define an initial set of hooks + synth::hook_define "exit" ;# The auxiliary is exiting + synth::hook_define "ecos_exit" ;# The eCos application has exited + synth::hook_define "ecos_initialized" ;# eCos static constructors have run + synth::hook_define "help" ;# --help +} + +# Rename the builtin exit command so that it can still be accessed. +rename exit _hook_real_exit + +# And define a replacement for exit which will invoke the appropriate +# hook. Care has to be taken in case of recursive exit calls, each +# hook function is only called once. + +proc exit { { code 0 } } { + while { [llength $synth::_hooks(exit)] > 0 } { + set handler [lindex $synth::_hooks(exit) end] + set synth::_hooks(exit) [lrange $synth::_hooks(exit) 0 end-1] + + # For now assume no errors - it is not clear what could be done + # about them anyway. + catch { eval $handler [list]} + } + _hook_real_exit $code +} + +# }}} +# {{{ Output + +# ---------------------------------------------------------------------------- +# The usual set of utilities for issuing warnings, errors, ... +# +# There are three possibilities to consider: +# +# 1) running in text-only mode. The output should just go to stdout +# +# 2) running in GUI mode and the text window exists. Just update the +# window +# +# 3) running in GUI mode but the text window is not yet ready. The +# output needs to be buffered for now, and will be flushed +# later. +# +# Also, if for some reason this program exits while there is output still +# buffered that output should also go to stdout. +# +# If any errors occur during initialization, e.g. an invalid device script +# or user initialization scripts, those get reported and an error count +# is maintained. When the eCos application reports that initialization is +# complete it will be sent back a status for the auxiliary, and will +# exit if things have not started up correctly. This tries to ensure that +# if there are multiple errors the user sees all of them. + +namespace eval synth { + + variable _pending_output [list] + variable _logfd "" + variable _error_count 0 + + proc logfile_open { } { + synth::report "Opening logfile $synth::logfile" + set msg "" + if { [catch { set synth::_logfd [open $synth::logfile "w"] } msg ] } { + synth::report_error "Unable to open logfile \"$synth::logfile\"\n $msg\n" + } + } + + # A default implementation of output. This gets overwritten later when running + # in GUI mode, so if GUI mode is enabled then this proc must be called before + # the GUI is ready and the data must be queued. + proc output { msg filter } { + if { ! $synth::flag_gui } { + # If a logfile exists, output normally goes there rather than + # to standard output. The exception is for errors which + # always go to stderr, in addition to the logfile. + if { "" != $synth::_logfd } { + puts -nonewline $synth::_logfd $msg + if { "error" == $filter } { + puts -nonewline stderr $msg + } + } else { + if { "error" == $filter } { + puts -nonewline stderr $msg + } else { + puts -nonewline $msg + } + } + } else { + lappend synth::_pending_output [list $msg $filter] + } + } + + # Invoked by the text window code once everything is ready + # and synth::output has been redefined. + proc _flush_output { } { + foreach msg $synth::_pending_output { + synth::output [lindex $msg 0] [lindex $msg 1] + } + set synth::_pending_output [list] + } + + # Cope with early exits. This will only have an effect if + # _flush_output has not been called yet, and by implication + # if synth::output has not yet been redefined. + proc _exit_flush_output { arg_list } { + if { 0 != [llength $synth::_pending_output] } { + set synth::flag_gui 0 + synth::_flush_output + } + } + synth::hook_add "exit" synth::_exit_flush_output + + proc report { msg } { + synth::output $msg "report" + } + + proc report_warning { msg } { + synth::output "Warning: $msg" "warning" + } + + proc report_error { msg } { + incr synth::_error_count + synth::output "Error: $msg" "error" + } + + # Internal errors indicate a serious problem within ecosynth or + # a device-specific script. For now this results in output to + # stderr, a backtrace, and termination of the auxiliary, which + # should also cause the eCos application to shut down. + # + # An alternative approach would involve calling ::error and + # benefitting from its backtrace generation, but there are various + # places where it makes to sense to catch problems and call + # synth::error rather than internal_error + proc internal_error { msg } { + puts stderr "ecosynth, an internal error has occurred:" + puts stderr " $msg" + puts stderr "---------- backtrace -------------------------------------------------" + for { set level [info level] } { $level > 0 } { incr level -1 } { + puts stderr [info level $level] + } + puts stderr "----------------------------------------------------------------------" + puts stderr "ecosynth, exiting." + exit 1 + } + + # Dummy implementations of the exported filter routines, in case a script + # tries to create a filter even when not running in graphical mode + variable _dummy_filters [list] + + proc filter_exists { name } { + set result 0 + if { -1 != [lsearch -exact $synth::_dummy_filters $name] } { + set result 1 + } + return $result + } + + proc filter_get_list { } { + return $synth::_dummy_filters + } + + proc filter_add { name args } { + if { [synth::filter_exists $name] } { + synth::internal_error "attempt to install filter $name twice.\n" + } + lappend synth::_dummy_filters $name + } +} + +# }}} +# {{{ Argument processing and global options + +# ---------------------------------------------------------------------------- +# Argument processing. The eCos application will usually just pass its +# command line arguments to the auxiliary. Four special arguments will +# have been examined already: +# +# -io, --io +# I/O facilities, i.e. the auxiliary should run +# -ni, -nio, --ni, --nio +# No I/O facilities, i.e. the auxiliary should not be run. +# -nw, --nw, --no-windows +# No windows, i.e. disable the GUI +# -w, --w, --windows +# Enable the GUI +# +# There are a number of additional flags available as standard: +# +# -v, --version +# The usual +# -h, --help +# Ditto +# -k, --k, --keep-going +# Ignore errors as much as possible +# -nr, --no-rc +# Skip the initrc and mainrc files +# -x, --exit +# The auxiliary should exit at the same time as the eCos application. +# -nx, --no-exit +# Inverse of the above +# -V, --verbose +# The usual +# --debug +# Not intended for end users +# -l <file>, -l=<file>, --logfile <file>, --logfile=<file> +# Send all output to the specified file. In GUI mode this is in addition +# to the main text window. In non-GUI mode this is instead of stdout. +# -t <file>, -t=<file>, --target <file>, --target=<file> +# Specify the target definition file. +# +# Many X applications accept a common set of options, e.g. -display, +# -geometry, etc. Although usually Tk will process these, there are +# some problems - see ecosynth.c, ecosynth_appinit() for details. +# Hence -geometry has to be processed here. +# +# -geometry <geom> +# +# +# Some device-specific scripts may want to support additional +# command line arguments. This is somewhat messy, since the core +# code has no way of knowing what devices might be available and +# hence what the actual valid arguments are. It would be possible +# to just ignore any arguments that are not used by any device, +# but that could really confuse a user who has made a typo. Instead +# the code below keeps track of which arguments have been "consumed", +# allowing it to issue a warning about unconsumed arguments after +# initialization. +# +# Arguments can take the following forms: +# +# 1) -flag or --flag. +# 2) -name=value or --name=value +# 3) -name value or --name value +# +# There is a possibility of confusion if any of the values begin with a hyphen. +# It is hard to do anything about this without advance knowledge of what all +# the valid arguments are. Instead the user can avoid problems by using +# the -name=value variant on the command line. +# +# There is also possible confusion if a single argument can occur multiple +# times. If that is permitted then things can get rather messy, and +# the current API does not really handle it. + +namespace eval synth { + + # Keep track of all arguments which have not yet been consumed. + array set _argv_unconsumed [list] + for { set i 0 } { $i < $::argc } { incr i } { + set synth::_argv_unconsumed($i) [lindex $::argv $i] + } + + # Provide a list of just those arguments that have not yet + # been consumed. + proc argv_get_unconsumed { } { + set result [list] + for { set i 0 } { $i < $::argc } {incr i } { + if { [info exists synth::_argv_unconsumed($i)] } { + lappend result $synth::_argv_unconsumed($i) + } + } + return $result + } + + proc _argv_consume { index } { + if { [info exists synth::_argv_unconsumed($index)] } { + unset synth::_argv_unconsumed($index) + } + } + + # Internal routine. Given a string of the form "-flag" or "-name=", + # return an index within argv or -1 if not found. As a side effect + # this "consumes" the argument. + proc _argv_lookup { name } { + set result -1 + if { "=" != [string index $name end] } { + for { set i 0 } { $i < $::argc } { incr i } { + set arg [lindex $::argv $i] + if { [string equal $arg $name] || [string equal $arg "-[set name]"] } { + set result $i + synth::_argv_consume $i + break + } + } + } else { + set name [string range $name 0 end-1] + set len [string length $name] + for { set i 0 } { $i < $::argc } { incr i } { + set arg [lindex $::argv $i] + if { [string equal -length $len $arg $name] } { + if { "=" == [string index $arg $len] } { + set result $i + synth::_argv_consume $i + break; + } elseif { ([string length $arg] == $len) && ($i < ($::argc - 1)) } { + set result $i + synth::_argv_consume $i + synth::_argv_consume [expr $i + 1] + break + } + } elseif { [string equal -length [expr $len + 1] $arg "-[set name]"] } { + if { "=" == [string index $arg [expr $len + 1]] } { + set result $i + synth::_argv_consume $i + break + } elseif { ([string length $arg] == [expr $len + 1]) && ($i < ($::argc - 1)) } { + set result $i + synth::_argv_consume $i + synth::_argv_consume [expr $i + 1] + break + } + } + } + } + return $result + } + + # Look for a given argument on the command line. + proc argv_defined { name } { + set result 0 + set index [synth::_argv_lookup $name] + if { -1 != $index } { + set result 1 + } + return $result + } + + # Return the value associated with a given argument, which must be present. + proc argv_get_value { name } { + if { "=" != [string index $name end] } { + synth::internal_error "attempt to get a value for a simple flag argument \"$name\".\n" + } + set result "" + set index [synth::_argv_lookup $name] + if { -1 == $index } { + synth::internal_error "attempt to get the value associated with a non-existent argument \"$name\".\n" + } + set arg [lindex $::argv $index] + set len [string length $name] + if { [string equal -length $len $arg $name] } { + set result [string range $arg $len end] + } elseif { [string equal -length [expr $len + 1] $arg "-[set name]"] } { + set result [string range $arg [expr $len + 1] end] + } else { + set result [lindex $::argv [expr $index + 1]] + } + return $result + } + + # -ni/-nio are not relevant. If present then they would have been handled + # within the eCos application, the auxiliary would not have been spawned, + # and this script would not be running. + + # -io will have been processed by the eCos application. + # -nw, -w, and related options have been processed by the C code. + # Look them up anyway to consume them. + synth::_argv_lookup "-io" + synth::_argv_lookup "-nw" + synth::_argv_lookup "-no-windows" + synth::_argv_lookup "-w" + synth::_argv_lookup "-windows" + + # Now cope with the other standard flags + if { [synth::argv_defined "-v"] || [synth::argv_defined "--version"] } { + # Just output the version message and exit. The eCos application + # will do the same. The version is obtained from configure.in, + # and also from the install directory. The synthetic target + # startup code will exit quietly if the auxiliary exits at this + # stage. This output should go via puts rather than the + # synth:: output routines, since the GUI will never appear if + # --version is specified. + puts "ecosynth: version $synth::_ecosynth_version" + puts " : install location [file dirname [info script]]" + exit 0 + } + + if { [synth::argv_defined "-l="] } { + set synth::logfile [synth::argv_get_value "-l="] + } elseif { [synth::argv_defined "-logfile="] } { + set synth::logfile [synth::argv_get_value "-logfile="] + } + if { "" != $synth::logfile } { + synth::logfile_open + } + + # -h/--help would normally also result in an immediate exit. However, + # the device-specific scripts have not yet been loaded so there + # is no way of reporting their options. Hence the usage information + # is delayed until later. Suppressing GUI mode as a side effect is + # probably a good idea as well, that way the output appears in the + # current console window. + if { [synth::argv_defined "-h"] || [synth::argv_defined "-help"] } { + set synth::flag_help 1 + set synth::flag_gui 0 + } + + if { [synth::argv_defined "-debug"] } { + set synth::flag_debug 1 + } + + if { [synth::argv_defined "-k"] || [synth::argv_defined "-keep-going"] } { + set synth::flag_keep_going 1 + } + + if { [synth::argv_defined "-nr"] || [synth::argv_defined "-no-rc"]} { + set synth::flag_no_rc 1 + } + + if { [synth::argv_defined "-x"] || [synth::argv_defined "-exit"] } { + set synth::flag_immediate_exit 1 + } elseif { [synth::argv_defined "-nx"] || [synth::argv_defined "-no-exit"] } { + set synth::flag_immediate_exit 0 + } + + if { [synth::argv_defined "-V"] || [synth::argv_defined "-verbose"] } { + set synth::flag_verbose 1 + } + + if { [synth::argv_defined "-t="] } { + set synth::target_definition [synth::argv_get_value "-t="] + } elseif { [synth::argv_defined "-target="] } { + set synth::target_definition [synth::argv_get_value "-target="] + } + + # Arguably -geometry should only be checked when the GUI is enabled, + # but doing so at all times is harmless. + # Note that '-geometry ""' means that any value held in the + # preferences file should be ignored. Hence the regexp below + # accepts the empty string, and treats it separately from + # uninitialized. + if { [synth::argv_defined "-geometry="] } { + set synth::geometry [synth::argv_get_value "-geometry="] + + if { ![regexp -- {^([0-9]+x[0-9]+)?([+-][0-9]+[+-][0-9]+)?$} $synth::geometry] } { + synth::report_warning "Invalid geometry string $synth::geometry\n" + set synth::geometry "<none>" + } + } + + if { $synth::flag_debug } { + synth::report \ + "Results of initial command-line parsing:\n \ + --help $synth::flag_help\n \ + --keep-going $synth::flag_keep_going\n \ + --no-rc $synth::flag_no_rc\n \ + --exit $synth::flag_immediate_exit\n \ + --verbose $synth::flag_verbose\n \ + logfile $synth::logfile\n \ + target definition $synth::target_definition\n \ + geometry $synth::geometry\n \ + unconsumed [synth::get_unconsumed_args]\n" + } +} + +# }}} +# {{{ Create and populate ~/.ecos/synth + +# ---------------------------------------------------------------------------- +# If the per-user configuration directories do not exist yet, create them. +# Also install default initrc.tcl and mainrc.tcl files which do nothing, but +# which can be edited. If problems occur then the user gets a warning +# but execution proceeds. +# +# Some people may object to this automatic creation of directories and +# configuration files. However there is plenty of precedent, and the +# files involved are small. Messages are generated so that the user +# knows what has happened. +# +# Currently the default target definition file is not copied from +# the install tree into the per-user tree. Although some users will +# be happy having this file in ~/.ecos/synth, others may prefer it +# to be more visible in the current directory. + +if { ![file exists "~/.ecos"] } { + synth::report "Creating new directory ~/.ecos for eCos configuration files.\n" + if { 0 != [catch { file mkdir "~/.ecos" }] } { + synth::report_warning "failed to create directory ~/.ecos\n" + } +} +if { [file exists "~/.ecos"] && [file isdirectory "~/.ecos"] && ![file exists "~/.ecos/synth"] } { + synth::report "Creating new directory ~/.ecos/synth for synthetic target configuration files.\n" + if { 0 != [catch { file mkdir "~/.ecos/synth" } ] } { + synth::report_warning "failed to create directory ~/.ecos/synth\n" + } else { + # initrc and mainrc are only copied when the directory is first created, + # so that users can delete them if unwanted - even though the + # default versions do nothing. + synth::report "Installing default configuration files ~/.ecos/synth/initrc.tcl and ~/.ecos/synth/mainrc.tcl\n" + catch { file copy -- [file join $synth::install_dir "user_initrc.tcl"] "~/.ecos/synth/initrc.tcl"} + catch { file copy -- [file join $synth::install_dir "user_mainrc.tcl"] "~/.ecos/synth/mainrc.tcl"} + } +} + +# }}} +# {{{ Read target definition file + +# ---------------------------------------------------------------------------- +# Once the GUI is up and running it is possible to start reading in some +# configuration files. The first of these is the target definition file. +# Typically this would be ~/.ecos/synth/default.tdf. An alternative +# definition file can be specified on the command line with the +# -t argument, and the code will look in the current directory, +# in ~/.ecos/synth, and in the install tree. +# +# The purpose of the target definition file is to specify exactly +# how I/O gets implemented. For example the eCos application may +# want to access a network device eth0, but that device could be +# implemented in a variety of ways (e.g. a real ethernet device +# on the Linux host, or a fake device provided by the ethertap +# facility). It is the target definition file that provides +# this information. +# +# The file is of course just another Tcl script, running in the +# current interpreter. There seems little point in using a safe +# interpreter given the considerable number of other Tcl scripts +# that are being used, some of which need the ability to e.g. +# run other programs. The main command is synth_device which +# takes two arguments, a device name and some options for that +# device, e.g.: +# +# synth_device eth0 { +# use eth1 +# } +# +# synth_device eth1 { +# use tap0 +# } +# +# When the eCos device driver looks up eth0 this will cause a +# device-specific Tcl script to be loaded, which can examine +# this data. +# +# This code has no way of knowing what constitutes valid or invalid +# contents for an eth0 device, especially since the Tcl script that +# could provide such knowledge has not been loaded. Instead it is +# assumed that the contents is another set of Tcl commands such as +# "physical", which will of course not be defined so the Tcl interpreter +# will invoke "unknown" which is temporarily redefined here. This makes +# it possible for the device-specific commands to have arbitrary number +# of arguments, or to define Tcl fragments for hooks, or whatever. +# +# As with argument processing, the code attempts to keep track of +# which devices and options have been "consumed" and can issue +# warnings about any unused devices or options. This helps to track +# down typos and similar problems. These warnings are only output +# when running at verbose mode, since it is fairly normal practice +# to have a single target definition file which supports +# a number of different eCos applications with different I/O +# requirements. + +namespace eval synth { + # A list of all devices specified in the target definition file. + # For now assume that a given device will only be specified once. + variable _tdf_devices [list] + + # An array with additional details of each device. This will have + # entries such as _tdf_device_options(eth0,4), where the second + # argument is a per-device index. The value of each entry is + # a list of the actual command and its arguments. This use of + # an index allows for multiple instances of a per-device + # option. + array set _tdf_device_options [list] + + # While reading in the device details it is necessary to keep track + # of the current device, if any. Otherwise the implementation of + # "unknown" will not be able to update _tdf_device_options. An index + # is needed as well. + variable _tdf_current_device "" + variable _tdf_current_index 0 + + # Keep track of which devices and options have been consumed + variable _tdf_consumed_devices [list] + variable _tdf_consumed_options [list] + + proc tdf_has_device { name } { + return [expr -1 != [lsearch -exact $synth::_tdf_devices $name]] + } + + proc tdf_get_devices { } { + return $synth::_tdf_devices + } + + proc _tdf_get_option_index { devname option } { + synth::_tdf_consume_device $devname + for { set i 0 } { [info exists synth::_tdf_device_options($devname,$i)] } { incr i } { + if { $option == [lindex $synth::_tdf_device_options($devname,$i) 0] } { + synth::_tdf_consume_option $devname $i + return $i + } + } + return -1 + } + + proc _tdf_get_option_indices { devname option } { + synth::_tdf_consume_device $devname + set result [list] + for { set i 0 } { [info exists synth::_tdf_device_options($devname,$i)] } { incr i } { + if { $option == [lindex $synth::_tdf_device_options($devname,$i) 0] } { + synth::_tdf_consume_option $devname $i + lappend result $i + } + } + return $result + } + + proc tdf_has_option { devname option } { + return [expr -1 != [synth::_tdf_get_option_index $devname $option]] + } + + proc tdf_get_option { devname option } { + set index [synth::_tdf_get_option_index $devname $option] + if { -1 != $index } { + lappend synth::_tdf_consumed_options "$devname,$index" + return [lrange $synth::_tdf_device_options($devname,$index) 1 end] + } else { + return [list] + } + } + + proc tdf_get_options { devname option } { + set result [list] + set indices [synth::_tdf_get_option_indices $devname $option] + foreach index $indices { + lappend result [lrange $synth::_tdf_device_options($devname,$index) 1 end] + } + return $result + } + + proc tdf_get_all_options { devname } { + set result [list] + for { set i 0 } { [info exists synth::_tdf_device_options($devname,$i)] } { incr i } { + lappend synth::_tdf_consumed_options "$devname,$index" + lappend result $synth::_tdf_device_options($devname,$i) + } + return $result + } + + proc _tdf_consume_device { name } { + if { -1 == [lsearch -exact $synth::_tdf_consumed_devices $name] } { + lappend synth::_tdf_consumed_devices $name + } + } + + proc _tdf_consume_option { devname index } { + if { -1 == [lsearch -exact $synth::_tdf_consumed_options "$devname,$index"] } { + lappend synth::_tdf_consumed_options "$devname,$index" + } + } + + proc tdf_get_unconsumed_devices { } { + set result [list] + foreach devname $synth::_tdf_devices { + if { -1 == [lsearch -exact $synth::_tdf_consumed_devices $devname] } { + lappend result $devname + } + } + return $result + } + + proc tdf_get_unconsumed_options { } { + set result [list] + foreach devname $synth::_tdf_devices { + if { -1 == [lsearch -exact $synth::_tdf_consumed_devices $devname] } { + # Do not report all the options for a device that has not been consumed at all + continue + } + for { set i 0 } { [info exists synth::_tdf_device_options($devname,$i)] } { incr i } { + if { -1 == [lsearch -exact $synth::_tdf_consumed_options "$devname,$i"] } { + lappend result [list $devname $synth::_tdf_device_options($devname,$i)] + } + } + } + return $result + } +} + +# Look for the target definition file. +set _tdf $synth::target_definition +if { "" == $_tdf } { + set _tdf "default" +} +set _config_file "" + +set _dirlist [list [pwd] "~/.ecos/synth" $synth::install_dir] +foreach _dir $_dirlist { + set _candidate "[file join $_dir $_tdf].tdf" ; # file join does the right thing for absolute paths + if { [file isfile $_candidate] } { + set _config_file $_candidate + break + } else { + set _candidate [file join $_dir $_tdf] + if { [file isfile $_candidate] } { + set _config_file $_candidate + break + } + } +} +if { "" == $_config_file } { + if { "" != $synth::target_definition } { + # The user explicitly specified a file, so it must be read in. + # If it cannot be found then that should be treated as an error. + set msg "Unable to find target definition file $synth::target_definition\n" + if { "absolute" != [file pathtype $synth::target_definition] } { + append msg " Searched $_dirlist\n" + } + synth::report_error $msg + exit 1 + } else { + # This is a mild error, because default.tdf should be installed + # below libexec. However the default file does not actually + # define anything, it is just a set of comments, so there is + # nothing to be gained by issuing a warning. + } +} else { + + set synth::target_definition $_config_file + + proc synth_device { name data } { + if { "" != $synth::_tdf_current_device } { + error "synth_device $name is nested inside $synth::_tdf_current_device\nNesting of synth_device entries is not allowed." + } + if { -1 != [lsearch -exact $synth::_tdf_devices $name] } { + error "Duplicate entry for synth_device $name" + } + set synth::_tdf_current_device $name + set synth::_tdf_current_index 0 + lappend synth::_tdf_devices $name + eval $data + # If the eval resulted in an error, propagate it immediately rather than attempt + # any form of recovery. The downside is that only error per run will be + # reported. + set synth::_tdf_current_device "" + } + rename unknown _synth_unknown + proc unknown { args } { + if { "" == $synth::_tdf_current_device } { + # An unknown command at the toplevel. Pass this to the + # original "unknown" command, in the unlikely event that + # the user really did want to autoload a library or do + # something similar. + eval _synth_unknown $arg + return + } + + # Anything else is treated as an option within the synth_device + set synth::_tdf_device_options($synth::_tdf_current_device,$synth::_tdf_current_index) $args + incr synth::_tdf_current_index + } + + set _config_file_msg "" + set _result [catch { source $_config_file } _config_file_msg ] + + rename unknown "" + rename synth_device "" + rename _synth_unknown unknown + + if { $_result } { + # Any problems reading in the target definition file should be + # treated as an error: I/O is unlikely to behave in the way + # that the user expects. + set msg "An error occurred while reading in the target definition file\n $_config_file\n $_config_file_msg\n" + synth::report_error $msg + exit 1 + } + unset _result _config_file_msg +} + +unset _dirlist _tdf _config_file _candidate + +# }}} + +if { $synth::flag_gui } { +# {{{ Main GUI code + +# {{{ Session file + +# ---------------------------------------------------------------------------- +# The tool manages a file ~/.ecos/synth/guisession, holding information +# such as the size and position of the main window. The aim is to give +# the user a fairly consistent interface between sessions. The information +# is saved during exit handling, and also in response to the window +# manager WM_SAVE_YOURSELF request. However note that the latter does +# not extend to user session information - restarting the eCos application +# the next time a user logs in is inappropriate for eCos, plus if +# the application is being run inside gdb (a likely scenario) it is gdb +# that should handle restarting the application. +# +# Using a single file has limitations. Specifically the user may be +# switching between a number of different target definition files, +# each resulting in a subtly different layout, and arguably there +# should be separate session information for each one. However +# distinguishing between per-target and global settings would be +# very complicated. +# +# The most obvious implementation involves the options database. +# +# FIXME: implement properly + +namespace eval synth { + # Make sure we are using the right options from .Xdefaults etc. + tk appname "ecosynth" + + if { $synth::flag_debug } { + # synth::report "Reading in session file ~/.ecos/synth/guisession\n" + } + + # synth::report_warning "Support for reading session file ~/.ecos/synth/guisession not yet implemented.\n" + + if { [file exists "~/.ecos/synth/guisession"] } { + if {0 != [catch { option readfile "~/.ecos/synth/guisession" userDefault} msg]} { + # synth::report_error "Failed to read GUI session information from file ~/.ecos/synth/guisession\n $msg\n" + } + } + + proc _update_session_file { arg_list } { + # synth::report_warning "Support for updating session file ~/.ecos/synth/guisession not yet implemented.\n" + } + proc _handle_wm_save_yourself { } { + # synth::report_warning "Support for WM_SAVE_YOURSELF not yet implemented\n" + } + + synth::hook_add "exit" synth::_update_session_file +} + +# }}} +# {{{ Load images + +# ---------------------------------------------------------------------------- +# Load various useful bitmaps etc. into memory, so that they can be accessed +# by any code that needs them. +# +# Running1 is a coloured version of the eCos logo. running2 and running3 are +# used by alternative implementations of the heartbeat: running2 has the +# red and black reversed, and running3 is mostly a mirror image of the normal +# logo. +namespace eval synth { + + proc load_image { image_name filename } { + set result 0 + set type [file extension $filename] + if { ! [file exists $filename] } { + synth::report_error "Image $filename has not been installed.\n" + } elseif { ! [file readable $filename] } { + synth::report_error "Image $filename is not readable.\n" + } elseif { (".xbm" == $type) } { + if { 0 == [catch { set $image_name [image create bitmap -file $filename] }] } { + set result 1 + } else { + synth::report_error "Bitmap image $filename is invalid.\n" + } + } else { + if { 0 == [catch { set $image_name [image create photo -file $filename] }] } { + set result 1 + } else { + synth::report_error "Image $filename is invalid.\n" + } + } + return $result + } + + set _images [list "tick_yes.xbm" "tick_no.xbm" "save.xbm" "cut.xbm" "copy.xbm" "paste.xbm" \ + "help.xbm" "running1.ppm" "saveall.xbm" ] + foreach _image $_images { + variable image_[file rootname $_image] + synth::load_image "synth::image_[file rootname $_image]" [file join $synth::install_dir $_image] + } + unset _images _image +} + +# }}} +# {{{ Balloon help + +namespace eval synth { + + variable _balloon_messages + variable _balloon_pending "" + + toplevel .balloon + label .balloon.info -borderwidth 2 -relief groove -background "light yellow" + pack .balloon.info -side left -fill both -expand 1 + wm overrideredirect .balloon 1 + wm withdraw .balloon + + proc register_balloon_help { widget message } { + set synth::_balloon_messages($widget) $message + bind $widget <Enter> { synth::_balloonhelp_pending %W } + bind $widget <Leave> { synth::_balloonhelp_cancel } + } + + proc _balloonhelp_pending { widget } { + synth::_balloonhelp_cancel + set synth::_balloon_pending [after 1200 [list synth::_balloonhelp_show $widget]] + } + + proc _balloonhelp_cancel { } { + if { "" != $synth::_balloon_pending } { + after cancel $synth::_balloon_pending + set synth::_balloon_pending "" + } else { + wm withdraw .balloon + } + } + + proc _balloonhelp_show { widget } { + .balloon.info configure -text $synth::_balloon_messages($widget) + set x [expr [winfo rootx $widget] + 2] + set y [expr [winfo rooty $widget] + [winfo height $widget] + 2] + wm geometry .balloon +$x+$y + wm deiconify .balloon + raise .balloon + set synth::_balloon_pending "" + } +} + +# }}} +# {{{ Window manager settings + +# ---------------------------------------------------------------------------- +# Set up the current program name in the title bar etc. + +namespace eval synth { + + if { $synth::flag_debug } { + synth::report "Performing required interactions with window manager\n" + } + + # The toplevel is withdrawn during startup. It is possible that + # some of the windows and other objects created initially will end + # up being deleted again before the system is fully up and running, + # and the event loop is entered before then to accept requests from + # the eCos application. This could cause confusing changes. The + # toplevel is displayed in response to the constructors-done request. + wm withdraw . + + # For now disable all attempts to use the "send" command. Leaving it + # enabled would introduce security problems. + rename "::send" {} + + variable title "eCos synthetic target" + if { "" != $synth::ecos_appname} { + append synth::title ": $synth::ecos_appname ($synth::_ppid)" + } + wm title . $synth::title + + # Use the specified geometry, or that from the last session. + # Obviously how well this works depends very much on the + # window manager being used. + set _geometry "" + if { "" == $synth::geometry} { + # Command line request to suppress the preferences. Revert + # to a default size. + set _geometry "640x480" + } elseif { "<none>" == $synth::geometry } { + # No command line option, use the value from the preferences file + # FIXME: implement + set _geometry "640x480" + } else { + # There was an explicit -geometry option on the command line. Use it. + set synth::_geometry $synth::geometry + if { [regexp -- {^([0-9]+x[0-9]+).*$} $synth::_geometry] } { + wm sizefrom . "user" + } + if { [regexp -- {^.*([+-][0-9]+[+-][0-9]+)$} $synth::_geometry] } { + wm positionfrom . "user" + } + } + wm geometry . $synth::_geometry + unset synth::_geometry + + set _file [file join $synth::install_dir "ecosicon.xbm"] + if { [file readable $synth::_file] } { + wm iconbitmap . "@$synth::_file" + } + set _file [file join $synth::install_dir "ecosiconmask.xbm"] + if { [file readable $synth::_file] } { + wm iconmask . "@$synth::_file" + } + unset synth::_file + + if { "" != $synth::ecos_appname } { + wm iconname . "ecosynth: $synth::ecos_appname" + } else { + wm iconname . "ecosynth" + } + + wm protocol . "WM_DELETE_WINDOW" synth::_handle_exit_request + wm protocol . "WM_SAVE_YOURSELF" synth::_handle_wm_save_yourself +} + +# }}} +# {{{ Exit and kill handling + +# ---------------------------------------------------------------------------- +# Exit handling. The user may request program termination using various +# different ways: +# 1) File->Exit +# 2) ctrl-Q, the shortcut for the above +# 3) the Window Manager's delete-window request +# +# If eCos has already exited then the request can be handled straightaway. +# The invocation of exit will go via the exit hooks so appropriate +# clean-ups will take place. +# +# If eCos has not already exited then it is assumed that the user wants +# the eCos application to terminate as well as the GUI. This can be achieved +# via the interrupt subsystem. However, there is a risk that the application +# has crashed, or is blocked in gdb, or has interrupts permanently disabled, +# in which case it is not going to respond to the SIGIO. To allow for this +# a number of retries are attempted, and after five seconds of this the +# application is killed off forcibly. + +namespace eval synth { + + variable _handle_exit_retries 0 + variable _handle_exit_after "" + + proc _handle_exit_request { } { + + if { !$synth::ecos_running } { + exit 0 + } + # Setting this flag causes ecosynth to exit immediately once + # the application terminates. + set synth::flag_immediate_exit 1 + + # Now ask the application to exit + synth::request_application_exit + + # Set up a timer to retry this + if { "" == $synth::_handle_exit_after } { + set synth::_handle_exit_after [after 1000 synth::_handle_exit_timer] + + # And output something so the user knows the request has been received + synth::report "Waiting for the eCos application to exit.\n" + } + } + + # This routine requests termination of eCos, but not of + # ecosynth + proc _handle_kill_request { } { + if { $synth::ecos_running } { + synth::request_application_exit + if { "" == $synth::_handle_exit_after } { + set synth::_handle_exit_after [after 1000 synth::_handle_exit_timer] + } + } + } + + proc _handle_exit_timer { } { + if { $synth::ecos_running } { + incr synth::_handle_exit_retries + if { $synth::_handle_exit_retries < 5 } { + synth::request_application_exit + synth::report "Still waiting for the eCos application to exit.\n" + } else { + synth::_send_SIGKILL + } + set synth::_handle_exit_after [after 1000 synth::_handle_exit_timer] + } + } +} + +# }}} +# {{{ Main window layout + +# ---------------------------------------------------------------------------- +# The window layout is as follows: +# 1) a menu bar at the top (surprise surprise). Many of the menus will be +# empty or nearly so, but device-specific scripts may want to extend +# the menus. +# 2) a toolbar. This is primarily for use by device-specific scripts +# 3) a central grid. +# 4) a status line at the bottom. +# +# The central grid is organised as a 3x3 set of frames. The centre frame holds +# the main text display, plus associated scrollbars, and is the frame that +# will expand or shrink as the toplevel is resized. The remaining eight frames +# (nw, n, ne, e, se, s, sw, w) are available for use by device-specific +# scripts, typically under control of settings in the target definition file. +# It is very possible that some or all of these eight frames will be empty, +# and if an entire row or column is empty then Tk will make them invisible. +# +# Possible enhancements: +# 1) implement some sort of paning/resizing around the central text window. +# That would provide some way of letting the user control the space +# taken by device-specific subwindows. This would be implemented +# by modifying the weights assigned to different rows/columns. +# 2) it would be very useful if the main text window could be split, +# like emacs. This would require multiple text widgets, with output +# being pasted in each one. +# 3) possibly the text window should not be hard-wired to the centre frame, +# instead its frame could be selected by preferences somehow. + +if { $synth::flag_debug } { + synth::report "Creating main window layout\n" +} + +# The various frames are generally accessed via variables + +menu .menubar -borderwidth 1 +menu .menubar.file +menu .menubar.edit +menu .menubar.view +menu .menubar.windows +menu .menubar.help + +. configure -menu .menubar +.menubar add cascade -label "File" -underline 0 -menu .menubar.file +.menubar add cascade -label "Edit" -underline 0 -menu .menubar.edit +.menubar add cascade -label "View" -underline 0 -menu .menubar.view +.menubar add cascade -label "Windows" -underline 0 -menu .menubar.windows +.menubar add cascade -label "Help" -underline 0 -menu .menubar.help + +.menubar.file add command -label "Save" -underline 0 -accelerator "Ctrl-S" -command [list synth::_handle_file_save] +.menubar.file add command -label "Save As..." -underline 5 -command [list synth::_handle_file_save_as] +.menubar.file add command -label "Save All..." -underline 6 -command [list synth::_handle_file_save_all] +.menubar.file add command -label "Kill eCos" -underline 0 -command [list synth::_handle_kill_request] +.menubar.file add command -label "Exit" -underline 1 -accelerator "Ctrl-Q" -command [list synth::_handle_exit_request] +bind . <Control-KeyPress-q> [list synth::_handle_exit_request] +bind . <Control-KeyPress-s> [list synth::_handle_file_save] + +# Once eCos has exited, the kill option should be disabled +namespace eval synth { + proc _menubar_ecos_exit_clean { arg_list } { + .menubar.file entryconfigure "Kill eCos" -state disabled + } + synth::hook_add "ecos_exit" synth::_menubar_ecos_exit_clean +} + +frame .toolbar -borderwidth 1 -relief groove +if { "" != $synth::image_save } { + button .toolbar.save -image $synth::image_save -borderwidth 0 -command [list synth::_handle_file_save] + pack .toolbar.save -side left -padx 2 + synth::register_balloon_help .toolbar.save "Save visible output" +} +if { "" != $synth::image_saveall } { + button .toolbar.saveall -image $synth::image_saveall -borderwidth 0 -command [list synth::_handle_file_save_all] + pack .toolbar.saveall -side left -padx 2 + synth::register_balloon_help .toolbar.saveall "Save all output" +} +if { "" != $synth::image_cut } { + button .toolbar.cut -image $synth::image_cut -borderwidth 0 -state disabled -command [list synth::_handle_edit_cut] + pack .toolbar.cut -side left -padx 2 + synth::register_balloon_help .toolbar.cut "Cut" +} +if { "" != $synth::image_copy } { + + button .toolbar.copy -image $synth::image_copy -borderwidth 0 -command [list synth::_handle_edit_copy] + pack .toolbar.copy -side left -padx 2 + synth::register_balloon_help .toolbar.copy "Copy" +} +if { "" != $synth::image_paste } { + button .toolbar.paste -image $synth::image_paste -borderwidth 0 -state disabled -command [list synth::_handle_edit_paste] + pack .toolbar.paste -side left -padx 2 + synth::register_balloon_help .toolbar.paste "Paste" +} +pack .toolbar -side top -fill x + +frame .main +frame .main.nw -borderwidth 0 +frame .main.n -borderwidth 0 +frame .main.ne -borderwidth 0 +frame .main.e -borderwidth 0 +frame .main.se -borderwidth 0 +frame .main.s -borderwidth 0 +frame .main.sw -borderwidth 0 +frame .main.w -borderwidth 0 + +frame .main.centre + +frame .main.border_nw_n -width 2 -background black -borderwidth 0 +frame .main.border_n_ne -width 2 -background black -borderwidth 0 +frame .main.border_w_centre -width 2 -background black -borderwidth 0 +frame .main.border_centre_e -width 2 -background black -borderwidth 0 +frame .main.border_sw_s -width 2 -background black -borderwidth 0 +frame .main.border_s_se -width 2 -background black -borderwidth 0 +frame .main.border_nw_w -height 2 -background black -borderwidth 0 +frame .main.border_n_centre -height 2 -background black -borderwidth 0 +frame .main.border_ne_e -height 2 -background black -borderwidth 0 +frame .main.border_w_sw -height 2 -background black -borderwidth 0 +frame .main.border_centre_s -height 2 -background black -borderwidth 0 +frame .main.border_e_se -height 2 -background black -borderwidth 0 + +text .main.centre.text -xscrollcommand [list .main.centre.horizontal set] -yscrollcommand [list .main.centre.vertical set] +scrollbar .main.centre.horizontal -orient horizontal -command [list .main.centre.text xview] +scrollbar .main.centre.vertical -orient vertical -command [list .main.centre.text yview] +grid configure .main.centre.text -row 0 -column 0 -sticky news +grid configure .main.centre.vertical -row 0 -column 1 -sticky ns +grid configure .main.centre.horizontal -row 1 -column 0 -sticky ew +# Is there anything useful to be done in 1,1? e.g. a >> button to +# go directly to perform ".main.centre.text see end" + +# Make sure that row 0 column 0, i.e. the text widget rather than the +# scrollbars, grows to fit all available space. +grid rowconfigure .main.centre 0 -weight 1 +grid rowconfigure .main.centre 1 -weight 0 +grid columnconfigure .main.centre 0 -weight 1 +grid columnconfigure .main.centre 1 -weight 0 + +grid configure .main.nw -row 0 -column 0 -sticky news +grid configure .main.border_nw_n -row 0 -column 1 -sticky ns +grid configure .main.n -row 0 -column 2 -sticky news +grid configure .main.border_n_ne -row 0 -column 3 -sticky ns +grid configure .main.ne -row 0 -column 4 -sticky news +grid configure .main.border_nw_w -row 1 -column 0 -sticky ew +grid configure .main.border_n_centre -row 1 -column 1 -columnspan 3 -sticky ew +grid configure .main.border_ne_e -row 1 -column 4 -sticky ew +grid configure .main.w -row 2 -column 0 -sticky news +grid configure .main.border_w_centre -row 2 -column 1 -sticky ns +grid configure .main.centre -row 2 -column 2 -sticky news +grid configure .main.border_centre_e -row 2 -column 3 -sticky ns +grid configure .main.e -row 2 -column 4 -sticky news +grid configure .main.border_w_sw -row 3 -column 0 -sticky ew +grid configure .main.border_centre_s -row 3 -column 1 -columnspan 3 -sticky ew +grid configure .main.border_e_se -row 3 -column 4 -sticky ew +grid configure .main.sw -row 4 -column 0 -sticky news +grid configure .main.border_sw_s -row 4 -column 1 -sticky ns +grid configure .main.s -row 4 -column 2 -sticky news +grid configure .main.border_s_se -row 4 -column 3 -sticky ns +grid configure .main.se -row 4 -column 4 -sticky news +grid columnconfigure .main 0 -weight 0 +grid columnconfigure .main 1 -weight 0 +grid columnconfigure .main 2 -weight 1 +grid columnconfigure .main 3 -weight 0 +grid columnconfigure .main 4 -weight 0 +grid rowconfigure .main 0 -weight 0 +grid rowconfigure .main 1 -weight 0 +grid rowconfigure .main 2 -weight 1 +grid rowconfigure .main 3 -weight 0 +grid rowconfigure .main 4 -weight 0 + +# The .main frame should not be packed into the main window yet. +# Until all devices have been instantiated the various subwindows +# are not yet known, so the desired size of .main is not known +# either. Packing it too early and then adding more windows +# causes confusion. + +# }}} +# {{{ Help + +# ---------------------------------------------------------------------------- +# Two main sources of documentation are of interest to the synthetic +# target. The first is the toplevel eCos documentation. The second +# is the documentation specific to the generic target. Device-specific +# scripts may want to add menu entries for their own documentation. +# +# The problems are: +# 1) where to find the documentation +# 2) how to view it? +# +# The documentation should be in the component repository. If there is +# a variable ECOS_REPOSITORY then that gives the appropriate information. +# Otherwise things get messy because the repository being used for +# eCos may not match the repository used when building the host-side +# support - the versions should match but the repository may have +# moved. Never the less that is the best we can do. +# NOTE: sources.redhat.com might provide another alternative, but the +# documentation is not organized in the same way as the repository. +# +# As for how to view the documentation, this is up to user preferences +# but ecosynth has built-in knowledge of three different viewers. + +namespace eval synth { + + if { $synth::flag_debug } { + synth::report "Setting up help menu\n" + } + + variable _browser1 "mozilla -remote openURL(%s)" + variable _browser2 "mozilla %s" + variable _browser3 "gnome-help-browser %s" + variable _main_help "" + variable _synth_help "" + set _repo "" + + if { [info exists env(ECOS_REPOSITORY)] } { + set _repo $env(ECOS_REPOSITORY) + } else { + set _repo $synth::_ecos_repository + } + if { ![file exists [file join $_repo "ecos.db"]] } { + synth::report_warning "Failed to locate eCos component repository.\n \ + Please define an environment variable ECOS_REPOSITORY.\n" + } else { + # FIXME: this needs attention once the documentation is more sorted + set synth::_main_help [file join $_repo "index.html"] + if { ![file exists $synth::_main_help] } { + if { 0 } { + synth::report_warning "Failed to locate toplevel documentation file $synth::_main_help\n \ + Help->eCos menu option disabled.\n" + } + set synth::_main_help "" + } else { + set synth::_main_help "file://$_main_help" + } + + set synth::_synth_help [file join $_repo $synth::_ecosynth_package_dir $synth::_ecosynth_package_version "doc/hal-synth-arch.html"] + if { ![file exists $synth::_synth_help] } { + synth::report_warning "Failed to locate synthetic target documentation $synth::_synth_help\n \ + Help->Synthetic target menu option disabled.\n" + set synth::_synth_help "" + } else { + set synth::_synth_help "file://$_synth_help" + } + } + + if { "" != $_main_help } { + .menubar.help add command -label "eCos" -command [list synth::_menu_help $synth::handle_help] + } else { + .menubar.help add command -label "eCos" -state disabled + } + if { "" != $_synth_help } { + .menubar.help add command -label "Synthetic target" -command [list synth::handle_help "$synth::_synth_help"] + } else { + .menubar.help add command -label "Synthetic target" -state disabled + } + + unset _repo + + proc handle_help { which } { + set command [format $synth::_browser1 $which] + if { 0 != [catch { eval exec -- "$command > /dev/null" } & ] } { + set command [format $synth::_browser2 $which] + if { 0 != [catch { eval exec -- "$command > /dev/null &" } ] } { + set command [format $synth::_browser3 $which] + if { 0 != [catch { eval exec -- "$command > /dev/null &"} ] } { + synth::report_warning "Unable to start a help browser.\n Please check the settings in Edit->Preferences.\n" + } + } + } + } + + # FIXME: add an about box as well. +} + +# }}} +# {{{ Filters + +# ---------------------------------------------------------------------------- +# The central text window is expected to provide the bulk of the information +# to the user. This information can be voluminous, so filtering is desirable. +# +# There are two types of filters. System filters are provided by ecosynth +# itself and by device-specific scripts. For example ecosynth has a filter +# for warnings, and the console device has a filter for eCos trace messages. +# In addition users can specify their own filters using regular expressions, +# and those filters take priority. Note that there is an assumption that +# output is predominantly line-based: if partial lines get output then +# some confusion is possible. +# +# With tk the implementation is relatively straightforward: the text widget's +# tag facility does all the hard work of controlling how text gets displayed. +# It is possible to show or hide text using -elide, colours can be controlled +# using -background and -foreground, ... Not all of this functionality +# is made available to the user just yet. + +namespace eval synth { + # The bulk of the information is held in arrays, indexed by the name of + # the filter. Lists are used to keep track of all valid names. + variable _system_filter_list [list] + variable _system_filter_settings + variable _user_filter_list [list] + variable _user_filter_settings + + # Does a given system filter already exist? + proc filter_exists { name } { + set result 0 + if { -1 != [lsearch -exact $synth::_system_filter_list $name] } { + set result 1 + } + return $result + } + + proc filter_get_list { } { + return $synth::_system_filter_list + } + + # Parsing support. All filters take a number of standard options: + # + # -text "message" - how to identify this filter to the user + # -hide [0|1] - whether or not this text should be hidden by default + # -foreground <colour> + # -background <colour> + # + # The details of the currently supported options are known only to + # filter_parse_options and filter_add, allowing new options such + # as font manipulation to be added in future. + # + # There are two ways of adding a filter. filter_add is typically used + # inside ecosynth.tcl with known good data. filter_add_parsed is + # used with user-provided data, e.g. from the target definition file, + # after a call to filter_validate. + proc filter_parse_options { arg_list result_ref message_ref } { + upvar 1 $result_ref result + upvar 1 $message_ref message + set message "" + + set text_set 0 + set hide_set 0 + set foreground_set 0 + set background_set 0 + + set len [llength $arg_list] + for { set i 0 } { $i < $len } { incr i } { + set arg [lindex $arg_list $i] + if { ( "-text" == $arg) || + ( "-hide" == $arg) || + ( "-foreground" == $arg) || ( "-fg" == $arg) || + ( "-background" == $arg) || ( "-bg" == $arg) } { + + incr i + if { $i >= $len } { + append message " Missing data after argument $arg\n" + } else { + set data [lindex $arg_list $i] + if { "-text" == $arg } { + if { $text_set } { + append message " Attempt to set -text option twice.\n" + } else { + set text_set 1 + set result("-text") $data + } + } elseif { "-hide" == $arg } { + if { $hide_set } { + append message " Attempt to set -hide option twice.\n" + } else { + set hide_set 1 + if { ! [string is boolean -strict $data] } { + append message " -hide should be given a boolean value, not \"$data\"\n" + } else { + set result("-hide") [expr $data ? 1 : 0] + } + } + } elseif { ( "-foreground" == $arg) || ( "-fg" == $arg ) } { + if { $foreground_set } { + append message " Attempt to set -foreground twice.\n" + } else { + set foreground_set 1 + # FIXME: is there some way of validating this color? + set result("-foreground") $data + } + } elseif { ( "-background" == $arg) || ( "-bg" == $arg ) } { + if { $background_set } { + append message " Attempt to set -background twice.\n" + } else { + set background_set 1 + # FIXME: is there some way of validating this color? + set result("-background") $data + } + } + } + } else { + append message " Unknown option \"$arg\".\n" + } + } + + if { "" == $message } { + return 1 + } else { + return 0 + } + } + + # Add a new system filter, after the options have been parsed + proc filter_add_parsed { name data_ref } { + upvar 1 $data_ref data + + set text $name + set hide 0 + set foreground "<default>" + set background "<default>" + if { [info exists data("-text")] } { + set text $data("-text") + } + if { [info exists data("-hide")] } { + set hide $data("-hide") + } + if { [info exists data("-foreground")] } { + set foreground $data("-foreground") + } + if { [info exists data("-background")] } { + set background $data("-background") + } + + if { $hide } { + .main.centre.text tag configure $name -elide 1 + } else { + .main.centre.text tag configure $name -elide 0 + } + if { "<default>" == $foreground } { + .main.centre.text tag configure $name -foreground [.main.centre.text cget -foreground] + } else { + set msg "" + if [catch { .main.centre.text tag configure $name -foreground $foreground } msg ] { + synth::report_warning "Unable to configure color \"$foreground\"\n $msg\n" + set foreground "<default>" + .main.centre.text tag configure $name -foreground [.main.centre.text cget -foreground] + } + } + if { "<default>" == $background } { + .main.centre.text tag configure $name -background [.main.centre.text cget -background] + } else { + set msg "" + if [catch { .main.centre.text tag configure $name -background $background } msg ] { + synth::report_warning "Unable to configure color \"$background\"\n $msg\n" + set background "<default>" + .main.centre.text tag configure $name -background [.main.centre.text cget -background] + } + } + + lappend synth::_system_filter_list $name + set synth::_system_filter_settings($name,text) $text + set synth::_system_filter_settings($name,hide) $hide + set synth::_system_filter_settings($name,foreground) $foreground + set synth::_system_filter_settings($name,background) $background + + # System tags should only get added during initialization. Hence the + # first time the system filters window is brought up all filters + # should be defined. However, just in case a new filter is added + # in the middle of a run... + if { [winfo exists .system_filters] } { + destroy .system_filters + } + } + + # Add a new system filter, performing the appropriate parsing. + proc filter_add { name args } { + + if { [synth::filter_exists $name] } { + synth::internal_error "attempt to install filter $name twice.\n" + } + array set data [list] + set msg "" + + if { ![synth::filter_parse_options $args data msg] } { + # Any dubious arguments to the internal filter_add are treated as fatal. + synth::internal_error "unable to create new filter $name.\n$msg" + } else { + filter_add_parsed $name data + } + } + + filter_add "report" -text "ecosynth messages" + filter_add "error" -text "ecosynth errors" -foreground red + # amber is not a standard colour. Amber leds emit light in the range + # 595-605 nm, corresponding to rgb values of approx. FF4200. + # OrangeRed is close enough at FF4500 + filter_add "warning" -text "ecosynth warnings" -foreground OrangeRed + + # Bring up the system filters window, creating it if necessary. + # Keeping the toplevel around but iconified/withdrawn when + # unwanted means that properties such as size and position will + # tend to be preserved. + variable _system_filter_new_settings + variable _system_filter_widgets + + proc _menu_view_system_filters { } { + if { [winfo exists .system_filters] } { + if { "normal" == [wm state .system_filters] } { + raise .system_filters + } else { + wm deiconify .system_filters + } + return + } + toplevel .system_filters + wm title .system_filters "ecosynth system filters" + wm protocol .system_filters "WM_DELETE_WINDOW" [list synth::_menu_view_system_filters_cancel] + wm group .system_filters . + + frame .system_filters.main + label .system_filters.main.header1 -text "Filter" + label .system_filters.main.header2 -text "Hide" + label .system_filters.main.header3 -text "Foreground" + label .system_filters.main.header4 -text "Background" + set text_fg [.system_filters.main.header1 cget -foreground] + frame .system_filters.main.row0 -height 1 -background $text_fg + frame .system_filters.main.row2 -height 1 -background $text_fg + frame .system_filters.main.col0 -width 1 -background $text_fg + frame .system_filters.main.col2 -width 1 -background $text_fg + frame .system_filters.main.col4 -width 1 -background $text_fg + frame .system_filters.main.col6 -width 1 -background $text_fg + frame .system_filters.main.col8 -width 1 -background $text_fg + grid .system_filters.main.row0 -row 0 -column 0 -columnspan 9 -sticky ew + grid .system_filters.main.header1 -row 1 -column 1 -sticky news + grid .system_filters.main.header2 -row 1 -column 3 -sticky news + grid .system_filters.main.header3 -row 1 -column 5 -sticky news + grid .system_filters.main.header4 -row 1 -column 7 -sticky news + grid .system_filters.main.row2 -row 2 -column 0 -columnspan 9 -sticky ew + + set row 3 + foreach filter $synth::_system_filter_list { + set synth::_system_filter_new_settings($filter,hide) $synth::_system_filter_settings($filter,hide) + set synth::_system_filter_new_settings($filter,foreground) $synth::_system_filter_settings($filter,foreground) + set synth::_system_filter_new_settings($filter,background) $synth::_system_filter_settings($filter,background) + + set synth::_system_filter_widgets($filter,label) \ + [label .system_filters.main.filter_name_$row -text $synth::_system_filter_settings($filter,text)] + set synth::_system_filter_widgets($filter,hide) \ + [checkbutton .system_filters.main.filter_hide_$row -borderwidth 2 -indicatoron false -selectcolor "" \ + -image $synth::image_tick_no -selectimage $synth::image_tick_yes -variable synth::_system_filter_new_settings($filter,hide)] + set synth::_system_filter_widgets($filter,foreground) [button .system_filters.main.filter_foreground_$row -borderwidth 2 \ + -command [list synth::_menu_view_system_filters_choose_foreground $filter]] + set synth::_system_filter_widgets($filter,background) [button .system_filters.main.filter_background_$row -borderwidth 2 \ + -command [list synth::_menu_view_system_filters_choose_background $filter]] + + grid .system_filters.main.filter_name_$row -row $row -column 1 -sticky news + grid .system_filters.main.filter_hide_$row -row $row -column 3 -sticky news + grid .system_filters.main.filter_foreground_$row -row $row -column 5 -sticky news + grid .system_filters.main.filter_background_$row -row $row -column 7 -sticky news + + incr row + frame .system_filters.main.row$row -height 1 -background $text_fg + grid .system_filters.main.row$row -row $row -column 0 -columnspan 9 -sticky ew + incr row + } + grid .system_filters.main.col0 -row 0 -column 0 -rowspan $row -sticky ns + grid .system_filters.main.col2 -row 0 -column 2 -rowspan $row -sticky ns + grid .system_filters.main.col4 -row 0 -column 4 -rowspan $row -sticky ns + grid .system_filters.main.col6 -row 0 -column 6 -rowspan $row -sticky ns + grid .system_filters.main.col8 -row 0 -column 8 -rowspan $row -sticky ns + + for { set i 0 } { $i < $row } { incr i 2 } { + grid rowconfigure .system_filters.main $i -weight 0 + } + for { set i 1 } { $i < $row } { incr i 2 } { + grid rowconfigure .system_filters.main $i -weight 1 + } + for { set i 0 } { $i < 9 } { incr i 2 } { + grid columnconfigure .system_filters.main $i -weight 0 + } + for { set i 1 } { $i < 9 } { incr i 2 } { + grid columnconfigure .system_filters.main $i -weight 1 + } + + pack .system_filters.main -side top -fill both -expand 1 -pady 4 -padx 4 + + # FIXME: add try and revert buttons + frame .system_filters.buttons + button .system_filters.buttons.ok -text "OK" -command [list synth::_menu_view_system_filters_ok] + button .system_filters.buttons.cancel -text "Cancel" -command [list synth::_menu_view_system_filters_cancel] + pack .system_filters.buttons.ok .system_filters.buttons.cancel -side left -expand 1 + pack .system_filters.buttons -side bottom -fill x -pady 4 + + frame .system_filters.separator -height 2 -borderwidth 1 -relief sunken + pack .system_filters.separator -side bottom -fill x -pady 4 + + bind .system_filters <KeyPress-Return> [list synth::_menu_view_system_filters_ok] + bind .system_filters <KeyPress-Escape> [list synth::_menu_view_system_filters_cancel] + + synth::_menu_view_system_filters_reset + } + + proc _menu_view_system_filters_reset { } { + foreach filter $synth::_system_filter_list { + set synth::_system_filter_new_settings($filter,hide) $synth::_system_filter_settings($filter,hide) + set synth::_system_filter_new_settings($filter,foreground) $synth::_system_filter_settings($filter,foreground) + set synth::_system_filter_new_settings($filter,background) $synth::_system_filter_settings($filter,background) + + set colour $synth::_system_filter_new_settings($filter,foreground) + if { "<default>" == $colour } { + set colour [.system_filters.main.header1 cget -foreground] + } + $synth::_system_filter_widgets($filter,label) configure -foreground $colour + $synth::_system_filter_widgets($filter,foreground) configure -background $colour -activebackground $colour + + set colour $synth::_system_filter_new_settings($filter,background) + if { "<default>" == $colour } { + set colour [.system_filters.main.header1 cget -background] + } + $synth::_system_filter_widgets($filter,label) configure -background $colour + $synth::_system_filter_widgets($filter,background) configure -background $colour -activebackground $colour + } + } + + # Change a colour. For now this involves calling Tk's chooseColor utility. + # This is simple but not quite right: it would be much better to allow + # the foreground and background to be modified in the same dialog, providing + # immediate feedback on how the text will actually appear; it should also + # provide some simple way of reverting to the default. + proc _menu_view_system_filters_choose_foreground { filter } { + set current_colour $synth::_system_filter_new_settings($filter,foreground) + if { "<default>" == $current_colour } { + set current_colour [.system_filters.main.header1 cget -foreground] + } + set new_colour [tk_chooseColor -parent .system_filters -title "$synth::_system_filter_settings($filter,text) foreground" \ + -initialcolor $current_colour] + if { "" != $new_colour } { + set synth::_system_filter_new_settings($filter,foreground) $new_colour + $synth::_system_filter_widgets($filter,label) configure -foreground $new_colour + $synth::_system_filter_widgets($filter,foreground) configure -background $new_colour -activebackground $new_colour + } + } + + proc _menu_view_system_filters_choose_background { filter } { + set current_colour $synth::_system_filter_new_settings($filter,background) + if { "<default>" == $current_colour } { + set current_colour [.system_filters.main.header1 cget -background] + } + set new_colour [tk_chooseColor -parent .system_filters -title "$synth::_system_filter_settings($filter,text) background" \ + -initialcolor $current_colour] + if { "" != $new_colour } { + set synth::_system_filter_new_settings($filter,background) $new_colour + $synth::_system_filter_widgets($filter,label) configure -background $new_colour + $synth::_system_filter_widgets($filter,background) configure -background $new_colour -activebackground $new_colour + } + } + + proc _menu_view_system_filters_ok { } { + wm withdraw .system_filters + foreach filter $synth::_system_filter_list { + if { $synth::_system_filter_settings($filter,hide) != $synth::_system_filter_new_settings($filter,hide) } { + set hide $synth::_system_filter_new_settings($filter,hide) + set synth::_system_filter_settings($filter,hide) $hide + if { $hide } { + .main.centre.text tag configure $filter -elide 1 + } else { + .main.centre.text tag configure $filter -elide 0 + } + } + if { $synth::_system_filter_settings($filter,foreground) != $synth::_system_filter_new_settings($filter,foreground) } { + set foreground $synth::_system_filter_new_settings($filter,foreground) + set synth::_system_filter_settings($filter,foreground) $foreground + .main.centre.text tag configure $filter -foreground $foreground + } + if { $synth::_system_filter_settings($filter,background) != $synth::_system_filter_new_settings($filter,background) } { + set background $synth::_system_filter_new_settings($filter,background) + set synth::_system_filter_settings($filter,background) $background + .main.centre.text tag configure $filter -background $background + } + } + } + + proc _menu_view_system_filters_cancel { } { + wm withdraw .system_filters + synth::_menu_view_system_filters_reset + } + + # Now add a suitable entry to the View menu. + .menubar.view add command -label "System filters..." -command [list synth::_menu_view_system_filters] + + # User filters. + # FIXME: implement + # .menubar.view add command -label "User filters..." -command [list synth::_menu_view_filters] -state disabled +} + +# }}} +# {{{ Text window + +# ---------------------------------------------------------------------------- +# The central text window is expected to provide the bulk of the information +# to the user. Various filtering mechanisms are desirable. For example the +# user should be able to control whether or not eCos trace messages are +# currently visible, not to mention other characteristics such as font +# and colours. The text widget's tag mechanism makes this relatively simple. + +namespace eval synth { + + # Should the user be able to edit the text window, e.g. to add annotations? + # This is disabled by default but can be enabled. + variable flag_read_only 1 + + # By default disable wrapping. Possibly it should be possible to + # enable this on a per-tag basis. + .main.centre.text configure -wrap "none" + + # Give the text widget the focus by default. That way operations + # like page-up work immediately. + focus .main.centre.text + + # If editing is currently disallowed, do not accept any input. + # The code below is probably not quite sufficient, it is + # ASCII-centric. A separate binding for Alt- sequences ensures + # that the top-level menu processing continues to work. + # Similarly a separate binding for Control- sequences ensures + # that the shortcuts continue to work. + bind .main.centre.text <Alt-KeyPress> { + continue + } + bind .main.centre.text <Control-KeyPress> { + continue + } + bind .main.centre.text <KeyPress> { + if { !$synth::flag_read_only } { + continue + } elseif { 0 != [llength %A] } { + break + } elseif { ("Return" == "%K") || ("Tab" == "%K") || ("space" == "%K") } { + break + } else { + continue + } + } + # There are a few special control- bindings built in to the Tk text + # widget which perform editing operations + bind .main.centre.text <Control-KeyPress-h> { + if { !$synth::flag_read_only } { + continue + } else { + break + } + } + bind .main.centre.text <Control-KeyPress-d> { + if { !$synth::flag_read_only } { + continue + } else { + break + } + } + bind .main.centre.text <Control-KeyPress-k> { + if { !$synth::flag_read_only } { + continue + } else { + break + } + } + bind .main.centre.text <Control-KeyPress-o> { + if { !$synth::flag_read_only } { + continue + } else { + break + } + } + bind .main.centre.text <Control-KeyPress-t> { + if { !$synth::flag_read_only } { + continue + } else { + break + } + } + + # Implement support for the normal edit menu operations. + # FIXME: add a search facility + .menubar.edit insert end command -label "Cut" -command [list synth::_handle_edit_cut] -underline 2 -accelerator "Ctrl-X" -state disabled + .menubar.edit insert end command -label "Copy" -command [list synth::_handle_edit_copy] -underline 0 -accelerator "Ctrl-C" + .menubar.edit insert end command -label "Paste" -command [list synth::_handle_edit_paste] -underline 0 -accelerator "Ctrl-V" -state disabled + .menubar.edit insert end command -label "Clear" -command [list synth::_handle_edit_clear] -underline 3 -accelerator "Del" -state disabled + .menubar.edit insert end command -label "Select All" -command [list synth::_handle_edit_select_all] -underline 9 -accelerator "Ctrl-A" + .menubar.edit insert end checkbutton -label "Read Only" -variable synth::flag_read_only + .menubar.edit insert end separator + proc _trace_read_only { name1 name2 op } { + if { !$synth::flag_read_only } { + .menubar.edit entryconfigure "Cut" -state normal + .menubar.edit entryconfigure "Paste" -state normal + .menubar.edit entryconfigure "Clear" -state normal + .toolbar.cut configure -state normal + .toolbar.paste configure -state normal + } else { + .menubar.edit entryconfigure "Cut" -state disabled + .menubar.edit entryconfigure "Paste" -state disabled + .menubar.edit entryconfigure "Clear" -state disabled + .toolbar.cut configure -state disabled + .toolbar.paste configure -state disabled + } + } + trace variable synth::flag_read_only "w" synth::_trace_read_only + + # Support for cut'n'paste etc. The widget does most of the hard + # work, but this code has to distinguish between read-only and + # read-write windows. + # + # Some operations such as clear may operate on everything in the + # selection, including hidden text that happens to be in the + # range. That may or may not be the right thing to do. It is right + # if the intent is to get rid of all events during a period of + # time, but wrong if the user wants to get rid of specific text. + bind . <Control-KeyPress-x> [list synth::_handle_edit_cut] + bind . <Control-KeyPress-c> [list synth::_handle_edit_copy] + bind . <Control-KeyPress-v> [list synth::_handle_edit_paste] + bind . <KeyPress-Delete> [list synth::_handle_edit_clear] + bind . <Control-KeyPress-a> [list synth::_handle_edit_select_all] + + bind .main.centre.text <<Paste>> { + if { !$synth::flag_read_only } { + continue + } else { + break + } + } + bind .main.centre.text <<Cut>> { + if { !$synth::flag_read_only } { + continue + } else { + break + } + } + bind .main.centre.text <<Clear>> { + if { !$synth::flag_read_only } { + continue + } else { + break + } + } + + proc _handle_edit_cut { } { + event generate .main.centre.text "<<Cut>>" + } + + proc _handle_edit_copy { } { + event generate .main.centre.text "<<Copy>>" + } + + proc _handle_edit_paste { } { + event generate .main.centre.text "<<Paste>>" + } + + proc _handle_edit_clear { } { + event generate .main.centre.text "<<Clear>>" + } + + proc _handle_edit_select_all { } { + .main.centre.text tag add sel 1.0 "end - 1 chars" + } + + # Most output to the text window goes through this routine. It inserts + # some text with an appropriate tag. In addition it will ensure that + # the new text is visible if appropriate, and if a logfile has been + # specified then that will be updated as well. + proc output { msg tag } { + set ytail [lindex [.main.centre.text yview] 1] + set xhead [lindex [.main.centre.text xview] 0] + .main.centre.text insert end $msg $tag + if { (1.0 == $ytail) && (0.0 == $xhead) } { + .main.centre.text see end + } + if { "" != $synth::_logfd } { + puts -nonewline $synth::_logfd $msg + } + } + + # Text output is now possible, so flush anything that is still buffered. + # xview and yview may not give the right results until the window + # is mapped, so always make the last text visible. + set synth::flag_gui_ready 1 + synth::_flush_output + .main.centre.text see end + + + # Support for saving the current document. Save applies only to + # the currently visible text. SaveAll gives the hidden text as + # well. + variable _savefile "" + proc _handle_file_save { } { + if { "" == $synth::_savefile } { + set synth::_savefile [tk_getSaveFile -parent .] + if { "" == $synth::_savefile } { + return + } + } + set msg "" + if { 0 != [catch { set fd [open $synth::_savefile "w"] } msg] } { + synth::report_error "$msg\n" + if { $synth::_system_filter_settings(error,hide) } { + tk_messageBox -type "ok" -icon "error" -parent . -message "$msg\n" + } + return + } + set number_lines [expr int([.main.centre.text index end])] + for { set i 1 } { $i < $number_lines } { incr i } { + set tags [.main.centre.text tag names "[set i].0"] + if {[llength $tags] > 0 } { + set tag [lindex $tags 0] + if { [info exists synth::_system_filter_settings($tag,hide)] && + $synth::_system_filter_settings($tag,hide) } { + continue + } + } + puts $fd [.main.centre.text get "[set i].0" "[set i].end"] + } + close $fd + } + + proc _handle_file_save_as { } { + set new_savefile [tk_getSaveFile -parent .] + if { "" == $new_savefile } { + return + } + set synth::_savefile $new_savefile + synth::_handle_file_save + } + + proc _handle_file_save_all { } { + set new_savefile [tk_getSaveFile -parent .] + if { "" == $new_savefile } { + return + } + set msg "" + if { 0 != [catch { set fd [open $new_savefile "w"] } msg] } { + synth::report_error "$msg\n" + if { $synth::_system_filter_settings(error,hide) } { + tk_messageBox -type "ok" -icon "error" -parent . -message "$msg\n" + } + return + } + puts -nonewline $fd [.main.centre.text get 1.0 end] + close $fd + } +} + +# }}} +# {{{ Heartbeat and status + +# ---------------------------------------------------------------------------- +# This code manages a status line at the bottom of the main window. +# This involves a little heartbeat window, a label with the +# text Running or Exited, some padding, and an additional status +# line for use by other code. +# +# A variety of heartbeats have been attempted. The current one is +# still not very good, but will do for now. Others are if 0'd out. +# Note that these others may require additional images to be +# preloaded. + +namespace eval synth { + frame .status -borderwidth 1 -relief groove + + if { 1 } { + # The eCos logo, bouncing horizontally + variable _heartbeat_image_width [image width $synth::image_running1] + variable _heartbeat_offset 0 + variable _heartbeat_ltor 1 + + frame .status.heartbeat -width $synth::_heartbeat_image_width -height [image height $synth::image_running1] + pack .status.heartbeat -side left + label .status.heartbeat.image -image $synth::image_running1 -anchor w -borderwidth 0 + place .status.heartbeat.image -x $synth::_heartbeat_offset -y 0 + + proc _heartbeat_update { } { + if { ! $synth::ecos_running } { + place configure .status.heartbeat.image -x 0 -y 0 + } else { + if { $synth::_heartbeat_ltor } { + incr synth::_heartbeat_offset 4 + } else { + incr synth::_heartbeat_offset -4 + } + place configure .status.heartbeat.image -x $synth::_heartbeat_offset + + if { $synth::_heartbeat_offset < (5 - $synth::_heartbeat_image_width) } { + set synth::_heartbeat_ltor 1 + } elseif { $synth::_heartbeat_offset > ( $synth::_heartbeat_image_width -5) } { + set synth::_heartbeat_ltor 0 + } + after 100 synth::_heartbeat_update + } + } + after 100 synth::_heartbeat_update + + } elseif { 0 } { + # The eCos logo, alternating between a normal and an inverse version + variable _heartbeat_image_width [image width $synth::image_running1] + variable _heartbeat_inverse "" + variable _heartbeat_normal "" + variable _heartbeat_inverse_width 1 + variable _heartbeat_normal_width 1 + + canvas .status.heartbeat_canvas -width [image width $synth::image_running1] -height [image height $synth::image_running1] + pack .status.heartbeat_canvas -side left + label .status.heartbeat_canvas.background -image $synth::image_running1 -anchor w -borderwidth 0 + label .status.heartbeat_canvas.inverse -image $synth::image_running2 -anchor w -borderwidth 0 + label .status.heartbeat_canvas.normal -image $synth::image_running1 -anchor w -borderwidth 0 + .status.heartbeat_canvas create window 0 0 -anchor nw -window .status.heartbeat_canvas.background + set synth::_heartbeat_inverse [.status.heartbeat_canvas create window 0 0 -anchor nw -window .status.heartbeat_canvas.inverse] + raise .status.heartbeat_canvas.inverse .status.heartbeat_canvas.background + set synth::_heartbeat_normal [.status.heartbeat_canvas create window 0 0 -anchor nw -window .status.heartbeat_canvas.normal] + raise .status.heartbeat_canvas.normal .status.heartbeat_canvas.inverse + + .status.heartbeat_canvas itemconfigure $synth::_heartbeat_inverse -width $synth::_heartbeat_inverse_width + .status.heartbeat_canvas itemconfigure $synth::_heartbeat_normal -width $synth::_heartbeat_normal_width + + proc _heartbeat_update { } { + if { ! $synth::ecos_running } { + .status.heartbeat_canvas delete $synth::_heartbeat_inverse + .status.heartbeat_canvas delete $synth::_heartbeat_normal + } else { + if { $synth::_heartbeat_inverse_width < $synth::_heartbeat_image_width } { + incr synth::_heartbeat_inverse_width 2 + .status.heartbeat_canvas itemconfigure $synth::_heartbeat_inverse -width $synth::_heartbeat_inverse_width + } elseif { $synth::_heartbeat_normal_width < $synth::_heartbeat_image_width } { + incr synth::_heartbeat_normal_width 2 + .status.heartbeat_canvas itemconfigure $synth::_heartbeat_normal -width $synth::_heartbeat_normal_width + } else { + set synth::_heartbeat_inverse_width 1 + set synth::_heartbeat_normal_width 1 + .status.heartbeat_canvas itemconfigure $synth::_heartbeat_inverse -width $synth::_heartbeat_inverse_width + .status.heartbeat_canvas itemconfigure $synth::_heartbeat_normal -width $synth::_heartbeat_normal_width + } + after 100 synth::_heartbeat_update + } + } + after 100 synth::_heartbeat_update + + } elseif { 0 } { + # The eCos logo moving left to right, then replaced by a slightly smaller + # mirror version moving right to left, sort of as if rotating around a torus + variable _heartbeat_image_width [image width $synth::image_running1] + variable _heartbeat_offset [expr -1 * [image width $synth::image_running1]] + variable _heartbeat_ltor 1 + + frame .status.heartbeat -width $synth::_heartbeat_image_width -height [image height $synth::image_running1] + pack .status.heartbeat -side left + label .status.heartbeat.label -image $synth::image_running1 -anchor w -borderwidth 0 + + place .status.heartbeat.label -x $synth::_heartbeat_offset -y 0 + + proc _heartbeat_update { } { + if { ! $synth::ecos_running } { + .status.heartbeat.label configure -image $synth::image_running1 + place configure .status.heartbeat.label -x 0 + } else { + if { $synth::_heartbeat_ltor } { + incr synth::_heartbeat_offset 4 + } else { + incr synth::_heartbeat_offset -4 + } + place configure .status.heartbeat.label -x $synth::_heartbeat_offset + if { $synth::_heartbeat_offset < (0 - $synth::_heartbeat_image_width) } { + .status.heartbeat.label configure -image $synth::image_running1 + set synth::_heartbeat_ltor 1 + } elseif { $synth::_heartbeat_offset > $synth::_heartbeat_image_width } { + .status.heartbeat.label configure -image $synth::image_running3 + set synth::_heartbeat_ltor 0 + } + after 100 synth::_heartbeat_update + } + } + after 100 synth::_heartbeat_update + } + + label .status.running -width 10 -text "Running" -anchor w + pack .status.running -side left + proc _heartbeat_exit_hook { arg_list } { + .status.running configure -text "Exited" + } + synth::hook_add "ecos_exit" synth::_heartbeat_exit_hook + + label .status.text -text "" -anchor w + pack .status.text -side left -fill x -expand 1 + pack .status -side bottom -fill x +} + +# }}} +# {{{ Preferences + +namespace eval synth { + + if { $synth::flag_debug } { + synth::report "Setting up preferences window.\n" + } + + variable _pref_browser1 "" + variable _pref_browser2 "" + variable _pref_browser3 "" + + toplevel .preferences + wm title .preferences "ecosynth preferences" + wm withdraw .preferences + wm protocol .preferences "WM_DELETE_WINDOW" [list synth::_menu_edit_preferences_cancel] + wm group .preferences . + + # NOTE: the fixed-size padx/pady arguments should probably be determined + # using a font calculation. The fixed width for the column 0 entries is also + # a cheat. + set _pref_col0_width 24 + + frame .preferences.help + frame .preferences.help.frame -borderwidth 2 -relief groove + pack .preferences.help.frame -fill both -expand 1 -pady 10 + frame .preferences.help.frame.blank -height 10 + label .preferences.help.frame.label1 -text "Preferred browser" -width $synth::_pref_col0_width -anchor w + label .preferences.help.frame.label2 -text "First alternative" -width $synth::_pref_col0_width -anchor w + label .preferences.help.frame.label3 -text "Second alternative" -width $synth::_pref_col0_width -anchor w + entry .preferences.help.frame.entry1 -width 40 -relief sunken -textvariable synth::_pref_browser1 + entry .preferences.help.frame.entry2 -width 40 -relief sunken -textvariable synth::_pref_browser2 + entry .preferences.help.frame.entry3 -width 40 -relief sunken -textvariable synth::_pref_browser3 + grid .preferences.help.frame.blank -row 0 -column 0 + grid .preferences.help.frame.label1 -row 1 -column 0 -sticky w + grid .preferences.help.frame.label2 -row 2 -column 0 -sticky w + grid .preferences.help.frame.label3 -row 3 -column 0 -sticky w + grid .preferences.help.frame.entry1 -row 1 -column 1 -sticky ew + grid .preferences.help.frame.entry2 -row 2 -column 1 -sticky ew + grid .preferences.help.frame.entry3 -row 3 -column 1 -sticky ew + grid columnconfigure .preferences.help.frame 0 -weight 0 + grid columnconfigure .preferences.help.frame 1 -weight 1 + + label .preferences.help.title -text "Help" + place .preferences.help.title -in .preferences.help.frame -relx .1 -x -5 -y -10 -bordermode outside + pack .preferences.help -fill both -expand 1 -padx 10 + + frame .preferences.buttons + button .preferences.buttons.ok -text "OK" -command [list synth::_menu_edit_preferences_ok] + button .preferences.buttons.cancel -text "Cancel" -command [list synth::_menu_edit_preferences_cancel] + pack .preferences.buttons.ok .preferences.buttons.cancel -side left -expand 1 + pack .preferences.buttons -side bottom -fill x -pady 4 + + frame .preferences.separator -height 2 -borderwidth 1 -relief sunken + pack .preferences.separator -side bottom -fill x -pady 4 + + bind .preferences <KeyPress-Return> [list synth::_menu_edit_preferences_ok] + bind .preferences <KeyPress-Escape> [list synth::_menu_edit_preferences_cancel] + + variable _saved_focus "" + proc _menu_edit_preferences { } { + set synth::_saved_focus [focus] + set synth::_pref_browser1 $synth::_browser1 + set synth::_pref_browser2 $synth::_browser2 + set synth::_pref_browser3 $synth::_browser3 + if { "normal" == [wm state .preferences] } { + raise .preferences + } else { + wm deiconify .preferences + } + focus .preferences.help.frame.entry1 + } + + proc _menu_edit_preferences_ok { } { + if { $synth::_browser1 != $synth::_pref_browser1 } { + set synth::_browser1 $synth::_pref_browser1 + } + if { $synth::_browser2 != $synth::_pref_browser2 } { + set synth::_browser2 $synth::_pref_browser2 + } + if { $synth::_browser3 != $synth::_pref_browser3 } { + set synth::_browser3 $synth::_pref_browser3 + } + + wm withdraw .preferences + catch { focus $synth::_saved_focus } + } + + proc _menu_edit_preferences_cancel { } { + wm withdraw .preferences + catch { focus $synth::_saved_focus } + } + + .menubar.edit add command -label "Preferences..." -command [list synth::_menu_edit_preferences] +} + +# }}} +# {{{ Clean-up + +# ---------------------------------------------------------------------------- +# GUI clean-up. +# +# Once all the device-specific scripts have been loaded and initialized, it +# is time to go through the various components of the GUI and clean up +# anything that is not actually required. +namespace eval synth { + + proc _cleanup_gui { } { + + if { $synth::flag_debug } { + synth::report "Cleaning up unused GUI items.\n" + } + + # File, Edit, View and Help should always have contents, unless + # the user has deleted entries via the mainrc file. The Windows + # menu will be empty unless contents have been added. There is + # always a global binding for ctrl-Q, and the window manager + # should always provide a way of killing off the application, + # so there is no need to treat File specially. + if { 0 == [.menubar.file index end] } { + .menubar delete "File" + } + if { 0 == [.menubar.edit index end] } { + .menubar delete "Edit" + } + if { 0 == [.menubar.view index end] } { + .menubar delete "View" + } + if { 0 == [.menubar.windows index end] } { + .menubar delete "Windows" + } + if { 0 == [.menubar.help index end] } { + .menubar delete "Help" + } + + # If the toolbar is empty get rid of it. + if { 0 == [llength [winfo children .toolbar]] } { + pack forget .toolbar + destroy .toolbar + } + + set can_destroy [list] + # Remove some or all of the top, left hand, right hand or bottom + # sets of frames, if nobody is using them. + if { (0 == [llength [pack slaves .main.nw]]) && + (0 == [llength [pack slaves .main.n]]) && + (0 == [llength [pack slaves .main.ne]]) } { + lappend can_destroy .main.nw .main.border_nw_n .main.n .main.border_n_ne .main.ne + lappend can_destroy .main.border_nw_w .main.border_n_centre .main.border_ne_e + } + if { (0 == [llength [pack slaves .main.nw]]) && + (0 == [llength [pack slaves .main.w]]) && + (0 == [llength [pack slaves .main.sw]]) } { + lappend can_destroy .main.nw .main.border_nw_w .main.w .main.border_w_sw .main.sw + lappend can_destroy .main.border_nw_n .main.border_w_centre .main.border_w_sw + } + if { (0 == [llength [pack slaves .main.ne]]) && + (0 == [llength [pack slaves .main.e]]) && + (0 == [llength [pack slaves .main.se]]) } { + lappend can_destroy .main.ne .main.border_ne_e .main.e .main.border_e_se .main.se + lappend can_destroy .main.border_n_ne .main.border_centre_e .main.border_s_se + } + if { (0 == [llength [pack slaves .main.sw]]) && + (0 == [llength [pack slaves .main.s]]) && + (0 == [llength [pack slaves .main.se]]) } { + lappend can_destroy .main.sw .main.border_sw_s .main.s .main.border_s_se .main.se + lappend can_destroy .main.border_w_sw .main.border_centre_s .main.border_e_se + } + + foreach frame [lsort -unique $can_destroy] { + grid forget $frame + } + foreach frame [lsort -unique $can_destroy] { + destroy $frame + } + + # Now that the full window layout is known the .main frame can be + # packed. Doing this before now could cause problems because the + # desired sizes of the subwindows are not known. + pack .main -expand 1 -fill both + } +} + +# }}} +# {{{ Screen dump support + +# Create screen dumps for the main window or for various subwindows. +# Normally disabled, but useful when generating documentation. +# FIXME: there seem to be problems getting the desired info about +# transient windows, e.g. sizes. Hence the generated dumps still +# require a lot of hand editing for now. +if { 0 } { + + bind . <Alt-w> { + exec xwd -out main.xwd -frame -id [winfo id .] + } + + bind . <Alt-f> { + .menubar invoke "File" + after 100 exec xwd -out menu_file.xwd -frame -id [winfo id .] + } + + bind . <Alt-e> { + .menubar invoke "Edit" + after 100 exec xwd -out menu_edit.xwd -frame -id [winfo id .] + } + + bind . <Alt-v> { + .menubar invoke "View" + after 100 exec xwd -out menu_view.xwd -frame -id [winfo id .] + } + + # The Help menu will extend beyond the window boundaries + bind . <Alt-h> { + .menubar invoke "Help" + after 100 exec xwd -out menu_help.xwd -root + } +} + +# }}} + +# }}} +} + +# {{{ Device instantiation + +# ---------------------------------------------------------------------------- +# This code handles the loading of device-specific scripts in response +# to requests from the eCos application, and the instantiation of devices. +# The application's request provides four pieces of information, held in +# null-terminated strings in the request buffer: +# +# package name e.g. hal/synth/arch +# package version e.g. current +# device type e.g. console or ethernet +# device instance e.g. eth0, or an empty string +# device data e.g. 1024x768 for frame buffer resolution +# +# The first two pieces of information can be concatenated to give a +# path to the install location. The third identifies a suitable +# tcl script, e.g. console.tcl. This is sufficient to locate and load +# the tcl script. It should return an instantiation procedure which will +# be invoked with the instance name (or an empty string if there will only +# ever be one instance of this device type). The instantiation procedure +# will then be called with a number and the device instance string, and +# should return a handler for all requests intended for that device. +# +# If the package name and version are empty strings then an application-specific +# device is being initialized, and the code will search in the current +# directory and in ~/.ecos/synth + +namespace eval synth { + # Map package/version/type on to an instantiation procedure + array set _instantiation_procs [list] + + # Map device instances on to handlers. + array set _device_handlers [list] + array set _device_names [list] + variable _next_device_id 1 + + # Let scripts know their install location and their source dir + variable device_install_dir "" + variable device_src_dir "" + + # One handler is predefined. + set synth::_device_handlers(0) synth::_handle_ecosynth_requests + set synth::_device_names(0) "ecosynth I/O auxiliary" + + proc _handle_INSTANTIATE { data } { + + set list [split $data \0] + if { [llength $list] < 5 } { + synth::send_reply -1 0 "" + return + } + set package_dir [lindex $list 0] + set package_version [lindex $list 1] + set device_type [lindex $list 2] + set device_instance [lindex $list 3] + set device_data [lindex $list 4] + + if { ![info exists synth::_instantiation_procs($package_dir,$package_version,$device_type)] } { + # The required script has not yet been loaded. + if { "" != $package_dir } { + # The device is provided by a package + set synth::device_install_dir [file join $synth::_ecosynth_libexecdir "ecos" $package_dir $package_version] + set synth::device_src_dir [file join $synth::_ecosynth_repository $package_dir $package_version] + + set script [file join $::synth::device_install_dir "[set device_type].tcl"] + if { ![file exists $script] } { + synth::report_error "Unable to initialize device $device_type\n Script \"$script\" not found.\n" + synth::send_reply -1 0 "" + return + } elseif { ![file readable $script] } { + synth::report_error "Unable to initialize device $device_type\n Script \"$script\" not readable.\n" + synth::send_reply -1 0 "" + return + } + + # Is there a more recent version in the repository + if { [info exists ::env(ECOSYNTH_DEVEL)] } { + set _orig_name [file join $synth::device_src_dir "host" "[set device_type].tcl"] + if { [file exists $_orig_name] && [file readable $_orig_name] } { + if { [file mtime $_orig_name] >= [file mtime $script] } { + puts "$_orig_name is more recent than install: executing that." + set script $_orig_name + } + } + } + } else { + # The device is application-specific + set script [file join [pwd] "[set device_type].tcl"] + if { ![file exists $script] || ![file readable $script] } { + set script [file join "~/.ecos/synth" "[set device_type].tcl"] + if { ![file exists $script] || ![file readable $script] } { + synth::report_error "Unable to initialize device $device_type\n Script $device_type.tcl not found in [pwd] or ~/.ecos/synth\n" + synth::send_reply -1 0 "" + return + } + } + } + + # The uplevel ensures that the device script operates at the global + # level, so any namespaces it creates are also at global level + # and not nested inside synth. This avoids having to add + # synth:: to lots of variable accesses and generally avoids confusion + set result [catch { uplevel #0 source $script } instantiator] + if { 0 != $result } { + synth::report_error "Unable to initialize device $device_type\n Error loading script \"$script\"\n $instantiator\n" + synth::send_reply -1 0 "" + return + } + + set synth::_instantiation_procs($package_dir,$package_version,$device_type) $instantiator + } + + set handler [$synth::_instantiation_procs($package_dir,$package_version,$device_type) \ + $synth::_next_device_id $device_instance $device_data] + if { "" == $handler } { + synth::send_reply -1 0 "" + } else { + set result $synth::_next_device_id + incr synth::_next_device_id + + set synth::_device_handlers($result) $handler + if { "" != $device_instance } { + set synth::_device_names($result) $device_instance + } else { + set synth::_device_names($result) $device_type + } + synth::send_reply $result 0 "" + } + } +} + +# }}} +# {{{ Interrupt handling + +# ---------------------------------------------------------------------------- +# Interrupt handling. Device handlers can request an interrupt number +# using allocate_interrupt, and typically they will transmit this +# number to the eCos device driver during initialization. Device handlers +# can at any time call raise_interrupt with that number, which typically +# will result in SIGIO being sent to the eCos application. The latter will +# send a request to retrieve a mask of current pending interrupts. +# +# Exit handling, in the sense of the user selecting File->Exit, is also +# handled here. Such an exit request also involves raising SIGIO and +# then sending a specially format response to the get-pending request. + +namespace eval synth { + + # The next interrupt number to be allocated. Interrupt source 0 is reserved + # for the timer, which is handled within eCos itself via SIGALRM + # rather than by the I/O auxiliary. + variable _interrupt_next 1 + + # Keep track of which interrupts belong to which devices, for display and + # diagnostic purposes. + array set _interrupt_names [list] + set _interrupt_names(0) "system clock" + + # A mask of current pending interrupts + variable _interrupt_pending 0 + + # Is an exit request pending? + variable _interrupt_exit_pending 0 + + # Allow other code to hook into the interrupt system, e.g. to display + # pending interrupts. + synth::hook_define "interrupt" + + # For now interrupts are always allocated dynamically, which effectively + # means in the order of C++ static constructors. This means that interrupt + # allocation depends on the application, and may even change as the application + # is relinked. + # + # An alternative approach would allow device scripts to request specific + # interrupt numbers, making the system a bit more deterministic, but + # introducing complications such as shared interrupt numbers. On the other + # hand that would make it easier to test chained interrupt support and + # the like. + # FIXME: add support for allocating specific interrupt numbers + proc interrupt_allocate { name } { + if { $synth::_interrupt_next == 32 } { + synth::report_error "Unable to allocate an interrupt vector for $name\nAll 32 interrupt vectors are already in use.\n" + return -1 + } + set result $synth::_interrupt_next + set synth::_interrupt_names($result) $name + incr synth::_interrupt_next + return $result + } + + # Allow information about the device->interrupt mappings to be retrieved + proc interrupt_get_max { } { + return [expr $synth::_interrupt_next - 1] + } + proc interrupt_get_devicename { number } { + if { [info exists synth::_interrupt_names($number) ] } { + return $synth::_interrupt_names($number) + } else { + return "" + } + } + + # Raise a specific interrupt. If the interrupt is already pending + # this has no effect because a SIGIO will have been sent to the + # eCos application already. Otherwise SIGIO needs to be raised. + proc interrupt_raise { number } { + if { $number >= $synth::_interrupt_next } { + error "Attempt to raise invalid interrupt $number." + } + if { !$synth::ecos_running } { + return + } + set or_mask [expr 0x01 << $number] + if { 0 == ($or_mask & $synth::_interrupt_pending) } { + # This interrupt was not previously pending, so action is needed. + set synth::_interrupt_pending [expr $synth::_interrupt_pending | $or_mask] + synth::hook_call "interrupt" $number + synth::_send_SIGIO + } + } + + # Request application exit. This is typically called in response to + # File->Exit. + proc request_application_exit { } { + set synth::_interrupt_exit_pending 1 + synth::_send_SIGIO + } + + # The eCos application wants to know about pending interrupts. It maintains + # its own set of pending interrupts, so once the information has been + # transferred there are no pending interrupts left in the I/O auxiliary, + # only in the eCos app. A pending exit is indicated by non-empty data, + # the actual data does not matter. + proc _handle_GET_IRQ_PENDING { } { + if { $synth::_interrupt_exit_pending } { + synth::send_reply $synth::_interrupt_pending 1 "x" + } else { + synth::send_reply $synth::_interrupt_pending 0 "" + } + set synth::_interrupt_pending 0 + } +} + +# }}} +# {{{ Initialization complete + +# ---------------------------------------------------------------------------- +# This is called once all static constructors have been run, i.e. when all +# eCos devices should be initialized. It does the following: +# +# 1) invoke any "initialized" hooks set up by device scripts. +# +# 2) run the per-user mainrc.tcl script, if it exists, so that users can +# install hooks, modify the GUI display, etc. +# +# 3) warn about any unused command line arguments +# +# 4) optionally warn about any unused entries in the target definition file +# +# 5) clean up the GUI, e.g. remove unwanted windows and borders, and display it. +# +# However if the user specified --help then, instead of all the above, +# a help message is displayed and the auxiliary exits, hopefully taking the +# eCos application with it. + +namespace eval synth { + + proc _handle_CONSTRUCTORS_DONE { } { + + if { $synth::flag_help } { + puts "Usage : <eCos application> <options>" + puts " Options are passed to the I/O auxiliary, and are not" + puts " accessible to the eCos application." + puts "Standard options:" + puts " -io : run with I/O facilities." + puts " -nio : run with no I/O facilities at all." + puts " -nw, --no-windows : run in console mode." + puts " -w, --windows : run in GUI mode (default)." + puts " -v, --version : display the version of the I/O auxiliary." + puts " -h, --help : show this help text." + puts " -k, --keep-going : ignore errors in init scripts or the" + puts " target definition file." + puts " -nr, --no-rc : do not run the user's init scripts." + puts " -x, --exit : terminate I/O auxiliary as soon as the eCos" + puts " application exits (default in console mode)." + puts " -nx, --no-exit : I/O auxiliary keeps running even after eCos" + puts " application has exited (default in GUI mode)." + puts " -V, --verbose : provide additional output during the run." + puts " -l <file>, --logfile <file> : send all output to the specified file. In" + puts " GUI mode this in addition to the main text" + puts " window. In console mode this is instead of" + puts " stdout." + puts " -t <file>, --target <file> : use the specified .tdf file as the target" + puts " definition. The auxiliary will look for this" + puts " file in the current directory, ~/.ecos, and" + puts " finally the install location." + puts " -geometry <geometry> : size and position for the main window." + synth::hook_call "help" + exit 1 + } + + synth::hook_call "ecos_initialized" + + # ---------------------------------------------------------------------------- + if { !$synth::flag_no_rc } { + set _config_file [file join "~/.ecos/synth" "mainrc.tcl"] + if { [file exists $_config_file] } { + if { [file readable $_config_file] } { + if { [catch { source $_config_file } msg ] } { + set error "Failed to execute user initialization file \"$_config_file\"\n" + append error " $msg\n" + if { $synth::flag_verbose } { + append error "------- backtrace ------------------------------------------\n" + append error $::errorInfo + append error "\n------- backtrace ends -------------------------------------\n" + } + synth::report_error $error + } + } else { + synth::report_error "No read access to user initialization file \"$_config_file\"\n" + } + } + unset _config_file + } + + # ---------------------------------------------------------------------------- + # Report any arguments that have not been used up by the auxiliary itself + # or by any device handlers + set unconsumed_args [synth::argv_get_unconsumed] + foreach arg $unconsumed_args { + synth::report_warning "Unrecognised command line option \"$arg\", ignored.\n" + } + + # ---------------------------------------------------------------------------- + if { $synth::flag_verbose } { + set unconsumed_devices [synth::tdf_get_unconsumed_devices] + set unconsumed_options [synth::tdf_get_unconsumed_options] + if { (0 != [llength $unconsumed_devices]) || (0 != [llength $unconsumed_options]) } { + set msg "Target definition file $synth::target_definition\n" + foreach dev $unconsumed_devices { + append msg " synth_device \"$dev\" not recognised.\n" + } + foreach option $unconsumed_options { + set dev [lindex $option 0] + set opt [lindex $option 1] + append msg " synth_device \"$dev\", option \"$opt\" not recognised.\n" + } + synth::report_warning $msg + } + } + + # ---------------------------------------------------------------------------- + if { $synth::flag_gui } { + synth::_cleanup_gui + wm deiconify . + } + + # ---------------------------------------------------------------------------- + # Finally send a reply back to the application so it can really + # start running. Alternatively, if any errors occurred during + # initialization and the user did not specify --keep-going then + # send back an error code, causing the eCos application to terminate. + if { (0 == $synth::_error_count) || $synth::flag_keep_going } { + synth::send_reply 1 0 "" + } else { + synth::send_reply 0 0 "" + } + } +} + +# }}} +# {{{ Requests for the I/O auxiliary itself + +# ---------------------------------------------------------------------------- +# There are three requests which can be aimed at the I/O auxiliary itself, +# rather than at device-specific scripts. These are: INSTANTIATE to instantiate +# a device; CONSTRUCTORS_DONE to indicate when initialization is complete; +# and GET_IRQ_PENDING which deals with interrupts. + +namespace eval synth { + + proc _handle_ecosynth_requests { devid request arg1 arg2 request_data request_len reply_len } { + if { 0x01 == $request } { + synth::_handle_INSTANTIATE $request_data + } elseif { 0x02 == $request } { + synth::_handle_CONSTRUCTORS_DONE + } elseif { 0x03 == $request } { + synth::_handle_GET_IRQ_PENDING + } elseif { 0x04 == $request } { + synth::_handle_GET_VERSION + } else { + error "The eCos application has sent an invalid request sent to the I/O auxiliary" + } + } + + variable _SYNTH_AUXILIARY_PROTOCOL_VERSION 0x01 + proc _handle_GET_VERSION { } { + synth::send_reply $synth::_SYNTH_AUXILIARY_PROTOCOL_VERSION 0 "" + } +} + +# }}} +# {{{ Application exit + +# ---------------------------------------------------------------------------- +# The application has exited. This is detected by an EOF event on the pipe +# from the eCos application. +# +# First the rest of the system is informed about the event using the +# appropriate hook. This should ensure that the various device-specific +# scripts do the right thing, e.g shut down sub-processes. Next, if +# the immediate exit flag is set then that is obeyed. This flag is set by +# default when in command-line mode because there is no point in continuing +# to run if there is neither an application nor a GUI for the user to interact +# with. It also gets set if the user has explicitly requested an exit. +# +# The exit call will invoke the appropriate hooks. +namespace eval synth { + + proc _application_has_exited { } { + + set synth::ecos_running 0 + synth::hook_call "ecos_exit" + + # Depending on command-line arguments and whether or not the GUI is present, + # the auxiliary should now exit + if { $synth::flag_immediate_exit } { + exit 0 + } elseif { !$synth::flag_gui } { + synth::report "eCos application has exited: I/O auxiliary still running in the background.\n" + } + } +} + +# }}} +# {{{ Communication with the eCos application + +namespace eval synth { + + # ---------------------------------------------------------------------------- + # The basic communication routines between the auxiliary and the + # eCos application. _read_request is invoked whenever there is + # a pending event on the pipe from the eCos application, either + # a request or an EOF. It + + # Keep track of a couple of things to detect protocol mismatches. + variable _reply_expected 0 + variable _expected_rxlen 0 + + # Receive a single request from the eCos application and invoke the + # appropriate handler. + proc _read_request { } { + # Read a single request from the application, or possibly EOF + set devid 0 + set reqcode 0 + set arg1 0 + set arg2 0 + set txlen 0 + set txdata "" + set rxlen 0 + set request [read $synth::_channel_from_app 24] + + if { [eof $synth::_channel_from_app] } { + fileevent $synth::_channel_from_app readable "" + synth::_application_has_exited + return + } + + # If a real request is sent then currently the application should + # not be expecting a reply + if { $synth::_reply_expected } { + error "The eCos application should not be sending a request when there is still a reply pending" + } + + set binary_result [binary scan $request "iiiiii" devid reqcode arg1 arg2 txlen rxlen] + if { 6 != $binary_result } { + error "Internal error decoding request from eCos application" + } + + # If running on a 64-bit platform then the above numbers will have been sign-extended, + # which could lead to confusing results + set devid [expr $devid & 0x0FFFFFFFF] + set reqcode [expr $reqcode & 0x0FFFFFFFF] + set arg1 [expr $arg1 & 0x0FFFFFFFF] + set arg2 [expr $arg2 & 0x0FFFFFFFF] + set txlen [expr $txlen & 0x0FFFFFFFF] + set rxlen [expr $rxlen & 0x0FFFFFFFF] + + # The top bit of rxlen is special and indicates whether or not a reply is expected. + set synth::_reply_expected [expr 0 != ($rxlen & 0x080000000)] + set synth::_expected_rxlen [expr $rxlen & 0x07FFFFFFF] + + # Is there additional data to be read + if { $txlen > 0 } { + set txdata [read $synth::_channel_from_app $txlen] + if { [eof $synth::_channel_from_app] } { + fileevent $synth::_channel_from_app readable "" + synth::_application_has_exited + return + } + } + + # The devid can be used to get hold of a handler function, and that will do + # the hard work. + if { ![info exists synth::_device_handlers($devid)] } { + error "A request has been received for an unknown device $devid" + } + + $synth::_device_handlers($devid) $devid $reqcode $arg1 $arg2 $txdata $txlen $synth::_expected_rxlen + } + + # Register _read_request as the handler for file events on the pipe from + # the application. + fileevent $synth::_channel_from_app readable synth::_read_request + + # Send a reply back to eCos. This consists of a two-word structure, + # result and length, followed by the data if any. Currently this + # raises an error if there is a mismatch between the specified and + # actual length of the data. Possibly the code should cope with + # data strings that exceed the specified length, extracting a + # suitable substring. + proc send_reply { result { length 0 } { data "" } } { + # Make sure that a reply is actually expected. + if { !$synth::_reply_expected } { + error "Attempt to send reply to application when no request has been sent" + } else { + set synth::_reply_expected 0 + } + + if { $length > $synth::_expected_rxlen } { + error "Reply contains more data than the application expects: $length bytes instead of $synth::_expected_rxlen" + } + if { ($length > 0) && ([string length $data] != $length) } { + error "Mismatch between specified and actual data length: $length [string length $data]" + } + if { !$synth::ecos_running } { + return + } + + set struct [binary format "ii" $result $length] + # Ignore any errors when writing down the pipe. The only likely error is + # when the application has exited, causing a SIGPIPE which Tcl + # will handle. The application should be waiting for this response. + catch { + puts -nonewline $synth::_channel_to_app $struct + if { $length > 0 } { + puts -nonewline $synth::_channel_to_app $data + } + } + } +} + +# }}} + +# {{{ initrc + +# ---------------------------------------------------------------------------- +# Just before control is returned to the eCos application, run the per-user +# file, ~/.ecos/synth/initrc.tcl. The main GUI is now in place and the target +# definition file has been read in, but no eCos static constructors have +# been run yet and hence no devices have been loaded or activated. +# All the various core procedures have been defined. initrc gives the user +# a chance to install hooks, redefine some internals, and so on. +# Another initialization file mainrc.tcl gets read in later, just before +# the eCos application really starts running. +# +# Possibly ecosynth should also read in a system-wide initialization +# file equivalent to emacs' site-start.el, but the extra complexity +# does not seem warranted just yet. + +if { !$synth::flag_no_rc } { + set _config_file [file join "~/.ecos/synth" "initrc.tcl"] + if { [file exists $_config_file] } { + if { [file readable $_config_file] } { + if { [catch { source $_config_file } msg ] } { + set error "Failed to execute user initialization file \"$_config_file\"\n" + append error " $msg\n" + if { $synth::flag_verbose } { + append error "------- backtrace ------------------------------------------\n" + append error $::errorInfo + append error "\n------- backtrace ends -------------------------------------\n" + } + synth::report_error $error + } + } else { + synth::report_error "No read access to user initialization file \"$_config_file\"\n" + } + } + unset _config_file +} + +# }}} +# {{{ Done + +# ---------------------------------------------------------------------------- +# The last few steps. + +# Once everything has been initialized the application can be woken up again. +# It should be blocked waiting for a single byte on the pipe. +if { $synth::flag_debug } { + synth::report "Core initialization complete, resuming the eCos application.\n" +} + +puts -nonewline $synth::_channel_to_app "." + +# Enter the event loop. In console mode there is a problem if -nx has been +# specified: there may not be any event handlers left once the eCos application +# has exited, so the vwait would abort. This is avoided by a dummy after proc. +if { !$synth::flag_gui && !$synth::flag_immediate_exit } { + namespace eval synth { + proc _dummy_after_handler { } { + after 1000000 synth::_dummy_after_handler + } + } + after 1000000 synth::_dummy_after_handler +} + +vwait synth::_ecosynth_exit + +# }}}
new file mode 100644 --- /dev/null +++ b/packages/hal/synth/arch/current/host/help.xbm @@ -0,0 +1,6 @@ +#define help_width 16 +#define help_height 15 +static unsigned char help_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0xc0, 0x01, 0xe0, 0x03, 0x30, 0x06, 0x30, 0x06, + 0x00, 0x06, 0x00, 0x03, 0x80, 0x01, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, + 0x80, 0x01, 0x00, 0x00, 0x00, 0x00};
new file mode 100644 --- /dev/null +++ b/packages/hal/synth/arch/current/host/paste.xbm @@ -0,0 +1,6 @@ +#define paste_width 16 +#define paste_height 15 +static unsigned char paste_bits[] = { + 0x00, 0x00, 0xe0, 0x01, 0x3e, 0x3f, 0xd1, 0x22, 0x09, 0x24, 0xf9, 0x27, + 0x01, 0x20, 0xc1, 0x3f, 0x41, 0x20, 0x41, 0x50, 0x41, 0x77, 0x41, 0x40, + 0x41, 0x4e, 0x7e, 0x40, 0xc0, 0x7f};
new file mode 100644 index 0000000000000000000000000000000000000000..dc461b0350e991932690eec86a8fe5ead8d00e1f GIT binary patch literal 1981 zc$~eI+YNvq3;_LR3LOC>OyB_Szl0-H6C!Eo!?Xk%J|vC3_CT*3j=07g_LKsAu^8ih z<vusx0u)wmC%V!d+<tVS<7$eBCflHKRyR!1KtkfOMWmFHts^uzyp>o@W$PBB>6rML zI;3q#jVWi%>HI;nAjJu*ZYbJu)>OVvxYDYEhAG!faz5eXV(U-)rC5VSm=-(W1hnLK HG`c_^fXf89
new file mode 100644 index 0000000000000000000000000000000000000000..38ccc9fac1a9cc15057cca74d19018fd9d58cc2d GIT binary patch literal 1981 zc$~%5!3}^Q3<XfnOraxa#0eb0{g-frYGNc!+g}ADHXbC6Jou>F66UcVmoUW`=&pSo zvaa)yuC$0%u3Jeby}+%fFP+ck<RH3&=3TT$(M<}eLasRpYB}As1;Ozlvc$}}Lr&{$ z@_U`3UItp2bJkXz53~t6nV8XiN;^7%v)18j@g<Fx>d@5WHA9&<__)mZoBdLL`H`0C Ll{CusYx+VDfm4Qk
new file mode 100644 index 0000000000000000000000000000000000000000..32a02b28b1255f00722684a751eb388c57312d96 GIT binary patch literal 1981 zc$~$Q(G7qg3`G5A3LOC>OyB_Szl0;G35jWF?}9aG!;fCLSFY%m!xG1s!<<q$eyx3- z-0RvtJg@g$H@eWJ3CRJe1ua!{#!9_?_!Nk0P7raWT1+ZK$D{5<a&;S3;QE-RxmL}+ zCR)DX(Y2sa+bC^~M%>=$7As%i=&FBn%{aQ>$3;|Rf?_wj;=dHq6&i8l(yYcpXY7qO H2k~W{(>$hY
new file mode 100644 --- /dev/null +++ b/packages/hal/synth/arch/current/host/save.xbm @@ -0,0 +1,6 @@ +#define save_width 16 +#define save_height 15 +static unsigned char save_bits[] = { + 0x00, 0x00, 0xfe, 0xff, 0x0a, 0xa0, 0x0a, 0xe0, 0x0a, 0xa0, 0x0a, 0xa0, + 0x0a, 0xa0, 0x0a, 0xa0, 0xf2, 0x9f, 0x02, 0x80, 0xf2, 0x9f, 0xf2, 0x93, + 0xf2, 0x93, 0xf2, 0x93, 0xfc, 0xff, };
new file mode 100644 --- /dev/null +++ b/packages/hal/synth/arch/current/host/saveall.xbm @@ -0,0 +1,6 @@ +#define saveall_width 16 +#define saveall_height 15 +static unsigned char saveall_bits[] = { + 0x00, 0x00, 0xfe, 0xff, 0x0a, 0xa0, 0x4a, 0xea, 0xaa, 0xaa, 0xea, 0xaa, + 0xaa, 0xaa, 0x0a, 0xa0, 0xf2, 0x9f, 0x02, 0x80, 0xf2, 0x9f, 0xf2, 0x93, + 0xf2, 0x93, 0xf2, 0x93, 0xfc, 0xff, };
new file mode 100644 --- /dev/null +++ b/packages/hal/synth/arch/current/host/tick_no.xbm @@ -0,0 +1,5 @@ +#define tick_no_width 11 +#define tick_no_height 11 +static unsigned char tick_no_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0x06, 0x03, 0x8c, 0x01, 0xd8, 0x00, 0x70, 0x00, + 0xd8, 0x00, 0x8c, 0x01, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00};
new file mode 100644 --- /dev/null +++ b/packages/hal/synth/arch/current/host/tick_yes.xbm @@ -0,0 +1,5 @@ +#define tick_yes_width 11 +#define tick_yes_height 11 +static unsigned char tick_yes_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x01, 0xc4, 0x01, 0xec, 0x00, + 0x7c, 0x00, 0x38, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00};
new file mode 100644 --- /dev/null +++ b/packages/hal/synth/arch/current/host/user_initrc.tcl @@ -0,0 +1,9 @@ +# ~/.ecos/synth/initrc.tcl +# +# This configuration file is executed by ecosynth, the eCos synthetic +# target auxiliary program, early on during initialization. Typically +# this file is used to set up search paths and similar variables. The +# eCos synthetic target documentation should be consulted for more +# information. +# +# This file is executed in a Tcl interpreter, so Tcl syntax applies.
new file mode 100644 --- /dev/null +++ b/packages/hal/synth/arch/current/host/user_mainrc.tcl @@ -0,0 +1,10 @@ +# ~/.ecos/synth/mainrc.tcl +# +# This configuration file is executed by ecosynth, the eCos synthetic +# target auxiliary program, just before the application is allowed +# to continue. The target definition file has been processed and the +# GUI has been set up, although usually the event loop will not have +# been entered and no windows will have been displayed yet. +# +# This file is executed in a Tcl interpreter, so Tcl syntax applies. +
--- a/packages/hal/synth/arch/current/include/hal_io.h +++ b/packages/hal/synth/arch/current/include/hal_io.h @@ -11,6 +11,7 @@ //####ECOSGPLCOPYRIGHTBEGIN#### // ------------------------------------------- // This file is part of eCos, the Embedded Configurable Operating System. +// Copyright (C) 2002 Bart Veer // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. // // eCos is free software; you can redistribute it and/or modify it under @@ -199,17 +200,33 @@ typedef volatile CYG_ADDRWORD HAL_IO_REG #define CYG_HAL_SYS_SIGINT 2 #define CYG_HAL_SYS_SIGQUIT 3 #define CYG_HAL_SYS_SIGILL 4 +#define CYG_HAL_SYS_SIGTRAP 5 +#define CYG_HAL_SYS_SIGABRT 6 #define CYG_HAL_SYS_SIGBUS 7 #define CYG_HAL_SYS_SIGFPE 8 +#define CYG_HAL_SYS_SIGKILL 9 +#define CYG_HAL_SYS_SIGUSR1 10 #define CYG_HAL_SYS_SIGSEGV 11 +#define CYG_HAL_SYS_SIGUSR2 12 #define CYG_HAL_SYS_SIGPIPE 13 #define CYG_HAL_SYS_SIGALRM 14 #define CYG_HAL_SYS_SIGTERM 15 +#define CYG_HAL_SYS_SIGSTKFLT 16 #define CYG_HAL_SYS_SIGCHLD 17 #define CYG_HAL_SYS_SIGCONT 18 #define CYG_HAL_SYS_SIGSTOP 19 #define CYG_HAL_SYS_SIGTSTP 20 +#define CYG_HAL_SYS_SIGTTIN 21 +#define CYG_HAL_SYS_SIGTTOU 22 +#define CYG_HAL_SYS_SIGURG 23 +#define CYG_HAL_SYS_SIGXCPU 24 +#define CYG_HAL_SYS_SIGXFSZ 25 +#define CYG_HAL_SYS_SIGVTALRM 26 +#define CYG_HAL_SYS_SIGPROF 27 +#define CYG_HAL_SYS_SIGWINCH 28 #define CYG_HAL_SYS_SIGIO 29 +#define CYG_HAL_SYS_SIGPWR 30 +#define CYG_HAL_SYS_SIGSYS 31 #define CYG_HAL_SYS_SA_NOCLDSTOP 0x00000001 #define CYG_HAL_SYS_SA_NOCLDWAIT 0x00000002 @@ -317,6 +334,13 @@ struct cyg_hal_sys_itimerval { struct cyg_hal_sys_timeval hal_it_value; }; +// System calls and related constants, or rather the subset that is +// needed internally. +#define CYG_HAL_SYS_R_OK 0x04 +#define CYG_HAL_SYS_W_OK 0x02 +#define CYG_HAL_SYS_X_OK 0x01 +#define CYG_HAL_SYS_F_OK 0x00 + /* lseek whence flags */ #define CYG_HAL_SYS_SEEK_SET 0 /* Seek from beginning of file. */ #define CYG_HAL_SYS_SEEK_CUR 1 /* Seek from current position. */ @@ -399,6 +423,13 @@ externC int cyg_hal_sys_seti externC int cyg_hal_sys_gettimeofday(struct cyg_hal_sys_timeval*, struct cyg_hal_sys_timezone*); +externC int cyg_hal_sys_access(const char*, int); +externC int cyg_hal_sys_fork(void); +externC int cyg_hal_sys_execve(const char*, const char* [], const char* []); +externC int cyg_hal_sys_pipe(int []); +externC int cyg_hal_sys_close(int); +externC int cyg_hal_sys_dup2(int, int); + // The actual implementation appears to return the new brk() value. externC void* cyg_hal_sys_brk(void*); @@ -416,8 +447,35 @@ extern const char** cyg_hal_sys_envi // ---------------------------------------------------------------------------- // Interaction between the application and the auxiliary. -// Not yet available, but there is a hardware-initialization routine. -externC void hal_synthetic_target_init(void); + +// Is the auxiliary actually in use/available? This flag should be tested by +// device drivers prior to attempting any communication with the auxiliary. +extern cyg_bool synth_auxiliary_running; + +// The fundamental I/O operation: sending a request to the auxiliary and +// optionally getting back a reply. A null pointer for the response field +// indicates that no reply is expected. +externC void synth_auxiliary_xchgmsg(int /* devid */, int /* request */, + int /* arg1 */, int /* arg2 */, + const unsigned char* /* txdata */, int /* txlen */, + int* /* response */, + unsigned char* /* rxdata */, int* /* actual_rxlen */, + int /* rxlen */); + +// Request that the auxiliary instantiates a given device, loading appropriate +// support code as required. This function takes the following arguments: +// 1) the location of the package that should provide this device, e.g. +// devs/eth/synth +// 2) the version of that package currently being used, e.g. "current" +// 3) the name of the device, e.g. "ethernet". This identifies the +// Tcl script that should be loaded to handle requests for this device. +// 4) the name of the device instance, e.g. "eth0". +// 5) device-specific initialization data. +externC int synth_auxiliary_instantiate(const char*, const char*, const char*, const char*, const char*); + +// Support for generating strings +#define SYNTH_MAKESTRING1(a) #a +#define SYNTH_MAKESTRING(a) SYNTH_MAKESTRING1(a) //----------------------------------------------------------------------------- #endif // ifndef CYGONCE_HAL_HAL_IO_H
--- a/packages/hal/synth/arch/current/src/synth_diag.c +++ b/packages/hal/synth/arch/current/src/synth_diag.c @@ -8,6 +8,7 @@ //####ECOSGPLCOPYRIGHTBEGIN#### // ------------------------------------------- // This file is part of eCos, the Embedded Configurable Operating System. +// Copyright (C) 2002 Bart Veer // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. // // eCos is free software; you can redistribute it and/or modify it under @@ -65,17 +66,25 @@ #include <cyg/infra/cyg_ass.h> //----------------------------------------------------------------------------- - -// When the auxiliary exists, hal_diag_init() will need to contact it and -// get hold of a suitable console device. +// If the auxiliary exists, hal_diag_init() will try to contact it and +// instantiate a console device. Subsequent console writes will be +// redirected to that device, as long as the auxiliary is up and running. +// If the auxiliary is not being used or has exited, console writes +// will instead go to stdout. // -// When interacting with stdin/stdout, arguably there should be some -// manipulation of tty settings e.g. to support single character -// input. However it is not clear which settings would be preferable -// to the default. +// This code also contains an implementation of hal_diag_read_char() +// which is probably not very useful. Currently it works by reading +// from stdin, but no attempt is made to set the tty into raw mode +// or anything like that. + +static int auxiliary_console_id = -1; void hal_diag_init( void ) { + if (synth_auxiliary_running) { + auxiliary_console_id = synth_auxiliary_instantiate("hal/synth/arch", SYNTH_MAKESTRING(CYGPKG_HAL_SYNTH), "console", + (const char*) 0, (const char*) 0); + } } // Output a single character. @@ -86,39 +95,53 @@ void hal_diag_init( void ) // I/O intensive facilities like unbuffered tracing). Therefore // this code will buffer lines up to 128 characters before // doing the I/O. +// +// NOTE: one problem is that there is no support for flushing buffers +// at this level. Therefore if say C library stdio ends up mapped to +// HAL diagnostics I/O then functions like fflush() and setvbuf() will +// not behave the way they should. There is no simple workaround at +// this level, the required information is not available. void hal_diag_write_char(char c) { static int diag_index = 0; - static char diag_buffer[128]; + static unsigned char diag_buffer[128]; CYG_ASSERT(diag_index < 128, "Diagnostic buffer overflow"); - diag_buffer[diag_index++] = c; + diag_buffer[diag_index++] = (unsigned char) c; if (('\n' == c) || (128 == diag_index)) { - int written; - char* next = diag_buffer; + if ((-1 != auxiliary_console_id) && synth_auxiliary_running) { + synth_auxiliary_xchgmsg(auxiliary_console_id, 0, 0, 0, diag_buffer, diag_index, (int *) 0, (unsigned char*) 0, (int *)0, 0); + diag_index = 0; + } else { + int written; + char* next = diag_buffer; - while (diag_index > 0) { - written = cyg_hal_sys_write(1, next, diag_index); - if (written > 0) { - diag_index -= written; - next += written; - } else if ((-CYG_HAL_SYS_EINTR != written) && (-CYG_HAL_SYS_EAGAIN != written)) { - CYG_FAIL("Unexpected error writing to stdout."); - diag_index = 0; - break; + while (diag_index > 0) { + written = cyg_hal_sys_write(1, next, diag_index); + if (written > 0) { + diag_index -= written; + next += written; + } else if ((-CYG_HAL_SYS_EINTR != written) && (-CYG_HAL_SYS_EAGAIN != written)) { + CYG_FAIL("Unexpected error writing to stdout."); + diag_index = 0; + break; + } } + CYG_ASSERT(0 == diag_index, "All data should have been written out"); + diag_index = 0; + cyg_hal_sys_fdatasync(1); } - CYG_ASSERT(0 == diag_index, "All data should have been written out"); - diag_index = 0; - cyg_hal_sys_fdatasync(1); } } -// Diagnostic input. It is not clear that this is actually useful. The -// read syscall will get woken up by the itimer alarm, but we don't -// want to stop reading if that's the case +// Diagnostic input. It is not clear that this is actually useful, +// input would normally go to gdb rather than to the application. If +// keyboard input really is required then that should be handled via a +// suitable device driver interacting with the auxiliary, not at the +// HAL level. The read syscall will get woken up by the itimer alarm, +// but we don't want to stop reading if that's the case void hal_diag_read_char(char *c) {
--- a/packages/hal/synth/arch/current/src/synth_entry.c +++ b/packages/hal/synth/arch/current/src/synth_entry.c @@ -8,6 +8,7 @@ //####ECOSGPLCOPYRIGHTBEGIN#### // ------------------------------------------- // This file is part of eCos, the Embedded Configurable Operating System. +// Copyright (C) 2002 Bart Veer // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. // // eCos is free software; you can redistribute it and/or modify it under @@ -99,6 +100,8 @@ cyg_hal_invoke_constructors (void) // startup. externC void cyg_start( void ); +externC void synth_hardware_init(void); +externC void synth_hardware_init2(void); void _linux_entry( void ) { @@ -135,9 +138,9 @@ void _linux_entry( void ) // "Initialize any global pointer register". There is no such register. // Perform platform-specific initialization. Actually, all Linux - // platforms can share this. It involves setting up signal handlers - // and so on. - hal_synthetic_target_init(); + // platforms can share this. It involves setting up signal handlers, + // starting the I/O auxiliary, and so on. + synth_hardware_init(); // This is not a ROM startup, so no need to worry about copying the // .data section. @@ -149,6 +152,14 @@ void _linux_entry( void ) // Invoke the C++ constructors. cyg_hal_invoke_constructors(); + // Once the C++ constructors have been invoked, a second stage + // of hardware initialization is desirable. At this point all + // eCos device drivers should have been initialized so the + // I/O auxiliary will have loaded the appropriate support + // scripts, and the auxiliary can now map the window(s) on to + // the display and generally operate normally. + synth_hardware_init2(); + // "Call cyg_start()". OK. cyg_start();
--- a/packages/hal/synth/arch/current/src/synth_intr.c +++ b/packages/hal/synth/arch/current/src/synth_intr.c @@ -8,6 +8,7 @@ //####ECOSGPLCOPYRIGHTBEGIN#### // ------------------------------------------- // This file is part of eCos, the Embedded Configurable Operating System. +// Copyright (C) 2002 Bart Veer // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. // // eCos is free software; you can redistribute it and/or modify it under @@ -50,32 +51,34 @@ // sigprocmask handling. // // In the synthetic target interrupts and exceptions are based around -// POSIX sighandlerals. When the clock ticks a SIGALRM signal is raised. +// POSIX sighandlers. When the clock ticks a SIGALRM signal is raised. // When the I/O auxiliary wants to raise some other interrupt, it // sends a SIGIO signal. When an exception occurs this results in // signals like SIGILL and SIGSEGV. This implies an implementation -// where the VSR is the signal handler. Disabling interrupts then -// means using sigprocmask() to block certain signals, and enabling -// interrupts means unblocking those signals. +// where the VSR is the signal handler. Disabling interrupts would +// then mean using sigprocmask() to block certain signals, and +// enabling interrupts means unblocking those signals. // // However there are a few problems. One of these is performance: some // bits of the system such as buffered tracing make very extensive use // of enabling and disabling interrupts, so making a sigprocmask // system call each time adds a lot of overhead. More seriously, there // is a subtle discrepancy between POSIX signal handling and hardware -// interrupts. It is expected that signal handlers return, and then -// the system automatically passes control back to the foreground thread. +// interrupts. Signal handlers are expected to return, and then the +// system automatically passes control back to the foreground thread. // In the process, the sigprocmask is manipulated before invoking the // signal handler and restored afterwards. Interrupt handlers are // different: it is quite likely that an interrupt results in another -// eCos thread being activated, so the signal handler does not actually -// return until the interrupted thread gets another chance to run. +// eCos thread being activated, so the signal handler does not +// actually return until the interrupted thread gets another chance to +// run. // -// The second problem can be addressed by making the sigprocmask part of -// the thread state, saving and restoring it as part of a context switch. -// This matches quite nicely onto typical real hardware, where there might -// be a flag inside some control register that controls whether or not -// interrupts are enabled. However this adds further to the overhead. +// The second problem can be addressed by making the sigprocmask part +// of the thread state, saving and restoring it as part of a context +// switch (c.f. siglongjmp()). This matches quite nicely onto typical +// real hardware, where there might be a flag inside some control +// register that controls whether or not interrupts are enabled. +// However this adds more system calls to context switch overhead. // // The alternative approach is to implement interrupt enabling and // disabling in software. The sigprocmask is manipulated only once, @@ -93,14 +96,14 @@ // interrupts. This is not currently implemented. // // At first glance it might seem that an interrupt stack could be -// implemented trivially using sigaltstack. This does not quite work. -// The problem is that signal handlers do not always return -// immediately, so the system does not get a chance to clean up the -// signal handling stack. A separate interrupt stack is possible but -// would have to be implemented here, in software, e.g. by having the -// signal handler invoke the VSR on that stack. Unfortunately the -// system may have pushed quite a lot of state on to the current stack -// already when raising the signal, so things could get messy. +// implemented trivially using sigaltstack. This does not quite work: +// signal handlers do not always return immediately, so the system +// does not get a chance to clean up the signal handling stack. A +// separate interrupt stack is possible but would have to be +// implemented here, in software, e.g. by having the signal handler +// invoke the VSR on that stack. Unfortunately the system may have +// pushed quite a lot of state on to the current stack already when +// raising the signal, so things could get messy. // ---------------------------------------------------------------------------- #include <pkgconf/hal.h> @@ -114,11 +117,14 @@ #endif #include <cyg/infra/cyg_type.h> // base types +#include <cyg/infra/diag.h> #include <cyg/hal/hal_arch.h> #include <cyg/hal/hal_intr.h> #include <cyg/hal/hal_io.h> #include <cyg/infra/cyg_ass.h> // Assertions are safe in the synthetic target +#include "synth_protocol.h" + // ---------------------------------------------------------------------------- // Statics. @@ -138,10 +144,10 @@ static volatile cyg_bool_t synth_sigalr static void (*synth_VSR)(void) = (void (*)(void)) 0; // The current ISR status and mask registers, or rather software -// emulations there of. These are not static since -// application-specific VSRs may want to examine/manipulate these. -// They are also not exported in any header file, forcing people -// writing such VSRs to know what they are doing. +// emulations thereof. These are not static since application-specific +// VSRs may want to examine/manipulate these. They are also not +// exported in any header file, forcing people writing such VSRs to +// know what they are doing. volatile cyg_uint32 synth_pending_isrs = 0; volatile cyg_uint32 synth_masked_isrs = 0xFFFFFFFF; @@ -171,12 +177,18 @@ synth_default_isr(cyg_vector_t vector, c return CYG_ISR_HANDLED; } -// The VSR is invoked under the following circumstances: +// The VSR is invoked +// 1) directly by a SIGALRM or SIGIO signal handler, if interrupts +// were enabled. +// 2) indirectly by hal_enable_interrupts(), if a signal happened +// while interrupts were disabled. hal_enable_interrupts() +// will have re-invoked the signal handler. // -// 1) interrupts were globally enabled, but are now disabled. -// 2) there are pending ISRs which are not masked off +// On entry interrupts are disabled, and there should be one or more +// pending ISRs which are not masked off. // -// The implementation is as per the HAL specification, where applicable. +// The implementation is as per the HAL specification, where +// applicable. static void synth_default_vsr(void) @@ -192,8 +204,8 @@ synth_default_vsr(void) // synchronously via enable_interrupts. // Increment the kernel scheduler lock, if the kernel is present. - // This prevents any attempts at context switching while interrupt - // handling is in progress. + // This prevents context switching while interrupt handling is in + // progress. #ifdef CYGFUN_HAL_COMMON_KERNEL_SUPPORT cyg_scheduler_lock(); #endif @@ -207,17 +219,20 @@ synth_default_vsr(void) // Decode the actual external interrupt being delivered. This is // determined from the pending and masked variables. Only one isr // source can be handled here, since interrupt_end must be invoked - // with details of that interrupt. + // with details of that interrupt. Multiple pending interrupts + // will be handled by a recursive call HAL_LSBIT_INDEX(isr_vector, (synth_pending_isrs & ~synth_masked_isrs)); CYG_ASSERT((CYGNUM_HAL_ISR_MIN <= isr_vector) && (isr_vector <= CYGNUM_HAL_ISR_MAX), "ISR vector must be valid"); - + isr_result = (*synth_isr_handlers[isr_vector].isr)(isr_vector, synth_isr_handlers[isr_vector].data); // Do not switch back from the interrupt stack, there isn't one. // Interrupts were not enabled before, so they must be enabled // now. This may result in a recursive invocation if other IRQs - // are still pending. + // are still pending. The ISR should have either acknowledged or + // masked the current interrupt source, to prevent a recursive + // call for the current interrupt. hal_enable_interrupts(); // Now call interrupt_end() with the result of the isr and the @@ -225,7 +240,7 @@ synth_default_vsr(void) // a context switch to another thread. In the latter case, when // the current thread is reactivated we end up back here. The // third argument should be a pointer to the saved state, but that - // is only relevant for thread-aware debugging which is not + // is only relevant for thread-aware debugging which is not yet // supported by the synthetic target. { extern void interrupt_end(cyg_uint32, CYG_ADDRESS, HAL_SavedRegisters*); @@ -238,7 +253,7 @@ synth_default_vsr(void) // Enabling interrupts. If a SIGALRM or SIGIO arrived at an inconvenient // time, e.g. when already interacting with the auxiliary, then these -// will have been left pending and must be servied now. Next, enabling +// will have been left pending and must be serviced now. Next, enabling // interrupts means checking the interrupt pending and mask registers // and seeing if the VSR should be invoked. void @@ -262,7 +277,7 @@ hal_enable_interrupts(void) // is to raise a signal, e.g. SIGUSR1. That way all interrupts // come in via the system's signal handling mechanism, and // it might be possible to do something useful with saved contexts - // etc. + // etc., facilitating thread-aware debugging. if (0 != (synth_pending_isrs & ~synth_masked_isrs)) { hal_interrupts_enabled = false; (*synth_VSR)(); @@ -457,11 +472,12 @@ synth_exception_sighandler(int sig) // handler for CYGNUM_HAL_INTERRUPT_RTC, but it depends on the HAL // for low-level manipulation of the clock hardware. // -// There is a problem with HAL_CLOCK_READ(). The obvious implementation -// would use getitimer(), but that has the wrong behaviour: it is intended -// for fairly coarse intervals and works in terms of system clock ticks, -// as opposed to a fine-grained implementation that actually examines the -// system clock. Instead it is necessary to use gettimeofday(). +// There is a problem with HAL_CLOCK_READ(). The obvious +// implementation would use getitimer(), but that has the wrong +// behaviour: it is intended for fairly coarse intervals and works in +// terms of system clock ticks, as opposed to a fine-grained +// implementation that actually examines the system clock. Instead use +// gettimeofday(). static struct cyg_hal_sys_timeval synth_clock = { 0, 0 }; @@ -470,7 +486,8 @@ hal_clock_initialize(cyg_uint32 period) { struct cyg_hal_sys_itimerval timer; - // Needed for hal_clock_read() + // Needed for hal_clock_read(), if HAL_CLOCK_READ() is used before + // the first clock interrupt. cyg_hal_sys_gettimeofday(&synth_clock, (struct cyg_hal_sys_timezone*) 0); // The synthetic target clock resolution is in microseconds. A typical @@ -508,7 +525,8 @@ synth_alrm_sighandler(int sig) // A timer signal means that IRQ 0 needs attention. synth_pending_isrs |= 0x01; - // If any of the pending interrupts are not masked, invoke the VSR + // If any of the pending interrupts are not masked, invoke the + // VSR. That will reenable interrupts. if (0 != (synth_pending_isrs & ~synth_masked_isrs)) { (*synth_VSR)(); } else { @@ -548,6 +566,22 @@ hal_clock_read(void) // there may already be ongoing communication with the auxiliary. // Instead some volatile flags are used to keep track of which signals // were raised while interrupts were disabled. +// +// It might be better to perform the interaction with the auxiliary +// as soon as possible, i.e. either in the SIGIO handler or when the +// current communication completes. That way the mask of pending +// interrupts would remain up to date even when interrupts are +// disabled, thus allowing applications to run in polled mode. + +// A little utility called when the auxiliary has been asked to exit, +// implicitly affecting this application as well. The sole purpose +// of this function is to put a suitably-named function on the stack +// to make it more obvious from inside gdb what is happening. +static void +synth_io_handle_shutdown_request_from_auxiliary(void) +{ + cyg_hal_sys_exit(0); +} static void synth_io_sighandler(int sig) @@ -564,7 +598,28 @@ synth_io_sighandler(int sig) // Update the interrupt status "register" to match pending interrupts // Contact the auxiliary to find out what interrupts are currently pending there. - CYG_FAIL("SIGIO should not occur until the auxiliary is implemented"); + // If there is no auxiliary at present, e.g. because it has just terminated + // and things are generally somewhat messy, ignore it. + // + // This code also deals with the case where the user has requested program + // termination. It would be wrong for the auxiliary to just exit, since the + // application could not distinguish that case from a crash. Instead the + // auxiliary can optionally return an additional byte of data, and if that + // byte actually gets sent then that indicates pending termination. + if (synth_auxiliary_running) { + int result; + int actual_len; + unsigned char dummy[1]; + synth_auxiliary_xchgmsg(SYNTH_DEV_AUXILIARY, SYNTH_AUXREQ_GET_IRQPENDING, 0, 0, + (const unsigned char*) 0, 0, // The auxiliary does not need any additional data + &result, dummy, &actual_len, 1); + synth_pending_isrs |= result; + if (actual_len) { + // The auxiliary has been asked to terminate by the user. This + // request has now been passed on to the eCos application. + synth_io_handle_shutdown_request_from_auxiliary(); + } + } // If any of the pending interrupts are not masked, invoke the VSR if (0 != (synth_pending_isrs & ~synth_masked_isrs)) { @@ -579,33 +634,17 @@ synth_io_sighandler(int sig) } // ---------------------------------------------------------------------------- -// SIGPIPE and SIGCHLD are special, related to the auxiliary process. -static void -synth_pipe_sighandler(int sig) -{ - CYG_ASSERT(CYG_HAL_SYS_SIGPIPE == sig, "The right signal handler should be invoked"); - CYG_FAIL("The auxiliary is not yet implemented"); -} - -static void -synth_chld_sighandler(int sig) -{ - CYG_ASSERT(CYG_HAL_SYS_SIGCHLD == sig, "The right signal handler should be invoked"); - CYG_FAIL("The auxiliary is not yet implemented"); -} - -// ---------------------------------------------------------------------------- // Here we define an action to do in the idle thread. For the -// synthetic architecture it makes no sense to spin eating processor -// time that other processes could make use of. Instead we call -// select. The itimer will still go off and kick the scheduler back -// into life so giving up an escape path from the select. There is one -// problem: in some configurations, e.g. when preemption is disabled, -// the idle thread must yield continuously rather than blocking. +// synthetic target it makes no sense to spin eating processor time +// that other processes could make use of. Instead we call select. The +// itimer will still go off and kick the scheduler back into life, +// giving us an escape path from the select. There is one problem: in +// some configurations, e.g. when preemption is disabled, the idle +// thread must yield continuously rather than blocking. void hal_idle_thread_action(cyg_uint32 loop_count) { -#ifndef CYGIMP_IDLE_THREAD_YIELD +#ifndef CYGIMP_HAL_IDLE_THREAD_SPIN cyg_hal_sys__newselect(0, (struct cyg_hal_sys_fd_set*) 0, (struct cyg_hal_sys_fd_set*) 0, @@ -614,11 +653,583 @@ hal_idle_thread_action(cyg_uint32 loop_c #endif CYG_UNUSED_PARAM(cyg_uint32, loop_count); } + +// ---------------------------------------------------------------------------- +// The I/O auxiliary. +// +// I/O happens via an auxiliary process. During startup this code attempts +// to locate and execute a program ecosynth which should be installed in +// ../libexec/ecosynth relative to some directory on the search path. +// Subsequent I/O operations involve interacting with this auxiliary. + +#define MAKESTRING1(a) #a +#define MAKESTRING2(a) MAKESTRING1(a) +#define AUXILIARY "../libexec/ecos/hal/synth/arch/" MAKESTRING2(CYGPKG_HAL_SYNTH) "/ecosynth" + +// Is the auxiliary up and running? +cyg_bool synth_auxiliary_running = false; + +// The pipes to and from the auxiliary. +static int to_aux = -1; +static int from_aux = -1; + +// Attempt to start up the auxiliary. Note that this happens early on +// during system initialization so it is "known" that the world is +// still simple, e.g. that no other files have been opened. +static void +synth_start_auxiliary(void) +{ +#define BUFSIZE 256 + char filename[BUFSIZE]; + const char* path = 0; + int i, j; + cyg_bool found = false; + int to_aux_pipe[2]; + int from_aux_pipe[2]; + int child; + int aux_version; +#if 1 + // Check for a command line argument -io. Only run the auxiliary if this + // argument is provided, i.e. default to traditional behaviour. + for (i = 1; i < cyg_hal_sys_argc; i++) { + const char* tmp = cyg_hal_sys_argv[i]; + if ('-' == *tmp) { + // Arguments beyond -- are reserved for use by the application, + // and should not be interpreted by the HAL itself or by ecosynth. + if (('-' == tmp[1]) && ('\0' == tmp[2])) { + break; + } + tmp++; + if ('-' == *tmp) { + // Do not distinguish between -io and --io + tmp++; + } + if (('i' == tmp[0]) && ('o' == tmp[1]) && ('\0' == tmp[2])) { + found = 1; + break; + } + } + } + if (!found) { + return; + } +#else + // Check for a command line argument -ni or -nio. Always run the + // auxiliary unless this argument is given, i.e. default to full + // I/O support. + for (i = 1; i < cyg_hal_sys_argc; i++) { + const char* tmp = cyg_hal_sys_argv[i]; + if ('-' == *tmp) { + if (('-' == tmp[1]) && ('\0' == tmp[2])) { + break; + } + tmp++; + if ('-' == *tmp) { + tmp++; + } + if ('n' == *tmp) { + tmp++; + if ('i' == *tmp) { + tmp++; + if ('\0' == *tmp) { + found = 1; // -ni or --ni + break; + } + if (('o' == *tmp) && ('\0' == tmp[1])) { + found = 1; // -nio or --nio + break; + } + } + } + } + } + if (found) { + return; + } +#endif + + // The auxiliary must be found relative to the current search path, + // so look for a PATH= environment variable. + for (i = 0; (0 == path) && (0 != cyg_hal_sys_environ[i]); i++) { + const char *var = cyg_hal_sys_environ[i]; + if (('P' == var[0]) && ('A' == var[1]) && ('T' == var[2]) && ('H' == var[3]) && ('=' == var[4])) { + path = var + 5; + } + } + if (0 == path) { + // Very unlikely, but just in case. + path = ".:/bin:/usr/bin"; + } + + found = 0; + while (!found && ('\0' != *path)) { // for every entry in the path + char *tmp = AUXILIARY; + + j = 0; + + // As a special case, an empty string in the path corresponds to the + // current directory. + if (':' == *path) { + filename[j++] = '.'; + } else { + while ((j < BUFSIZE) && ('\0' != *path) && (':' != *path)) { + filename[j++] = *path++; + } + // If not at the end of the search path, move on to the next entry. + if ('\0' != *path) { + while ((':' != *path) && ('\0' != *path)) { + path++; + } + if (':' == *path) { + path++; + } + } + } + // Now append a directory separator, and then the name of the executable. + if (j < BUFSIZE) { + filename[j++] = '/'; + } + while ((j < BUFSIZE) && ('\0' != *tmp)) { + filename[j++] = *tmp++; + } + // If there has been a buffer overflow, skip this entry. + if (j == BUFSIZE) { + filename[BUFSIZE-1] = '\0'; + diag_printf("Warning: buffer limit reached while searching PATH for the I/O auxiliary.\n"); + diag_printf(" : skipping current entry.\n"); + } else { + // filename now contains a possible match for the auxiliary. + filename[j++] = '\0'; + if (0 == cyg_hal_sys_access(filename, CYG_HAL_SYS_X_OK)) { + found = true; + } + } + } +#undef BUFSIZE + + if (!found) { + diag_printf("Error: unable to find the I/O auxiliary program on the current search PATH\n"); + diag_printf(" : please install the appropriate host-side tools.\n"); + cyg_hal_sys_exit(1); + } + + // An apparently valid executable exists (or at the very least it existed...), + // so create the pipes that will be used for communication. + if ((0 != cyg_hal_sys_pipe(to_aux_pipe)) || + (0 != cyg_hal_sys_pipe(from_aux_pipe))) { + diag_printf("Error: unable to set up pipes for communicating with the I/O auxiliary.\n"); + cyg_hal_sys_exit(1); + } + + // Time to fork(). + child = cyg_hal_sys_fork(); + if (child < 0) { + diag_printf("Error: failed to fork() process for the I/O auxiliary.\n"); + cyg_hal_sys_exit(1); + } else if (child == 0) { + cyg_bool found_dotdot; + // There should not be any problems rearranging the file descriptors as desired... + cyg_bool unexpected_error = 0; + + // In the child process. Close unwanted file descriptors, then some dup2'ing, + // and execve() the I/O auxiliary. The auxiliary will inherit stdin, + // stdout and stderr from the eCos application, so that functions like + // printf() work as expected. In addition fd 3 will be the pipe from + // the eCos application and fd 4 the pipe to the application. It is possible + // that the eCos application was run from some process other than a shell + // and hence that file descriptors 3 and 4 are already in use, but that is not + // supported. One possible workaround would be to close all file descriptors + // >= 3, another would be to munge the argument vector passing the file + // descriptors actually being used. + unexpected_error |= (0 != cyg_hal_sys_close(to_aux_pipe[1])); + unexpected_error |= (0 != cyg_hal_sys_close(from_aux_pipe[0])); + + if (3 != to_aux_pipe[0]) { + if (3 == from_aux_pipe[1]) { + // Because to_aux_pipe[] was set up first it should have received file descriptors 3 and 4. + diag_printf("Internal error: file descriptors have been allocated in an unusual order.\n"); + cyg_hal_sys_exit(1); + } else { + unexpected_error |= (3 != cyg_hal_sys_dup2(to_aux_pipe[0], 3)); + unexpected_error |= (0 != cyg_hal_sys_close(to_aux_pipe[0])); + } + } + if (4 != from_aux_pipe[1]) { + unexpected_error |= (4 != cyg_hal_sys_dup2(from_aux_pipe[1], 4)); + unexpected_error |= (0 != cyg_hal_sys_close(from_aux_pipe[1])); + } + if (unexpected_error) { + diag_printf("Error: internal error in auxiliary process, failed to manipulate pipes.\n"); + cyg_hal_sys_exit(1); + } + // The arguments passed to the auxiliary are mostly those for + // the synthetic target application, except for argv[0] which + // is replaced with the auxiliary's pathname. The latter + // currently holds at least one ../, and cleaning this up is + // useful. + // + // If the argument vector contains -- then that and subsequent + // arguments are not passed to the auxiliary. Instead such + // arguments are reserved for use by the application. + do { + int len; + for (len = 0; '\0' != filename[len]; len++) + ; + found_dotdot = false; + for (i = 0; i < (len - 4); i++) { + if (('/' == filename[i]) && ('.' == filename[i+1]) && ('.' == filename[i+2]) && ('/' == filename[i+3])) { + j = i + 3; + for ( --i; (i >= 0) && ('/' != filename[i]); i--) { + CYG_EMPTY_STATEMENT; + } + if (i >= 0) { + found_dotdot = true; + do { + i++; j++; + filename[i] = filename[j]; + } while ('\0' != filename[i]); + } + } + } + } while(found_dotdot); + + cyg_hal_sys_argv[0] = filename; + + for (i = 1; i < cyg_hal_sys_argc; i++) { + const char* tmp = cyg_hal_sys_argv[i]; + if (('-' == tmp[0]) && ('-' == tmp[1]) && ('\0' == tmp[2])) { + cyg_hal_sys_argv[i] = (const char*) 0; + break; + } + } + cyg_hal_sys_execve(filename, cyg_hal_sys_argv, cyg_hal_sys_environ); + + // An execute error has occurred. Report this here, then exit. The + // parent will detect a close on the pipe without having received + // any data, and it will assume that a suitable diagnostic will have + // been displayed already. + diag_printf("Error: failed to execute the I/O auxiliary.\n"); + cyg_hal_sys_exit(1); + } else { + int rc; + char buf[1]; + + // Still executing the eCos application. + // Do some cleaning-up. + to_aux = to_aux_pipe[1]; + from_aux = from_aux_pipe[0]; + if ((0 != cyg_hal_sys_close(to_aux_pipe[0])) || + (0 != cyg_hal_sys_close(from_aux_pipe[1]))) { + diag_printf("Error: internal error in main process, failed to manipulate pipes.\n"); + cyg_hal_sys_exit(1); + } + + // It is now a good idea to block until the auxiliary is + // ready, i.e. give it a chance to read in its configuration + // files, load appropriate scripts, pop up windows, ... This + // may take a couple of seconds or so. Once the auxiliary is + // ready it will write a single byte down the pipe. This is + // the only time that the auxiliary will write other than when + // responding to a request. + do { + rc = cyg_hal_sys_read(from_aux, buf, 1); + } while (-CYG_HAL_SYS_EINTR == rc); + + if (1 != rc) { + // The auxiliary has not started up successfully, so exit + // immediately. It should have generated appropriate + // diagnostics. + cyg_hal_sys_exit(1); + } + } + + // At this point the auxiliary is up and running. It should not + // generate any interrupts just yet since none of the devices have + // been initialized. Remember that the auxiliary is now running, + // so that the initialization routines for those devices can + // figure out that they should interact with the auxiliary rather + // than attempt anything manually. + synth_auxiliary_running = true; + + // Make sure that the auxiliary is the right version. + synth_auxiliary_xchgmsg(SYNTH_DEV_AUXILIARY, SYNTH_AUXREQ_GET_VERSION, 0, 0, + (const unsigned char*) 0, 0, + &aux_version, (unsigned char*) 0, (int*) 0, 0); + if (SYNTH_AUXILIARY_PROTOCOL_VERSION != aux_version) { + synth_auxiliary_running = false; + diag_printf("Error: an incorrect version of the I/O auxiliary is installed\n" + " Expected version %d, actual version %d\n" + " Installed binary is %s\n", + SYNTH_AUXILIARY_PROTOCOL_VERSION, aux_version, filename); + cyg_hal_sys_exit(1); + } +} + +// Write a request to the I/O auxiliary, and optionally get back a +// reply. The dev_id is 0 for messages intended for the auxiliary +// itself, for example a device instantiation or a request for the +// current interrupt sate. Otherwise it identifies a specific device. +// The request code is specific to the device, and the two optional +// arguments are specific to the request. +void +synth_auxiliary_xchgmsg(int devid, int reqcode, int arg1, int arg2, + const unsigned char* txdata, int txlen, + int* result, + unsigned char* rxdata, int* actual_rxlen, int rxlen) +{ + unsigned char request[SYNTH_REQUEST_LENGTH]; + unsigned char reply[SYNTH_REPLY_LENGTH]; + int rc; + int reply_rxlen; + cyg_bool_t old_isrstate; + + CYG_ASSERT(devid >= 0, "A valid device id should be supplied"); + CYG_ASSERT((0 == txlen) || ((const unsigned char*)0 != txdata), "Data transmits require a transmit buffer"); + CYG_ASSERT((0 == rxlen) || ((unsigned char*)0 != rxdata), "Data receives require a receive buffer"); + CYG_ASSERT((0 == rxlen) || ((int*)0 != result), "If a reply is expected then space must be allocated"); + + // I/O interactions with the auxiliary must be atomic: a context switch in + // between sending the header and the actual data would be bad. + HAL_DISABLE_INTERRUPTS(old_isrstate); + + // The auxiliary should be running for the duration of this + // exchange. However the auxiliary can disappear asynchronously, + // so it is not possible for higher-level code to be sure that the + // auxiliary is still running. + // + // If the auxiliary disappears during this call then usually this + // will cause a SIGCHILD or SIGPIPE, both of which result in + // termination. The exception is when the auxiliary decides to + // shut down stdout for some reason without exiting - that has to + // be detected in the read loop. + if (synth_auxiliary_running) { + request[SYNTH_REQUEST_DEVID_OFFSET + 0] = (devid >> 0) & 0x0FF; + request[SYNTH_REQUEST_DEVID_OFFSET + 1] = (devid >> 8) & 0x0FF; + request[SYNTH_REQUEST_DEVID_OFFSET + 2] = (devid >> 16) & 0x0FF; + request[SYNTH_REQUEST_DEVID_OFFSET + 3] = (devid >> 24) & 0x0FF; + request[SYNTH_REQUEST_REQUEST_OFFSET + 0] = (reqcode >> 0) & 0x0FF; + request[SYNTH_REQUEST_REQUEST_OFFSET + 1] = (reqcode >> 8) & 0x0FF; + request[SYNTH_REQUEST_REQUEST_OFFSET + 2] = (reqcode >> 16) & 0x0FF; + request[SYNTH_REQUEST_REQUEST_OFFSET + 3] = (reqcode >> 24) & 0x0FF; + request[SYNTH_REQUEST_ARG1_OFFSET + 0] = (arg1 >> 0) & 0x0FF; + request[SYNTH_REQUEST_ARG1_OFFSET + 1] = (arg1 >> 8) & 0x0FF; + request[SYNTH_REQUEST_ARG1_OFFSET + 2] = (arg1 >> 16) & 0x0FF; + request[SYNTH_REQUEST_ARG1_OFFSET + 3] = (arg1 >> 24) & 0x0FF; + request[SYNTH_REQUEST_ARG2_OFFSET + 0] = (arg1 >> 0) & 0x0FF; + request[SYNTH_REQUEST_ARG2_OFFSET + 1] = (arg1 >> 8) & 0x0FF; + request[SYNTH_REQUEST_ARG2_OFFSET + 2] = (arg1 >> 16) & 0x0FF; + request[SYNTH_REQUEST_ARG2_OFFSET + 3] = (arg1 >> 24) & 0x0FF; + request[SYNTH_REQUEST_TXLEN_OFFSET + 0] = (txlen >> 0) & 0x0FF; + request[SYNTH_REQUEST_TXLEN_OFFSET + 1] = (txlen >> 8) & 0x0FF; + request[SYNTH_REQUEST_TXLEN_OFFSET + 2] = (txlen >> 16) & 0x0FF; + request[SYNTH_REQUEST_TXLEN_OFFSET + 3] = (txlen >> 24) & 0x0FF; + request[SYNTH_REQUEST_RXLEN_OFFSET + 0] = (rxlen >> 0) & 0x0FF; + request[SYNTH_REQUEST_RXLEN_OFFSET + 1] = (rxlen >> 8) & 0x0FF; + request[SYNTH_REQUEST_RXLEN_OFFSET + 2] = (rxlen >> 16) & 0x0FF; + request[SYNTH_REQUEST_RXLEN_OFFSET + 3] = ((rxlen >> 24) & 0x0FF) | (((int*)0 != result) ? 0x080 : 0); + + // sizeof(synth_auxiliary_request) < PIPE_BUF (4096) so a single write should be atomic, + // subject only to incoming clock or SIGIO or child-related signals. + do { + rc = cyg_hal_sys_write(to_aux, (const void*) &request, SYNTH_REQUEST_LENGTH); + } while (-CYG_HAL_SYS_EINTR == rc); + + // Is there any more data to be sent? + if (0 < txlen) { + int sent = 0; + CYG_LOOP_INVARIANT(synth_auxiliary_running, "The auxiliary cannot just disappear"); + + while (sent < txlen) { + rc = cyg_hal_sys_write(to_aux, (const void*) &(txdata[sent]), txlen - sent); + if (-CYG_HAL_SYS_EINTR == rc) { + continue; + } else if (rc < 0) { + diag_printf("Internal error: unexpected result %d when sending buffer to auxiliary.\n", rc); + diag_printf(" : this application is exiting immediately.\n"); + cyg_hal_sys_exit(1); + } else { + sent += rc; + } + } + CYG_ASSERT(sent <= txlen, "Amount of data sent should not exceed requested size"); + } + + // The auxiliary can now process this entire request. Is a reply expected? + if ((int*)0 != result) { + // The basic reply is also only a small number of bytes, so should be atomic. + do { + rc = cyg_hal_sys_read(from_aux, (void*) &reply, SYNTH_REPLY_LENGTH); + } while (-CYG_HAL_SYS_EINTR == rc); + if (rc <= 0) { + if (rc < 0) { + diag_printf("Internal error: unexpected result %d when receiving data from auxiliary.\n", rc); + } else { + diag_printf("Internal error: EOF detected on pipe from auxiliary.\n"); + } + diag_printf(" : this application is exiting immediately.\n"); + cyg_hal_sys_exit(1); + } + CYG_ASSERT(SYNTH_REPLY_LENGTH == rc, "The correct amount of data should have been read"); + + // Replies are packed in Tcl and assumed to be two 32-bit + // little-endian integers. + *result = (reply[SYNTH_REPLY_RESULT_OFFSET + 3] << 24) | + (reply[SYNTH_REPLY_RESULT_OFFSET + 2] << 16) | + (reply[SYNTH_REPLY_RESULT_OFFSET + 1] << 8) | + (reply[SYNTH_REPLY_RESULT_OFFSET + 0] << 0); + reply_rxlen = (reply[SYNTH_REPLY_RXLEN_OFFSET + 3] << 24) | + (reply[SYNTH_REPLY_RXLEN_OFFSET + 2] << 16) | + (reply[SYNTH_REPLY_RXLEN_OFFSET + 1] << 8) | + (reply[SYNTH_REPLY_RXLEN_OFFSET + 0] << 0); + + CYG_ASSERT(reply_rxlen <= rxlen, "The auxiliary should not be sending more data than was requested."); + + if ((int*)0 != actual_rxlen) { + *actual_rxlen = reply_rxlen; + } + if (reply_rxlen) { + int received = 0; + + while (received < reply_rxlen) { + rc = cyg_hal_sys_read(from_aux, (void*) &(rxdata[received]), reply_rxlen - received); + if (-CYG_HAL_SYS_EINTR == rc) { + continue; + } else if (rc <= 0) { + if (rc < 0) { + diag_printf("Internal error: unexpected result %d when receiving data from auxiliary.\n", rc); + } else { + diag_printf("Internal error: EOF detected on pipe from auxiliary.\n"); + } + diag_printf(" : this application is exiting immediately.\n"); + } else { + received += rc; + } + } + CYG_ASSERT(received == reply_rxlen, "Amount received should be exact"); + } + } + } + + HAL_RESTORE_INTERRUPTS(old_isrstate); +} + +// Instantiate a device. This takes arguments such as +// devs/eth/synth/ecosynth, current, ethernet, eth0, and 200x100 If +// the package and version are NULL strings then the device being +// initialized is application-specific and does not belong to any +// particular package. +int +synth_auxiliary_instantiate(const char* pkg, const char* version, const char* devtype, const char* devinst, const char* devdata) +{ + int result = -1; + char buf[512 + 1]; + const char* str; + int index; + + CYG_ASSERT((const char*)0 != devtype, "Device instantiations must specify a valid device type"); + CYG_ASSERT((((const char*)0 != pkg) && ((const char*)0 != version)) || \ + (((const char*)0 == pkg) && ((const char*)0 == version)), "If a package is specified then the version must be supplied as well"); + + index = 0; + str = pkg; + if ((const char*)0 == str) { + str = ""; + } + while ( (index < 512) && ('\0' != *str) ) { + buf[index++] = *str++; + } + if (index < 512) buf[index++] = '\0'; + str = version; + if ((const char*)0 == str) { + str = ""; + } + while ((index < 512) && ('\0' != *str) ) { + buf[index++] = *str++; + } + if (index < 512) buf[index++] = '\0'; + for (str = devtype; (index < 512) && ('\0' != *str); ) { + buf[index++] = *str++; + } + if (index < 512) buf[index++] = '\0'; + if ((const char*)0 != devinst) { + for (str = devinst; (index < 512) && ('\0' != *str); ) { + buf[index++] = *str++; + } + } + if (index < 512) buf[index++] = '\0'; + if ((const char*)0 != devdata) { + for (str = devdata; (index < 512) && ('\0' != *str); ) { + buf[index++] = *str++; + } + } + if (index < 512) { + buf[index++] = '\0'; + } else { + diag_printf("Internal error: buffer overflow constructing instantiate request for auxiliary.\n"); + diag_printf(" : this application is exiting immediately.\n"); + cyg_hal_sys_exit(1); + } + + if (synth_auxiliary_running) { + synth_auxiliary_xchgmsg(SYNTH_DEV_AUXILIARY, SYNTH_AUXREQ_INSTANTIATE, 0, 0, + buf, index, + &result, + (unsigned char*) 0, (int *) 0, 0); + } + return result; +} + +// ---------------------------------------------------------------------------- +// SIGPIPE and SIGCHLD are special, related to the auxiliary process. +// +// A SIGPIPE can only happen when the application is writing to the +// auxiliary, which only happens inside synth_auxiliary_xchgmsg() (this +// assumes that no other code is writing down a pipe, e.g. to interact +// with a process other than the standard I/O auxiliary). Either the +// auxiliary has explicitly closed the pipe, which it is not supposed +// to do, or more likely it has exited. Either way, there is little +// point in continuing - unless we already know that the system is +// shutting down. +static void +synth_pipe_sighandler(int sig) +{ + CYG_ASSERT(CYG_HAL_SYS_SIGPIPE == sig, "The right signal handler should be invoked"); + if (synth_auxiliary_running) { + synth_auxiliary_running = false; + diag_printf("Internal error: communication with the I/O auxiliary has been lost.\n"); + diag_printf(" : this application is exiting immediately.\n"); + cyg_hal_sys_exit(1); + } +} + +// Similarly it is assumed that there will be no child processes other than +// the auxiliary. Therefore a SIGCHLD indicates that the auxiliary has +// terminated unexpectedly. This is bad: normal termination involves +// the application exiting and the auxiliary terminating in response, +// not the other way around. +// +// As a special case, if it is known that the auxiliary is not currently +// usable then the signal is ignored. This copes with the situation where +// the auxiliary has just been fork()'d but has failed to initialize, or +// alternatively where the whole system is in the process of shutting down +// cleanly and it happens that the auxiliary got there first. +static void +synth_chld_sighandler(int sig) +{ + CYG_ASSERT(CYG_HAL_SYS_SIGCHLD == sig, "The right signal handler should be invoked"); + if (synth_auxiliary_running) { + synth_auxiliary_running = false; + diag_printf("Internal error: the I/O auxiliary has terminated unexpectedly.\n"); + diag_printf(" : this application is exiting immediately.\n"); + cyg_hal_sys_exit(1); + } +} + // ---------------------------------------------------------------------------- // Initialization void -hal_synthetic_target_init(void) +synth_hardware_init(void) { struct cyg_hal_sys_sigaction action; struct cyg_hal_sys_sigset_t blocked; @@ -676,8 +1287,8 @@ hal_synthetic_target_init(void) CYG_FAIL("Failed to install signal handler for SIGIO"); } - // Now install handlers for the various exceptions. For now these - // also operate with unchanged sigprocmasks, allowing nested + // Install handlers for the various exceptions. For now these also + // operate with unchanged sigprocmasks, allowing nested // exceptions. It is not clear that this is entirely a good idea, // but in practice these exceptions will usually be handled by gdb // anyway. @@ -704,9 +1315,13 @@ hal_synthetic_target_init(void) CYG_FAIL("Failed to install signal handler for SIGPIPE"); } action.hal_handler = &synth_chld_sighandler; + action.hal_flags |= CYG_HAL_SYS_SA_NOCLDSTOP | CYG_HAL_SYS_SA_NOCLDWAIT; if (0 != cyg_hal_sys_sigaction(CYG_HAL_SYS_SIGCHLD, &action, (struct cyg_hal_sys_sigaction*) 0)) { CYG_FAIL("Failed to install signal handler for SIGCHLD"); } + + // Start up the auxiliary process. + synth_start_auxiliary(); // All done. At this stage interrupts are still disabled, no ISRs // have been installed, and the clock is not yet ticking. @@ -714,3 +1329,31 @@ hal_synthetic_target_init(void) // and SIGALRM could come in, but nothing has yet been done // to make that happen. } + +// Second-stage hardware init. This is called after all C++ static +// constructors have been run, which should mean that all device +// drivers have been initialized and will have performed appropriate +// interactions with the I/O auxiliary. There should now be a +// message exchange with the auxiliary to let it know that there will +// not be any more devices, allowing it to remove unwanted frames, +// run the user's mainrc.tcl script, and so on. Also this is the +// time that the various toplevels get mapped on to the display. +// +// This request blocks until the auxiliary is ready. The return value +// indicates whether or not any errors occurred on the auxiliary side, +// and that those errors have not been suppressed using --keep-going + +void +synth_hardware_init2(void) +{ + if (synth_auxiliary_running) { + int result; + synth_auxiliary_xchgmsg(SYNTH_DEV_AUXILIARY, SYNTH_AUXREQ_CONSTRUCTORS_DONE, + 0, 0, (const unsigned char*) 0, 0, + &result, + (unsigned char*) 0, (int*) 0, 0); + if ( !result ) { + cyg_hal_sys_exit(1); + } + } +}
new file mode 100644 --- /dev/null +++ b/packages/hal/synth/arch/current/src/synth_protocol.h @@ -0,0 +1,124 @@ +#ifndef CYGONCE_HAL_SYNTH_PROTOCOL_H +#define CYGONCE_HAL_SYNTH_PROTOCOL_H + +//============================================================================= +// +// synth_protocol.h +// +// Generic protocol between eCos and the I/O auxiliary. +// +//============================================================================= +//####ECOSGPLCOPYRIGHTBEGIN#### +// ------------------------------------------- +// This file is part of eCos, the Embedded Configurable Operating System. +// Copyright (C) 2002 Bart Veer +// +// eCos is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 or (at your option) any later version. +// +// eCos is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License along +// with eCos; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. +// +// As a special exception, if other files instantiate templates or use macros +// or inline functions from this file, or you compile this file and link it +// with other works to produce a work based on this file, this file does not +// by itself cause the resulting work to be covered by the GNU General Public +// License. However the source code for this file must still be made available +// in accordance with section (3) of the GNU General Public License. +// +// This exception does not invalidate any other reasons why a work based on +// this file might be covered by the GNU General Public License. +// +// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. +// at http://sources.redhat.com/ecos/ecos-license/ +// ------------------------------------------- +//####ECOSGPLCOPYRIGHTEND#### +//============================================================================= +//#####DESCRIPTIONBEGIN#### +// +// Author(s): bartv +// Contributors:bartv +// Date: 2002-08-05 +// Purpose: Protocol definitions. +// Description: This header file defines the protocol used between the +// synthetic target HAL and the I/O auxiliary. The relevant +// code in the latter is implemented in Tcl (making +// use of the "binary" command) so this header file is +// not actually used on the host-side. Instead the protocol +// is defined in terms of byte arrays. +// +// The header file is not exported to any higher-level packages +// that wish to communicate with the auxiliary. Instead those +// packages are expected to use the functions synth_auxiliary_xchgmsg() +// and synth_auxiliary_instantiate(). +// +// Usage: #include "synth_protocol.h" +// +//####DESCRIPTIONEND#### +// +//============================================================================= + +// Messages from the eCos synthetic target application to the I/O +// auxiliary are exactly 24 bytes long, consisting of six 32-bit +// little-endian integers. Inside the auxiliary they will be decoded +// using the Tcl binary scan command and the format i6. The top bit +// of RXLEN is overloaded to indicate whether or not a reply is expected +// at all. +#define SYNTH_REQUEST_LENGTH 24 +#define SYNTH_REQUEST_DEVID_OFFSET 0 +#define SYNTH_REQUEST_REQUEST_OFFSET 4 +#define SYNTH_REQUEST_ARG1_OFFSET 8 +#define SYNTH_REQUEST_ARG2_OFFSET 12 +#define SYNTH_REQUEST_TXLEN_OFFSET 16 +#define SYNTH_REQUEST_RXLEN_OFFSET 20 + +// And the response. This consists of two 32-bit little-endian integers, +// a result code and an actual rx_len field. +#define SYNTH_REPLY_LENGTH 8 +#define SYNTH_REPLY_RESULT_OFFSET 0 +#define SYNTH_REPLY_RXLEN_OFFSET 4 + +// Device 0 is special, it is for control messages with the auxiliary +// itself - for example, to instantiate a device. +#define SYNTH_DEV_AUXILIARY 0 + +// Requests intended directly for the auxiliary. + +// Instantiate a device. arg1 and arg2 are ignored. The tx buffer +// holds a string for the given device. The rx buffer will be for a +// single integer, the device id or -1. +#define SYNTH_AUXREQ_INSTANTIATE 0x01 + +// Second-stage initialization, once all eCos device drivers have been +// activated. +#define SYNTH_AUXREQ_CONSTRUCTORS_DONE 0x02 + +// Get the current mask of pending interrupts. arg1 and arg2 are +// ignored, and there is no tx buffer. The reply code holds the irq +// pending mask. Normally there is no additional reply data, but if +// rx_len is non-zero then that indicates that the auxiliary has been +// asked to exit. +#define SYNTH_AUXREQ_GET_IRQPENDING 0x03 + +// Versioning. The core protocol cannot be changed without breaking +// lots of code. However it is still a good idea to allow the eCos +// application to verify that the host-side is the right version, in +// case new requests are added. arg1 and arg2 are ignored, there is no +// tx buffer or reply data, and the reply code holds the version. +#define SYNTH_AUXREQ_GET_VERSION 0x04 + +// The version has to be kept in synch with ecosynth.tcl +#define SYNTH_AUXILIARY_PROTOCOL_VERSION 0x01 + +// The console device is also provided by the architectural package, +// but only implements one function (write some output) so there is no +// need for any function codes. + +#endif // CYGONCE_HAL_SYNTH_PROTOCOL.H
--- a/packages/hal/synth/i386linux/current/ChangeLog +++ b/packages/hal/synth/i386linux/current/ChangeLog @@ -1,3 +1,8 @@ +2002-09-15 Bart Veer <bartv@ecoscentric.com> + + * src/syscall-i386-linux-1.0.S: + Add access system call + 2002-08-04 Bart Veer <bartv@tymora.demon.co.uk> * src/vectors.S (_start):
