⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ecosynth.tcl

📁 eCos操作系统源码
💻 TCL
📖 第 1 页 / 共 5 页
字号:
# {{{  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 nonefconfigure $synth::_channel_from_app -encoding binaryfconfigure $synth::_channel_to_app   -encoding binaryfconfigure $synth::_channel_from_app -translation binaryfconfigure $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, ...#

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -