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

📄 synth-new-host.html

📁 有关ecos2。0介绍了实时嵌入式的结构以及线程调度的实现和内存的管理等
💻 HTML
📖 第 1 页 / 共 3 页
字号:
<!-- Copyright (C) 2003 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"><METANAME="GENERATOR"CONTENT="Modular DocBook HTML Stylesheet Version 1.76b+"><LINKREL="HOME"TITLE="eCos Reference Manual"HREF="ecos-ref.html"><LINKREL="UP"TITLE="eCos Synthetic Target"HREF="hal-synth-arch.html"><LINKREL="PREVIOUS"TITLE="Writing New Devices - target"HREF="synth-new-target.html"><LINKREL="NEXT"TITLE="Porting"HREF="synth-porting.html"></HEAD><BODYCLASS="REFENTRY"BGCOLOR="#FFFFFF"TEXT="#000000"LINK="#0000FF"VLINK="#840084"ALINK="#0000FF"><DIVCLASS="NAVHEADER"><TABLESUMMARY="Header navigation table"WIDTH="100%"BORDER="0"CELLPADDING="0"CELLSPACING="0"><TR><THCOLSPAN="3"ALIGN="center">eCos Reference Manual</TH></TR><TR><TDWIDTH="10%"ALIGN="left"VALIGN="bottom"><AHREF="synth-new-target.html"ACCESSKEY="P">Prev</A></TD><TDWIDTH="80%"ALIGN="center"VALIGN="bottom"></TD><TDWIDTH="10%"ALIGN="right"VALIGN="bottom"><AHREF="synth-porting.html"ACCESSKEY="N">Next</A></TD></TR></TABLE><HRALIGN="LEFT"WIDTH="100%"></DIV><H1><ANAME="SYNTH-NEW-HOST">Writing New Devices - host</H1><DIVCLASS="REFNAMEDIV"><ANAME="AEN18382"></A><H2>Name</H2>Writing New Devices&nbsp;--&nbsp;extending the synthetic target, host-side</DIV><DIVCLASS="REFSECT1"><ANAME="SYNTH-NEW-HOST-DESCRIPTION"></A><H2>Description</H2><P>On the host-side adding a new device means writing a Tcl/Tk scriptthat will handle instantiation and subsequent requests from thetarget-side. These scripts all run in the same full interpreter,extended with various commands provided by the main I/O auxiliarycode, and running in an overall GUI framework. Some knowledge ofprogramming with Tcl/Tk is required to implement host-side devicesupport.    </P><P>Some devices can be implemented entirely using a Tcl/Tk script. Forexample, if the final system will have some buttons then those can beemulated in the synthetic target using a few Tk widgets. A simpleemulation could just have the right number of buttons in a row. A moreadvanced emulation could organize the buttons with the right layout,perhaps even matching the colour scheme, the shapes, and the relativesizes. With other devices it may be necessary for the Tcl script tointeract with an external program, because the required functionalitycannot easily be accessed from a Tcl script. For example interactingwith a raw ethernet device involves some <TTCLASS="FUNCTION">ioctl</TT>calls, which is easier to do in a C program. Therefore the<TTCLASS="FILENAME">ethernet.tcl</TT> script which implements thehost-side ethernet support spawns a separate program<TTCLASS="FILENAME">rawether</TT>, written in C, that performs thelow-level I/O. Raw ethernet access usually also requires rootprivileges, and running a small program <TTCLASS="FILENAME">rawether</TT>with such privileges is somewhat less of a security risk than thewhole eCos application, the I/O auxiliary, and various dynamicallyloaded Tcl scripts.    </P><P>Because all scripts run in a single interpreter, some care hasto be taken to avoid accidental sharing of global variables. The bestway to avoid problems is to have each script create its own Tclnamespace, so for example the <TTCLASS="FILENAME">ethernet.tcl</TT> scriptcreates a namespace <TTCLASS="VARNAME">ethernet::</TT> and all variablesand procedures reside in this namespace. Similarly the I/O auxiliaryitself makes use of a <TTCLASS="VARNAME">synth::</TT> namespace.    </P></DIV><DIVCLASS="REFSECT1"><ANAME="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. Thethird argument to <TTCLASS="FUNCTION">synth_auxiliary_instantiate</TT>specifies the type of device, for example <TTCLASS="LITERAL">ethernet</TT>,and the I/O auxiliary will append a <TTCLASS="FILENAME">.tcl</TT> suffixand look for a script <TTCLASS="FILENAME">ethernet.tcl</TT>.    </P><P>If the device being instantiated is application-specific rather thanpart of an eCos package, the I/O auxiliary will look first in thecurrent directory, then in <TTCLASS="FILENAME">~/.ecos/synth</TT>. If it is part of an eCospackage then the auxiliary will expect to find the Tcl script and anysupport files below <TTCLASS="FILENAME">libexec/ecos</TT> in the install tree - notethat the same install tree must be used for the I/O auxiliary itselfand for any device driver support. The directory hierarchy below<TTCLASS="FILENAME">libexec/ecos</TT> matches thestructure of the eCos repository, allowing multiple versions of apackage to be installed to allow for incompatible protocol changes.    </P><P>The preferred way to build host-side software is to use<BCLASS="COMMAND">autoconf</B> and <BCLASS="COMMAND">automake</B>. Usuallythis involves little more than copying the<TTCLASS="FILENAME">acinclude.m4</TT>, <TTCLASS="FILENAME">configure.in</TT>and <TTCLASS="FILENAME">Makefile.am</TT> files from an existing package,for example the synthetic target ethernet driver, and then makingminor edits. In <TTCLASS="FILENAME">acinclude.m4</TT> it may be necessaryto adjust the path to the root of the repository.<TTCLASS="FILENAME">configure.in</TT> may require a similar change, andthe <TTCLASS="FUNCTION">AC_INIT</TT> macro invocation will have to bechanged to match one of the files in the new package. A critical macroin this file is <TTCLASS="FILENAME">ECOS_PACKAGE_DIRS</TT> which will setup the correct install directory. <TTCLASS="FILENAME">Makefile.am</TT> mayrequire some more changes, for example to specify the data files thatshould be installed (including the Tcl script). These files shouldthen be processed using <BCLASS="COMMAND">aclocal</B>,<BCLASS="COMMAND">autoconf</B> and <BCLASS="COMMAND">automake</B> in thatorder. Actually building the software then just involves<BCLASS="COMMAND">configure</B>, <BCLASS="COMMAND">make</B> and<BCLASS="COMMAND">make install</B>, as per the instructions in thetoplevel <TTCLASS="FILENAME">README.host</TT> file.    </P><P>To assist developers, if the environment variable<TTCLASS="ENVAR">ECOSYNTH_DEVEL</TT> is set then a slightly differentalgorithm is used for locating device Tcl scripts. Instead of lookingonly in the install tree the I/O auxiliary will also look in thesource tree, and if the script there is more recent than the installedversion it will be used in preference. This allows developers tomodify the master copy without having to run <BCLASS="COMMAND">makeinstall</B> all the time.    </P><P>If a script needs to know where it has been installed it can examinethe Tcl variable <TTCLASS="VARNAME">synth::device_install_dir</TT> . Thisvariable gets updated whenever a  script is loaded, so if thevalue may be needed later it should be saved away in a device-specificvariable.     </P></DIV><DIVCLASS="REFSECT1"><ANAME="SYNTH-NEW-HOST-INSTANTIATION"></A><H2>Instantiation</H2><P>The I/O auxiliary will <BCLASS="COMMAND">source</B> the device-specificTcl script when the eCos application first attempts to instantiate adevice of that type. The script should return a procedure that will beinvoked to instantiate a device.    </P><TABLEBORDER="5"BGCOLOR="#E0E0F0"WIDTH="70%"><TR><TD><PRECLASS="PROGRAMLISTING">namespace eval ethernet {    &#8230;    proc instantiate { id instance data } {        &#8230;        return ethernet::handle_request    }}return ethernet::instantiate</PRE></TD></TR></TABLE><P>The <TTCLASS="VARNAME">id</TT> argument is a unique identifier for thisdevice instance. It will also be supplied on subsequent calls to therequest handler, and will match the return value of<TTCLASS="FUNCTION">synth_auxiliary_instantiate</TT> on the target side. Acommon use for this value is as an array index to support multipleinstances of this types of device. The <TTCLASS="VARNAME">instance</TT> and<TTCLASS="VARNAME">data</TT> arguments match the corresponding arguments to<TTCLASS="FUNCTION">synth_auxiliary_instantiate</TT> on the target side, soa typical value for <TTCLASS="VARNAME">instance</TT> would be<TTCLASS="LITERAL">eth0</TT>, and <TTCLASS="VARNAME">data</TT> is used to passarbitrary initialization parameters from target to host.    </P><P>The actual work done by the instantiation procedure is obviouslydevice-specific. It may involve allocating an <AHREF="synth-new-host.html#SYNTH-NEW-HOST-INTERRUPTS">interrupt vector</A>, adding adevice-specific subwindow to the display, opening a real Linux device,establishing a socket connection to some server, spawning a separateprocess to handle the actual I/O, or a combination of some or all ofthe above.    </P><P>If the device is successfully instantiated then the return valueshould be a handler for subsequent I/O requests. Otherwise the returnvalue should be an empty string, and on the target-side the<TTCLASS="FUNCTION">synth_auxiliary_instantiate</TT> call will return<TTCLASS="LITERAL">-1</TT>. The script is responsible for providing<AHREF="synth-new-host.html#SYNTH-NEW-HOST-OUTPUT">diagnostics</A> explainingwhy the device could not be instantiated.    </P></DIV><DIVCLASS="REFSECT1"><ANAME="SYNTH-NEW-HOST-REQUESTS"></A><H2>Handling Requests</H2><P>When the target-side calls<TTCLASS="FUNCTION">synth_auxiliary_xchgmsg</TT>, the I/O auxiliary willend up calling the request handler for the appropriate device instancereturned during instantiation:    </P><TABLEBORDER="5"BGCOLOR="#E0E0F0"WIDTH="70%"><TR><TD><PRECLASS="PROGRAMLISTING">namespace eval ethernet {    &#8230;    proc handle_request { id request arg1 arg2 txdata txlen max_rxlen } {        &#8230;        if { &lt;some condition&gt; } {            synth::send_reply &lt;error code&gt; 0 ""            return        }        &#8230;        synth::send_reply &lt;reply code&gt; $packet_len $packet    }    &#8230;}</PRE></TD></TR></TABLE><P>The <TTCLASS="VARNAME">id</TT> argument is the same device id that waspassed to the instantiate function, and is typically used as an arrayindex to access per-device data. The <TTCLASS="VARNAME">request</TT>,<TTCLASS="VARNAME">arg1</TT>, <TTCLASS="VARNAME">arg2</TT>, and<TTCLASS="VARNAME">max_rxlen</TT> are the same values that were passed to<TTCLASS="FUNCTION">synth_auxiliary_xchgmsg</TT> on the target-side,although since this is a Tcl script obviously the numbers have beenconverted to strings. The <TTCLASS="VARNAME">txdata</TT> buffer is raw dataas transmitted by the target, or an empty string if the I/O operationdoes not involve any additional data. The Tcl procedures<BCLASS="COMMAND">binary scan</B>, <BCLASS="COMMAND">string index</B> and<BCLASS="COMMAND">string range</B> may be found especially useful whenmanipulating this buffer. <TTCLASS="VARNAME">txlen</TT> is provided forconvenience, although <BCLASS="COMMAND">string length $txdata</B> wouldgive the same information.    </P><P>The code for actually processing the request is of course devicespecific. If the target does not expect a reply then the requesthandler should just return when finished. If a reply is expected thenthere should be a call to <BCLASS="COMMAND">synth::send_reply</B>. Thefirst argument is the reply code, and will be turned into a 32-bitinteger on the target side. The second argument specifies the lengthof the reply data, and the third argument is the reply data itself.For some devices the Tcl procedure <BCLASS="COMMAND">binary format</B>may prove useful. If the reply involves just a code and no additionaldata, the second and third arguments should be <TTCLASS="LITERAL">0</TT>and an empty string respectively.    </P><P>Attempts to send a reply when none is expected, fail to send a replywhen one is expected, or send a reply that is larger than thetarget-side expects, will all be detected by the I/O auxiliary andresult in run-time error messages.    </P><P>It is not possible for the host-side code to send unsolicited messagesto the target. If host-side code needs attention from the target, forexample because some I/O operation has completed, then an interruptshould be raised.    </P></DIV><DIVCLASS="REFSECT1"><ANAME="SYNTH-NEW-HOST-INTERRUPTS"></A><H2>Interrupts</H2><P>The I/O auxiliary provides a number of procedures for interrupthandling.     </P><TABLEBORDER="5"BGCOLOR="#E0E0F0"WIDTH="70%"><TR><TD><PRECLASS="PROGRAMLISTING">synth::interrupt_allocate &lt;name&gt;synth::interrupt_get_maxsynth::interrupt_get_devicename &lt;vector&gt;synth::interrupt_raise &lt;vector&gt;</PRE></TD></TR></TABLE><P><BCLASS="COMMAND">synth::interrupt_allocate</B> is normally called duringdevice instantiation, and returns the next free interrupt vector. Thiscan be passed on to the target-side device driver in response to asuitable request, and it can then install an interrupt handler on thatvector. Interrupt vector <TTCLASS="LITERAL">0</TT> is used within thetarget-side code for the real-time clock, so the allocated vectorswill start at <TTCLASS="LITERAL">1</TT>. The argument identifies thedevice, for example <TT

⌨️ 快捷键说明

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