📄 porting.sgml
字号:
vectors. We do believe that the pros generally outweigh the cons by a
great margin, but there may be situations where the opposite is
true.
</para>
<para>
The use of the services are implemented by way of macros, meaning
that it is possible to circumvent the virtual vectors if
desired. There is (as yet) no implementation for doing this, but it is
possible.
</para>
<para>Here is a list of pros and cons:</para>
<variablelist>
<varlistentry><term>Pro: Allows debugging without including stubs</term>
<listitem><para>This is the primary reason for using virtual vectors. It
allows the ROM monitor to provide most of the debugging
infrastructure, requiring only the application to provide
hooks for asynchronous debugger interrupts and for accessing
kernel thread information.</para></listitem></varlistentry>
<varlistentry><term>Pro: Allows debugging to be initiated from arbitrary
channel</term>
<listitem><para> While this is only true where the application does not
actively override the debugging channel setup, it is a very
nice feature during development. In particular it makes it
possible to launch (and/or debug) applications via Ethernet
even though the application configuration does not contain
networking support.</para></listitem></varlistentry>
<varlistentry><term>Pro: Image smaller due to services being provided by ROM
monitor</term>
<listitem><para>All service functions except HAL IO are included in the
default configuration. But if these are all disabled the
image for download will be a little smaller. Probably
doesn't matter much for regular development, but it is a
worthwhile saving for the 20000 daily tests run in the Red
Hat eCos test farm.</para></listitem></varlistentry>
<varlistentry><term>Con: The vectors add a layer of indirection, increasing application
size and reducing performance.</term>
<listitem><para>The size increase is a fraction of what is required to
implement the services. So for RAM configurations there is
a net saving, while for ROM configurations there is a small
overhead.</para>
<para>The performance loss means little for most of the
services (of which the most commonly used is diagnostic IO
which happens via polled routines
anyway).</para></listitem>
</varlistentry>
<varlistentry><term>Con: The layer of indirection is another point of
failure.</term>
<listitem><para> The concern primarily being that of vectors being
trashed by rogue writes from bad code, causing a complete
loss of the service and possibly a crash. But this does
not differ much from a rogue write to anywhere else in the
address space which could cause the same amount of
mayhem. But it is arguably an additional point of failure
for the service in question.</para></listitem></varlistentry>
<varlistentry><term>Con: All the indirection stuff makes it harder to bring a HAL
up</term>
<listitem><para> This is a valid concern. However, seeing as most of the
code in question is shared between all HALs and should
remain unchanged over time, the risk of it being broken
when a new HAL is being worked on should be
minimal.</para>
<para> When starting a new port, be sure to implement the HAL
IO drivers according to the scheme used in other drivers,
and there should be no problem.</para>
<para> However, it is still possible to circumvent the vectors
if they are suspect of causing problems: simply change the
HAL_DIAG_INIT and HAL_DIAG_WRITE_CHAR macros to use the raw
IO functions.</para></listitem></varlistentry>
</variablelist>
</section>
<!-- }}} -->
<!-- {{{ Available Services -->
<section>
<title>Available services</title>
<para>
The <filename>hal_if.h</filename> file in the common HAL defines the
complete list of available services. A few worth mentioning in
particular:</para>
<itemizedlist>
<listitem> <para>COMMS services. All HAL IO happens via the communication
channels.</para>
</listitem>
<listitem> <para>uS delay. Fine granularity (busy wait) delay function.</para>
</listitem>
<listitem> <para>Reset. Allows a software initiated reset of the board.</para>
</listitem>
</itemizedlist>
</section>
<!-- }}} -->
</section>
<!-- }}} -->
<!-- {{{ The COMMS Channels -->
<section>
<title>The COMMS channels</title>
<para>As all HAL IO happens via the COMMS channels these deserve to be
described in a little more detail. In particular the controls of where
diagnostic output is routed and how it is treated to allow for display
in debuggers.</para>
<!-- {{{ Console and Debuggers Channels -->
<section>
<title>Console and Debugging Channels</title>
<para>There are two COMMS channels - one for console IO and one for
debugging IO. They can be individually configured to use any of the
actual IO ports (serial or Ethernet) available on the platform.</para>
<para>The console channel is used for any IO initiated by calling the
<function>diag_*()</function> functions. Note that these should only be used during
development for debugging, assertion and possibly tracing
messages. All proper IO should happen via proper devices. This means
it should be possible to remove the HAL device drivers from production
configurations where assertions are disabled.</para>
<para>The debugging channel is used for communication between the
debugger and the stub which remotely controls the target for the
debugger (the stub runs on the target). This usually happens via some
protocol, encoding commands and replies in some suitable form.</para>
<para>Having two separate channels allows, e.g., for simple logging
without conflicts with the debugger or interactive IO which some
debuggers do not allow.</para>
</section>
<!-- }}} -->
<!-- {{{ Mangling -->
<section>
<title>Mangling</title>
<para>As debuggers usually have a protocol using specialized commands
when communicating with the stub on the target, sending out text as
raw ASCII from the target on the same channel will either result in
protocol errors (with loss of control over the target) or the text may
just be ignored as junk by the debugger.</para>
<para>To get around this, some debuggers have a special command for text
output. Mangling is the process of encoding diagnostic ASCII text
output in the form specified by the debugger protocol.</para>
<para>When it is necessary to use mangling, i.e. when writing console
output to the same port used for debugging, a mangler function is
installed on the console channel which mangles the text and passes it
on to the debugger channel.</para>
</section>
<!-- }}} -->
<!-- {{{ Controlling the Console Channel -->
<section>
<title>Controlling the Console Channel</title>
<para>Console output configuration is either inherited from the ROM
monitor launching the application, or it is specified by the
application. This is controlled by the new option
<literal>CYGSEM_HAL_VIRTUAL_VECTOR_INHERIT_CONSOLE</literal> which
defaults to enabled when the configuration is set to use a ROM
monitor.</para>
<para>If the user wants to specify the console configuration in the
application image, there are two new options that are used for
this.</para>
<para>Defaults are to direct diagnostic output via a mangler to the
debugging channel (<literal>CYGDBG_HAL_DIAG_TO_DEBUG_CHAN</literal>
enabled). The mangler type is controlled by the option
<literal>CYGSEM_HAL_DIAG_MANGLER</literal>. At present there are only
two mangler types:</para>
<variablelist>
<varlistentry><term><acronym>GDB</acronym></term>
<listitem><para> This causes a mangler appropriate for debugging with GDB to be
installed on the console channel.</para></listitem></varlistentry>
<varlistentry><term>None</term>
<listitem><para> This causes a NULL mangler to be installed on the console
channel. It will redirect the IO to/from the debug channel
without mangling of the data. This option differs from setting
the console channel to the same IO port as the debugging
channel in that it will keep redirecting data to the debugging
channel even if that is changed to some other port.</para></listitem></varlistentry>
</variablelist>
<para>Finally, by disabling <literal>CYGDBG_HAL_DIAG_TO_DEBUG_CHAN</literal>, the diagnostic
output is directed in raw form to the specified console IO port.</para>
<para>In summary this results in the following common configuration
scenarios for RAM startup configurations:</para>
<itemizedlist>
<listitem><para> For regular debugging with diagnostic output appearing in the
debugger, mangling is enabled and stubs disabled.</para>
<para>Diagnostic output appears via the debugging channel as
initiated by the ROM monitor, allowing for correct behavior
whether the application was launched via serial or Ethernet, from
the RedBoot command line or from a debugger.</para>
</listitem>
<listitem><para> For debugging with raw diagnostic output, mangling is
disabled.</para>
<para> Debugging session continues as initiated by the ROM monitor,
whether the application was launched via serial or
Ethernet. Diagnostic output is directed at the IO port configured
in the application configuration.</para>
<note>
<title>Note:</title>
<para> There is one caveat to be aware of. If the
application uses proper devices (be it serial or Ethernet) on
the same ports as those used by the ROM monitor, the
connections initiated by the ROM monitor will be
terminated.</para>
</note>
</listitem>
</itemizedlist>
<para>And for ROM startup configurations:</para>
<itemizedlist>
<listitem><para> Production configuration with raw output and no debugging
features (configured for RAM or ROM), mangling is disabled, no
stubs are included.</para>
<para>Diagnostic output appears (in unmangled form) on the specified
IO port.</para>
</listitem>
<listitem><para> RedBoot configuration, includes debugging features and necessary
mangling.</para>
<para>Diagnostic and debugging output port is auto-selected by the
first connection to any of the supported IO ports. Can change
from interactive mode to debugging mode when a debugger is
detected - when this happens a mangler will be installed as
required.</para>
</listitem>
<listitem><para> GDB stubs configuration (obsoleted by RedBoot configuration),
includes debugging features, mangling is hardwired to GDB
protocol.</para>
<para>Diagnostic and debugging output is hardwired to configured IO
ports, mangling is hardwired.</para>
</listitem>
</itemizedlist>
</section>
<!-- }}} -->
<!-- {{{ Footnote: Design Reasoning -->
<section>
<title>Footnote: Design Reasoning for Control of Console Channel</title>
<para>The current code for controlling the console channel is a
replacement for an older implementation which had some shortcomings
which addressed by the new implementation.</para>
<para>This is what the old implementation did: on initialization it would
check if the CDL configured console channel differed from the active
debug channel - and if so, set the console channel, thereby disabling
mangling.</para>
<para>The idea was that whatever channel was configured to be used for
console (i.e., diagnostic output) in the application was what should
be used. Also, it meant that if debug and console channels were
normally the same, a changed console channel would imply a request for
unmangled output.</para>
<para>But this prevented at least two things:</para>
<itemizedlist>
<listitem><para> It was impossible to inherit the existing connection by which
the application was launched (either by RedBoot commands via
telnet, or by via a debugger).</para>
<para>This was mostly a problem on targets supporting Ethernet
access since the diagnostic output would not be returned via the
Ethernet connection, but on the configured serial port.</para>
<para>The problem also occurred on any targets with multiple serial
ports where the ROM monitor was configured to use a different
port than the CDL defaults.</para>
</listitem>
<listitem><para> Proper control of when to mangle or just write out raw ASCII
text.</para>
<para>Sometimes it's desirable to disable mangling, even if the
channel specified is the same as that used for debugging. This
usually happens if GDB is used to download the application, but
direct interaction with the application on the same channel is
desired (GDB protocol only allows output from the target, no
input).</para>
</listitem>
</itemizedlist>
</section>
<!-- }}} -->
</section>
<!-- }}} -->
<!-- {{{ The Calling Interface API -->
<section>
<title>The calling Interface API</title>
<para>The calling interface API is defined by hal_if.h and hal_if.c in
hal/common.</para>
<para>The API provides a set of services. Different platforms, or
different versions of the ROM monitor for a single platform, may
implement fewer or extra service. The table has room for growth, and
any entries which are not supported map to a NOP-service (when called
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -