- add ability for openocd to communicate to gdb using pipes (stdin/stdout).
- this is enabled by new command line option option --pipe. git-svn-id: svn://svn.berlios.de/openocd/trunk@1242 b42882b7-edfa-0310-969c-e2dbd0fdcd60__archive__
parent
459d03e3bb
commit
47d0449347
|
@ -15,7 +15,7 @@
|
||||||
|
|
||||||
@itemize @bullet
|
@itemize @bullet
|
||||||
@item Copyright @copyright{} 2008 The OpenOCD Project
|
@item Copyright @copyright{} 2008 The OpenOCD Project
|
||||||
@item Copyright @copyright{} 2007-2008 Spen @email{spen@@spen-soft.co.uk}
|
@item Copyright @copyright{} 2007-2008 Spencer Oliver @email{spen@@spen-soft.co.uk}
|
||||||
@item Copyright @copyright{} 2008 Oyvind Harboe @email{oyvind.harboe@@zylin.com}
|
@item Copyright @copyright{} 2008 Oyvind Harboe @email{oyvind.harboe@@zylin.com}
|
||||||
@item Copyright @copyright{} 2008 Duane Ellis @email{openocd@@duaneellis.com}
|
@item Copyright @copyright{} 2008 Duane Ellis @email{openocd@@duaneellis.com}
|
||||||
@end itemize
|
@end itemize
|
||||||
|
@ -411,9 +411,10 @@ bash$ openocd --help
|
||||||
--debug | -d set debug level <0-3>
|
--debug | -d set debug level <0-3>
|
||||||
--log_output | -l redirect log output to file <name>
|
--log_output | -l redirect log output to file <name>
|
||||||
--command | -c run <command>
|
--command | -c run <command>
|
||||||
|
--pipe | -p use pipes when talking to gdb
|
||||||
@end verbatim
|
@end verbatim
|
||||||
|
|
||||||
By default openocd reads the file configuration file ``openocd.cfg''
|
By default OpenOCD reads the file configuration file ``openocd.cfg''
|
||||||
in the current directory. To specify a different (or multiple)
|
in the current directory. To specify a different (or multiple)
|
||||||
configuration file, you can use the ``-f'' option. For example:
|
configuration file, you can use the ``-f'' option. For example:
|
||||||
|
|
||||||
|
@ -445,6 +446,9 @@ Search paths for config/script files can be added to OpenOCD by using
|
||||||
the @option{-s <search>} switch. The current directory and the OpenOCD
|
the @option{-s <search>} switch. The current directory and the OpenOCD
|
||||||
target library is in the search path by default.
|
target library is in the search path by default.
|
||||||
|
|
||||||
|
For details on the @option{-p} option. @xref{Connecting to GDB}.
|
||||||
|
Option @option{-p} is not currently supported under native win32.
|
||||||
|
|
||||||
Note! OpenOCD will launch the GDB & telnet server even if it can not
|
Note! OpenOCD will launch the GDB & telnet server even if it can not
|
||||||
establish a connection with the target. In general, it is possible for
|
establish a connection with the target. In general, it is possible for
|
||||||
the JTAG controller to be unresponsive until the target is set up
|
the JTAG controller to be unresponsive until the target is set up
|
||||||
|
@ -455,7 +459,7 @@ correctly via e.g. GDB monitor commands in a GDB init script.
|
||||||
@cindex configuration
|
@cindex configuration
|
||||||
|
|
||||||
@section Outline
|
@section Outline
|
||||||
There are 4 basic ways of ``configurating'' openocd to run, they are:
|
There are 4 basic ways of ``configurating'' OpenOCD to run, they are:
|
||||||
|
|
||||||
@enumerate
|
@enumerate
|
||||||
@item A small openocd.cfg file which ``sources'' other configuration files
|
@item A small openocd.cfg file which ``sources'' other configuration files
|
||||||
|
@ -671,7 +675,7 @@ tap identifier dotted name.
|
||||||
every chip. If the @t{-expected-id} is nonzero, OpenOCD attempts
|
every chip. If the @t{-expected-id} is nonzero, OpenOCD attempts
|
||||||
to verify the tap id number verses configuration file and may issue an
|
to verify the tap id number verses configuration file and may issue an
|
||||||
error or warning like this. The hope is this will help pin point
|
error or warning like this. The hope is this will help pin point
|
||||||
problem openocd configurations.
|
problem OpenOCD configurations.
|
||||||
|
|
||||||
@example
|
@example
|
||||||
Info: JTAG tap: sam7x256.cpu tap/device found: 0x3f0f0f0f (Manufacturer: 0x787, Part: 0xf0f0, Version: 0x3)
|
Info: JTAG tap: sam7x256.cpu tap/device found: 0x3f0f0f0f (Manufacturer: 0x787, Part: 0xf0f0, Version: 0x3)
|
||||||
|
@ -904,7 +908,7 @@ command interpretor today (28/nov/2008) is a mixture of (newer)
|
||||||
JIM-Tcl commands, and (older) the orginal command interpretor.
|
JIM-Tcl commands, and (older) the orginal command interpretor.
|
||||||
|
|
||||||
@item @b{Commands}
|
@item @b{Commands}
|
||||||
@* At the openocd telnet command line (or via the GDB mon command) one
|
@* At the OpenOCD telnet command line (or via the GDB mon command) one
|
||||||
can type a Tcl for() loop, set variables, etc.
|
can type a Tcl for() loop, set variables, etc.
|
||||||
|
|
||||||
@item @b{Historical Note}
|
@item @b{Historical Note}
|
||||||
|
@ -1145,7 +1149,7 @@ if compiled with FTD2XX support.
|
||||||
@b{TODO:} Confirm the following: On windows the name needs to end with
|
@b{TODO:} Confirm the following: On windows the name needs to end with
|
||||||
a ``space A''? Or not? It has to do with the FTD2xx driver. When must
|
a ``space A''? Or not? It has to do with the FTD2xx driver. When must
|
||||||
this be added and when must it not be added? Why can't the code in the
|
this be added and when must it not be added? Why can't the code in the
|
||||||
interface or in openocd automatically add this if needed? -- Duane.
|
interface or in OpenOCD automatically add this if needed? -- Duane.
|
||||||
|
|
||||||
@item @b{ft2232_serial} <@var{serial-number}>
|
@item @b{ft2232_serial} <@var{serial-number}>
|
||||||
@cindex ft2232_serial
|
@cindex ft2232_serial
|
||||||
|
@ -1527,7 +1531,7 @@ then ``bypass'' the tap, the tap is completely removed from the
|
||||||
circuit and skipped.
|
circuit and skipped.
|
||||||
|
|
||||||
|
|
||||||
From OpenOCDs view point, a JTAG TAP is in one of 3 states:
|
From OpenOCD's view point, a JTAG TAP is in one of 3 states:
|
||||||
|
|
||||||
@itemize @bullet
|
@itemize @bullet
|
||||||
@item @b{Enabled - Not In ByPass} and has a variable bit length
|
@item @b{Enabled - Not In ByPass} and has a variable bit length
|
||||||
|
@ -1640,7 +1644,7 @@ configure it like this:
|
||||||
puts [format "The button is %s" $x]
|
puts [format "The button is %s" $x]
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
In OpenOCDs terms, the ``target'' is an object just like a Tcl/Tk
|
In OpenOCD's terms, the ``target'' is an object just like a Tcl/Tk
|
||||||
button. Commands avaialble as a ``target object'' are:
|
button. Commands avaialble as a ``target object'' are:
|
||||||
|
|
||||||
@comment START targetobj commands.
|
@comment START targetobj commands.
|
||||||
|
@ -1841,7 +1845,7 @@ via the configure option or to query the target via cget.
|
||||||
@item @b{-work-area-size [ADDRESS]} specify/set the work area
|
@item @b{-work-area-size [ADDRESS]} specify/set the work area
|
||||||
@item @b{-work-area-backup [0|1]} does the work area get backed up
|
@item @b{-work-area-backup [0|1]} does the work area get backed up
|
||||||
@item @b{-endian [big|little]}
|
@item @b{-endian [big|little]}
|
||||||
@item @b{-variant [NAME]} some chips have varients openocd needs to know about
|
@item @b{-variant [NAME]} some chips have varients OpenOCD needs to know about
|
||||||
@item @b{-chain-position DOTTED.NAME} the tap name this target refers to.
|
@item @b{-chain-position DOTTED.NAME} the tap name this target refers to.
|
||||||
@end itemize
|
@end itemize
|
||||||
Example:
|
Example:
|
||||||
|
@ -1870,7 +1874,7 @@ cores.
|
||||||
@* None (this is also used as the ARM946)
|
@* None (this is also used as the ARM946)
|
||||||
@item @b{cortex_m3}
|
@item @b{cortex_m3}
|
||||||
@* use variant <@var{-variant lm3s}> when debugging luminary lm3s targets. This will cause
|
@* use variant <@var{-variant lm3s}> when debugging luminary lm3s targets. This will cause
|
||||||
openocd to use a software reset rather than asserting SRST to avoid a issue with clearing
|
OpenOCD to use a software reset rather than asserting SRST to avoid a issue with clearing
|
||||||
the debug registers. This is fixed in Fury Rev B, DustDevil Rev B, Tempest, these revisions will
|
the debug registers. This is fixed in Fury Rev B, DustDevil Rev B, Tempest, these revisions will
|
||||||
be detected and the normal reset behaviour used.
|
be detected and the normal reset behaviour used.
|
||||||
@item @b{xscale}
|
@item @b{xscale}
|
||||||
|
@ -1880,9 +1884,9 @@ be detected and the normal reset behaviour used.
|
||||||
@item @b{mips_m4k}
|
@item @b{mips_m4k}
|
||||||
@* Use variant @option{ejtag_srst} when debugging targets that do not
|
@* Use variant @option{ejtag_srst} when debugging targets that do not
|
||||||
provide a functional SRST line on the EJTAG connector. This causes
|
provide a functional SRST line on the EJTAG connector. This causes
|
||||||
openocd to instead use an EJTAG software reset command to reset the
|
OpenOCD to instead use an EJTAG software reset command to reset the
|
||||||
processor. You still need to enable @option{srst} on the reset
|
processor. You still need to enable @option{srst} on the reset
|
||||||
configuration command to enable openocd hardware reset functionality.
|
configuration command to enable OpenOCD hardware reset functionality.
|
||||||
@comment END varients
|
@comment END varients
|
||||||
@end itemize
|
@end itemize
|
||||||
@section working_area - Command Removed
|
@section working_area - Command Removed
|
||||||
|
@ -2004,7 +2008,7 @@ to a <@var{file}>.
|
||||||
@end itemize
|
@end itemize
|
||||||
|
|
||||||
@section flash bank command
|
@section flash bank command
|
||||||
The @b{flash bank} command is used to configure one or more flash chips (or banks in openocd terms)
|
The @b{flash bank} command is used to configure one or more flash chips (or banks in OpenOCD terms)
|
||||||
|
|
||||||
@example
|
@example
|
||||||
@b{flash bank} <@var{driver}> <@var{base}> <@var{size}> <@var{chip_width}>
|
@b{flash bank} <@var{driver}> <@var{base}> <@var{size}> <@var{chip_width}>
|
||||||
|
@ -2170,7 +2174,7 @@ erase the device.
|
||||||
@end itemize
|
@end itemize
|
||||||
|
|
||||||
Note: Before using the str9xpec driver here is some background info to help
|
Note: Before using the str9xpec driver here is some background info to help
|
||||||
you better understand how the drivers works. Openocd has two flash drivers for
|
you better understand how the drivers works. OpenOCD has two flash drivers for
|
||||||
the str9.
|
the str9.
|
||||||
@enumerate
|
@enumerate
|
||||||
@item
|
@item
|
||||||
|
@ -2793,41 +2797,52 @@ openocd -f interface/parport.cfg -f target/at91r40008.cfg -c init -c reset
|
||||||
OpenOCD complies with the remote gdbserver protocol, and as such can be used
|
OpenOCD complies with the remote gdbserver protocol, and as such can be used
|
||||||
to debug remote targets.
|
to debug remote targets.
|
||||||
|
|
||||||
@section Connecting to gdb
|
@section Connecting to GDB
|
||||||
@cindex Connecting to gdb
|
@cindex Connecting to GDB
|
||||||
|
@anchor{Connecting to GDB}
|
||||||
Use GDB 6.7 or newer with OpenOCD if you run into trouble. For
|
Use GDB 6.7 or newer with OpenOCD if you run into trouble. For
|
||||||
instance 6.3 has a known bug where it produces bogus memory access
|
instance 6.3 has a known bug where it produces bogus memory access
|
||||||
errors, which has since been fixed: look up 1836 in
|
errors, which has since been fixed: look up 1836 in
|
||||||
@url{http://sourceware.org/cgi-bin/gnatsweb.pl?database=gdb}
|
@url{http://sourceware.org/cgi-bin/gnatsweb.pl?database=gdb}
|
||||||
|
|
||||||
|
@*OpenOCD can communicate with GDB in two ways:
|
||||||
A connection is typically started as follows:
|
@enumerate
|
||||||
|
@item
|
||||||
|
A socket (tcp) connection is typically started as follows:
|
||||||
@example
|
@example
|
||||||
target remote localhost:3333
|
target remote localhost:3333
|
||||||
@end example
|
@end example
|
||||||
This would cause gdb to connect to the gdbserver on the local pc using port 3333.
|
This would cause GDB to connect to the gdbserver on the local pc using port 3333.
|
||||||
|
@item
|
||||||
|
A pipe connection is typically started as follows:
|
||||||
|
@example
|
||||||
|
target remote openocd --pipe
|
||||||
|
@end example
|
||||||
|
This would cause GDB to run OpenOCD and communicate using pipes (stdin/stdout).
|
||||||
|
Using this method has the advantage of GDB starting/stopping OpenOCD for debug session.
|
||||||
|
@end enumerate
|
||||||
|
|
||||||
To see a list of available OpenOCD commands type @option{monitor help} on the
|
@*To see a list of available OpenOCD commands type @option{monitor help} on the
|
||||||
gdb commandline.
|
GDB commandline.
|
||||||
|
|
||||||
OpenOCD supports the gdb @option{qSupported} packet, this enables information
|
OpenOCD supports the gdb @option{qSupported} packet, this enables information
|
||||||
to be sent by the gdb server (openocd) to gdb. Typical information includes
|
to be sent by the gdb server (OpenOCD) to GDB. Typical information includes
|
||||||
packet size and device memory map.
|
packet size and device memory map.
|
||||||
|
|
||||||
Previous versions of OpenOCD required the following gdb options to increase
|
Previous versions of OpenOCD required the following GDB options to increase
|
||||||
the packet size and speed up gdb communication.
|
the packet size and speed up GDB communication.
|
||||||
@example
|
@example
|
||||||
set remote memory-write-packet-size 1024
|
set remote memory-write-packet-size 1024
|
||||||
set remote memory-write-packet-size fixed
|
set remote memory-write-packet-size fixed
|
||||||
set remote memory-read-packet-size 1024
|
set remote memory-read-packet-size 1024
|
||||||
set remote memory-read-packet-size fixed
|
set remote memory-read-packet-size fixed
|
||||||
@end example
|
@end example
|
||||||
This is now handled in the @option{qSupported} PacketSize.
|
This is now handled in the @option{qSupported} PacketSize and should not be required.
|
||||||
|
|
||||||
@section Programming using gdb
|
@section Programming using GDB
|
||||||
@cindex Programming using gdb
|
@cindex Programming using GDB
|
||||||
|
|
||||||
By default the target memory map is sent to gdb, this can be disabled by
|
By default the target memory map is sent to GDB, this can be disabled by
|
||||||
the following OpenOCD config option:
|
the following OpenOCD config option:
|
||||||
@example
|
@example
|
||||||
gdb_memory_map disable
|
gdb_memory_map disable
|
||||||
|
@ -2836,34 +2851,34 @@ For this to function correctly a valid flash config must also be configured
|
||||||
in OpenOCD. For faster performance you should also configure a valid
|
in OpenOCD. For faster performance you should also configure a valid
|
||||||
working area.
|
working area.
|
||||||
|
|
||||||
Informing gdb of the memory map of the target will enable gdb to protect any
|
Informing GDB of the memory map of the target will enable GDB to protect any
|
||||||
flash area of the target and use hardware breakpoints by default. This means
|
flash area of the target and use hardware breakpoints by default. This means
|
||||||
that the OpenOCD option @option{gdb_breakpoint_override} is not required when
|
that the OpenOCD option @option{gdb_breakpoint_override} is not required when
|
||||||
using a memory map. @xref{gdb_breakpoint_override}.
|
using a memory map. @xref{gdb_breakpoint_override}.
|
||||||
|
|
||||||
To view the configured memory map in gdb, use the gdb command @option{info mem}
|
To view the configured memory map in GDB, use the gdb command @option{info mem}
|
||||||
All other unasigned addresses within gdb are treated as RAM.
|
All other unasigned addresses within GDB are treated as RAM.
|
||||||
|
|
||||||
GDB 6.8 and higher set any memory area not in the memory map as inaccessible,
|
GDB 6.8 and higher set any memory area not in the memory map as inaccessible,
|
||||||
this can be changed to the old behaviour by using the following gdb command.
|
this can be changed to the old behaviour by using the following GDB command.
|
||||||
@example
|
@example
|
||||||
set mem inaccessible-by-default off
|
set mem inaccessible-by-default off
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
If @option{gdb_flash_program enable} is also used, gdb will be able to
|
If @option{gdb_flash_program enable} is also used, GDB will be able to
|
||||||
program any flash memory using the vFlash interface.
|
program any flash memory using the vFlash interface.
|
||||||
|
|
||||||
gdb will look at the target memory map when a load command is given, if any
|
GDB will look at the target memory map when a load command is given, if any
|
||||||
areas to be programmed lie within the target flash area the vFlash packets
|
areas to be programmed lie within the target flash area the vFlash packets
|
||||||
will be used.
|
will be used.
|
||||||
|
|
||||||
If the target needs configuring before gdb programming, an event
|
If the target needs configuring before GDB programming, an event
|
||||||
script can be executed.
|
script can be executed.
|
||||||
@example
|
@example
|
||||||
$_TARGETNAME configure -event EVENTNAME BODY
|
$_TARGETNAME configure -event EVENTNAME BODY
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
To verify any flash programming the gdb command @option{compare-sections}
|
To verify any flash programming the GDB command @option{compare-sections}
|
||||||
can be used.
|
can be used.
|
||||||
|
|
||||||
@node TCL scripting API
|
@node TCL scripting API
|
||||||
|
@ -3598,7 +3613,7 @@ foreach who @{A B C D E@}
|
||||||
OpenOCD comes with a target configuration script library. These scripts can be
|
OpenOCD comes with a target configuration script library. These scripts can be
|
||||||
used as-is or serve as a starting point.
|
used as-is or serve as a starting point.
|
||||||
|
|
||||||
The target library is published together with the openocd executable and
|
The target library is published together with the OpenOCD executable and
|
||||||
the path to the target library is in the OpenOCD script search path.
|
the path to the target library is in the OpenOCD script search path.
|
||||||
Similarly there are example scripts for configuring the JTAG interface.
|
Similarly there are example scripts for configuring the JTAG interface.
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
INCLUDES = -I$(top_srcdir)/src $(all_includes) -I$(top_srcdir)/src/target
|
INCLUDES = -I$(top_srcdir)/src $(all_includes) -I$(top_srcdir)/src/target -I$(top_srcdir)/src/server
|
||||||
METASOURCES = AUTO
|
METASOURCES = AUTO
|
||||||
AM_CPPFLAGS = -DPKGDATADIR=\"$(pkgdatadir)\" -DPKGLIBDIR=\"$(pkglibdir)\" @CPPFLAGS@
|
AM_CPPFLAGS = -DPKGDATADIR=\"$(pkgdatadir)\" -DPKGLIBDIR=\"$(pkglibdir)\" @CPPFLAGS@
|
||||||
noinst_LIBRARIES = libhelper.a
|
noinst_LIBRARIES = libhelper.a
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
#include "time_support.h"
|
#include "time_support.h"
|
||||||
#include "command.h"
|
#include "command.h"
|
||||||
|
#include "server.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -108,9 +109,11 @@ static void log_puts(enum log_levels level, const char *file, int line, const ch
|
||||||
#endif
|
#endif
|
||||||
string);
|
string);
|
||||||
}
|
}
|
||||||
else
|
else if(server_use_pipes == 0)
|
||||||
{
|
{
|
||||||
if (strcmp(string, "\n")!=0)
|
/* if we are using gdb through pipes then we do not want any output
|
||||||
|
* to the pipe otherwise we get repeated strings */
|
||||||
|
if (strcmp(string, "\n") != 0)
|
||||||
{
|
{
|
||||||
/* print human readable output - but skip empty lines */
|
/* print human readable output - but skip empty lines */
|
||||||
fprintf(log_output, "%s%s",
|
fprintf(log_output, "%s%s",
|
||||||
|
@ -203,6 +206,18 @@ int handle_debug_level_command(struct command_context_s *cmd_ctx, char *cmd, cha
|
||||||
if (debug_level > 3)
|
if (debug_level > 3)
|
||||||
debug_level = 3;
|
debug_level = 3;
|
||||||
|
|
||||||
|
if (debug_level >= LOG_LVL_DEBUG && server_use_pipes == 1)
|
||||||
|
{
|
||||||
|
/* if we are enabling debug info then we need to write to a log file
|
||||||
|
* otherwise the pipe will get full and cause issues with gdb */
|
||||||
|
FILE* file = fopen("openocd.log", "w");
|
||||||
|
if (file)
|
||||||
|
{
|
||||||
|
log_output = file;
|
||||||
|
LOG_WARNING("enabling log output as we are using pipes");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,10 +24,13 @@
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "replacements.h"
|
||||||
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "command.h"
|
#include "command.h"
|
||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
#include "server.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -43,8 +46,9 @@ static struct option long_options[] =
|
||||||
{"debug", optional_argument, 0, 'd'},
|
{"debug", optional_argument, 0, 'd'},
|
||||||
{"file", required_argument, 0, 'f'},
|
{"file", required_argument, 0, 'f'},
|
||||||
{"search", required_argument, 0, 's'},
|
{"search", required_argument, 0, 's'},
|
||||||
{"log_output", required_argument, 0, 'l'},
|
{"log_output", required_argument, 0, 'l'},
|
||||||
{"command", required_argument, 0, 'c'},
|
{"command", required_argument, 0, 'c'},
|
||||||
|
{"pipe", no_argument, 0, 'p'},
|
||||||
{0, 0, 0, 0}
|
{0, 0, 0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -95,7 +99,7 @@ int parse_cmdline_args(struct command_context_s *cmd_ctx, int argc, char *argv[]
|
||||||
/* getopt_long stores the option index here. */
|
/* getopt_long stores the option index here. */
|
||||||
int option_index = 0;
|
int option_index = 0;
|
||||||
|
|
||||||
c = getopt_long(argc, argv, "hvd::l:f:s:c:", long_options, &option_index);
|
c = getopt_long(argc, argv, "hvd::l:f:s:c:p", long_options, &option_index);
|
||||||
|
|
||||||
/* Detect the end of the options. */
|
/* Detect the end of the options. */
|
||||||
if (c == -1)
|
if (c == -1)
|
||||||
|
@ -140,7 +144,20 @@ int parse_cmdline_args(struct command_context_s *cmd_ctx, int argc, char *argv[]
|
||||||
add_config_command(optarg);
|
add_config_command(optarg);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 'p': /* --pipe | -p */
|
||||||
|
#if BUILD_ECOSBOARD == 1
|
||||||
|
/* pipes unsupported on hosted platforms */
|
||||||
|
LOG_WARNING("pipes not supported on this platform");
|
||||||
|
#else
|
||||||
|
#ifdef IS_MINGW
|
||||||
|
/* pipes currently unsupported on win32 */
|
||||||
|
LOG_WARNING("pipes currently unsupported on win32");
|
||||||
|
exit(1);
|
||||||
|
#else
|
||||||
|
server_use_pipes = 1;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,6 +171,7 @@ int parse_cmdline_args(struct command_context_s *cmd_ctx, int argc, char *argv[]
|
||||||
LOG_OUTPUT("--debug | -d\tset debug level <0-3>\n");
|
LOG_OUTPUT("--debug | -d\tset debug level <0-3>\n");
|
||||||
LOG_OUTPUT("--log_output | -l\tredirect log output to file <name>\n");
|
LOG_OUTPUT("--log_output | -l\tredirect log output to file <name>\n");
|
||||||
LOG_OUTPUT("--command | -c\trun <command>\n");
|
LOG_OUTPUT("--command | -c\trun <command>\n");
|
||||||
|
LOG_OUTPUT("--pipe | -p\tuse pipes for gdb communication\n");
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -169,10 +169,18 @@ int gdb_get_char(connection_t *connection, int* next_char)
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
retval=check_pending(connection, 1, NULL);
|
if (connection->service->type == CONNECTION_PIPE)
|
||||||
if (retval!=ERROR_OK)
|
{
|
||||||
return retval;
|
gdb_con->buf_cnt = read(connection->fd, gdb_con->buffer, GDB_BUFFER_SIZE);
|
||||||
gdb_con->buf_cnt = read_socket(connection->fd, gdb_con->buffer, GDB_BUFFER_SIZE);
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
retval = check_pending(connection, 1, NULL);
|
||||||
|
if (retval != ERROR_OK)
|
||||||
|
return retval;
|
||||||
|
gdb_con->buf_cnt = read_socket(connection->fd, gdb_con->buffer, GDB_BUFFER_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
if (gdb_con->buf_cnt > 0)
|
if (gdb_con->buf_cnt > 0)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
|
@ -269,9 +277,20 @@ int gdb_write(connection_t *connection, void *data, int len)
|
||||||
if (gdb_con->closed)
|
if (gdb_con->closed)
|
||||||
return ERROR_SERVER_REMOTE_CLOSED;
|
return ERROR_SERVER_REMOTE_CLOSED;
|
||||||
|
|
||||||
if (write_socket(connection->fd, data, len) == len)
|
if (connection->service->type == CONNECTION_PIPE)
|
||||||
{
|
{
|
||||||
return ERROR_OK;
|
/* write to stdout */
|
||||||
|
if (write(STDOUT_FILENO, data, len) == len)
|
||||||
|
{
|
||||||
|
return ERROR_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (write_socket(connection->fd, data, len) == len)
|
||||||
|
{
|
||||||
|
return ERROR_OK;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
gdb_con->closed = 1;
|
gdb_con->closed = 1;
|
||||||
return ERROR_SERVER_REMOTE_CLOSED;
|
return ERROR_SERVER_REMOTE_CLOSED;
|
||||||
|
@ -2158,7 +2177,7 @@ int gdb_input(connection_t *connection)
|
||||||
if (retval == ERROR_SERVER_REMOTE_CLOSED)
|
if (retval == ERROR_SERVER_REMOTE_CLOSED)
|
||||||
return retval;
|
return retval;
|
||||||
|
|
||||||
/* logging does not propagate the error, yet can set th gdb_con->closed flag */
|
/* logging does not propagate the error, yet can set the gdb_con->closed flag */
|
||||||
if (gdb_con->closed)
|
if (gdb_con->closed)
|
||||||
return ERROR_SERVER_REMOTE_CLOSED;
|
return ERROR_SERVER_REMOTE_CLOSED;
|
||||||
|
|
||||||
|
@ -2177,32 +2196,35 @@ int gdb_init(void)
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gdb_port == 0)
|
if (gdb_port == 0 && server_use_pipes == 0)
|
||||||
{
|
{
|
||||||
LOG_WARNING("no gdb port specified, using default port 3333");
|
LOG_WARNING("no gdb port specified, using default port 3333");
|
||||||
gdb_port = 3333;
|
gdb_port = 3333;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (target)
|
if (server_use_pipes)
|
||||||
{
|
{
|
||||||
char service_name[8];
|
/* only a single gdb connection when using a pipe */
|
||||||
|
|
||||||
snprintf(service_name, 8, "gdb-%2.2i", target->target_number);
|
|
||||||
|
|
||||||
gdb_service = malloc(sizeof(gdb_service_t));
|
gdb_service = malloc(sizeof(gdb_service_t));
|
||||||
gdb_service->target = target;
|
gdb_service->target = target;
|
||||||
|
|
||||||
add_service("gdb", CONNECTION_GDB,
|
add_service("gdb", CONNECTION_PIPE, 0, 1, gdb_new_connection, gdb_input, gdb_connection_closed, gdb_service);
|
||||||
gdb_port + target->target_number,
|
|
||||||
1, gdb_new_connection, gdb_input,
|
|
||||||
gdb_connection_closed,
|
|
||||||
gdb_service);
|
|
||||||
|
|
||||||
LOG_DEBUG("gdb service for target %s at port %i",
|
LOG_DEBUG("gdb service for target %s using pipes", target->type->name);
|
||||||
target->type->name,
|
}
|
||||||
gdb_port + target->target_number);
|
else
|
||||||
|
{
|
||||||
|
while (target)
|
||||||
|
{
|
||||||
|
gdb_service = malloc(sizeof(gdb_service_t));
|
||||||
|
gdb_service->target = target;
|
||||||
|
|
||||||
target = target->next;
|
add_service("gdb", CONNECTION_TCP, gdb_port + target->target_number, 1, gdb_new_connection, gdb_input, gdb_connection_closed, gdb_service);
|
||||||
|
|
||||||
|
LOG_DEBUG("gdb service for target %s at port %i", target->type->name, gdb_port + target->target_number);
|
||||||
|
target = target->next;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
|
|
|
@ -53,6 +53,9 @@ service_t *services = NULL;
|
||||||
static int shutdown_openocd = 0;
|
static int shutdown_openocd = 0;
|
||||||
int handle_shutdown_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
|
int handle_shutdown_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
|
||||||
|
|
||||||
|
/* set when using pipes rather than tcp */
|
||||||
|
int server_use_pipes = 0;
|
||||||
|
|
||||||
int add_connection(service_t *service, command_context_t *cmd_ctx)
|
int add_connection(service_t *service, command_context_t *cmd_ctx)
|
||||||
{
|
{
|
||||||
unsigned int address_size;
|
unsigned int address_size;
|
||||||
|
@ -69,28 +72,44 @@ int add_connection(service_t *service, command_context_t *cmd_ctx)
|
||||||
c->priv = NULL;
|
c->priv = NULL;
|
||||||
c->next = NULL;
|
c->next = NULL;
|
||||||
|
|
||||||
address_size = sizeof(c->sin);
|
if (service->type == CONNECTION_TCP)
|
||||||
|
|
||||||
c->fd = accept(service->fd, (struct sockaddr *)&service->sin, &address_size);
|
|
||||||
|
|
||||||
/* This increases performance dramatically for e.g. GDB load which
|
|
||||||
* does not have a sliding window protocol. */
|
|
||||||
retval=setsockopt(c->fd, /* socket affected */
|
|
||||||
IPPROTO_TCP, /* set option at TCP level */
|
|
||||||
TCP_NODELAY, /* name of option */
|
|
||||||
(char *)&flag, /* the cast is historical cruft */
|
|
||||||
sizeof(int)); /* length of option value */
|
|
||||||
|
|
||||||
LOG_INFO("accepting '%s' connection from %i", service->name, c->sin.sin_port);
|
|
||||||
if ((retval = service->new_connection(c)) == ERROR_OK)
|
|
||||||
{
|
{
|
||||||
|
address_size = sizeof(c->sin);
|
||||||
|
|
||||||
|
c->fd = accept(service->fd, (struct sockaddr *)&service->sin, &address_size);
|
||||||
|
|
||||||
|
/* This increases performance dramatically for e.g. GDB load which
|
||||||
|
* does not have a sliding window protocol. */
|
||||||
|
retval=setsockopt(c->fd, /* socket affected */
|
||||||
|
IPPROTO_TCP, /* set option at TCP level */
|
||||||
|
TCP_NODELAY, /* name of option */
|
||||||
|
(char *)&flag, /* the cast is historical cruft */
|
||||||
|
sizeof(int)); /* length of option value */
|
||||||
|
|
||||||
|
LOG_INFO("accepting '%s' connection from %i", service->name, c->sin.sin_port);
|
||||||
|
if ((retval = service->new_connection(c)) != ERROR_OK)
|
||||||
|
{
|
||||||
|
close_socket(c->fd);
|
||||||
|
LOG_ERROR("attempted '%s' connection rejected", service->name);
|
||||||
|
free(c);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else if (service->type == CONNECTION_PIPE)
|
||||||
{
|
{
|
||||||
close_socket(c->fd);
|
#ifndef _WIN32
|
||||||
LOG_ERROR("attempted '%s' connection rejected", service->name);
|
c->fd = service->fd;
|
||||||
free(c);
|
|
||||||
return retval;
|
/* do not check for new connections again on stdin */
|
||||||
|
service->fd = -1;
|
||||||
|
#endif
|
||||||
|
LOG_INFO("accepting '%s' connection from pipe", service->name);
|
||||||
|
if ((retval = service->new_connection(c)) != ERROR_OK)
|
||||||
|
{
|
||||||
|
LOG_ERROR("attempted '%s' connection rejected", service->name);
|
||||||
|
free(c);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* add to the end of linked list */
|
/* add to the end of linked list */
|
||||||
|
@ -113,7 +132,8 @@ int remove_connection(service_t *service, connection_t *connection)
|
||||||
if (c->fd == connection->fd)
|
if (c->fd == connection->fd)
|
||||||
{
|
{
|
||||||
service->connection_closed(c);
|
service->connection_closed(c);
|
||||||
close_socket(c->fd);
|
if (service->type == CONNECTION_TCP)
|
||||||
|
close_socket(c->fd);
|
||||||
command_done(c->cmd_ctx);
|
command_done(c->cmd_ctx);
|
||||||
|
|
||||||
/* delete connection */
|
/* delete connection */
|
||||||
|
@ -150,44 +170,67 @@ int add_service(char *name, enum connection_type type, unsigned short port, int
|
||||||
c->priv = priv;
|
c->priv = priv;
|
||||||
c->next = NULL;
|
c->next = NULL;
|
||||||
|
|
||||||
if ((c->fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
|
if (type == CONNECTION_TCP)
|
||||||
{
|
{
|
||||||
LOG_ERROR("error creating socket: %s", strerror(errno));
|
if ((c->fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
|
||||||
exit(-1);
|
{
|
||||||
}
|
LOG_ERROR("error creating socket: %s", strerror(errno));
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
setsockopt(c->fd, SOL_SOCKET, SO_REUSEADDR, (void*)&so_reuseaddr_option, sizeof(int));
|
setsockopt(c->fd, SOL_SOCKET, SO_REUSEADDR, (void*)&so_reuseaddr_option, sizeof(int));
|
||||||
|
|
||||||
socket_nonblock(c->fd);
|
socket_nonblock(c->fd);
|
||||||
|
|
||||||
memset(&c->sin, 0, sizeof(c->sin));
|
memset(&c->sin, 0, sizeof(c->sin));
|
||||||
c->sin.sin_family = AF_INET;
|
c->sin.sin_family = AF_INET;
|
||||||
c->sin.sin_addr.s_addr = INADDR_ANY;
|
c->sin.sin_addr.s_addr = INADDR_ANY;
|
||||||
c->sin.sin_port = htons(port);
|
c->sin.sin_port = htons(port);
|
||||||
|
|
||||||
if (bind(c->fd, (struct sockaddr *)&c->sin, sizeof(c->sin)) == -1)
|
if (bind(c->fd, (struct sockaddr *)&c->sin, sizeof(c->sin)) == -1)
|
||||||
{
|
{
|
||||||
LOG_ERROR("couldn't bind to socket: %s", strerror(errno));
|
LOG_ERROR("couldn't bind to socket: %s", strerror(errno));
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
int segsize=65536;
|
int segsize=65536;
|
||||||
setsockopt(c->fd, IPPROTO_TCP, TCP_MAXSEG, &segsize, sizeof(int));
|
setsockopt(c->fd, IPPROTO_TCP, TCP_MAXSEG, &segsize, sizeof(int));
|
||||||
#endif
|
#endif
|
||||||
int window_size = 128 * 1024;
|
int window_size = 128 * 1024;
|
||||||
|
|
||||||
/* These setsockopt()s must happen before the listen() */
|
/* These setsockopt()s must happen before the listen() */
|
||||||
|
|
||||||
setsockopt(c->fd, SOL_SOCKET, SO_SNDBUF,
|
setsockopt(c->fd, SOL_SOCKET, SO_SNDBUF,
|
||||||
(char *)&window_size, sizeof(window_size));
|
(char *)&window_size, sizeof(window_size));
|
||||||
setsockopt(c->fd, SOL_SOCKET, SO_RCVBUF,
|
setsockopt(c->fd, SOL_SOCKET, SO_RCVBUF,
|
||||||
(char *)&window_size, sizeof(window_size));
|
(char *)&window_size, sizeof(window_size));
|
||||||
|
|
||||||
if (listen(c->fd, 1) == -1)
|
if (listen(c->fd, 1) == -1)
|
||||||
|
{
|
||||||
|
LOG_ERROR("couldn't listen on socket: %s", strerror(errno));
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (type == CONNECTION_PIPE)
|
||||||
{
|
{
|
||||||
LOG_ERROR("couldn't listen on socket: %s", strerror(errno));
|
/* use stdin */
|
||||||
exit(-1);
|
c->fd = STDIN_FILENO;
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
/* for win32 set stdin/stdout to binary mode */
|
||||||
|
if (_setmode(_fileno(stdout), _O_BINARY) < 0)
|
||||||
|
LOG_WARNING("cannot change stdout mode to binary");
|
||||||
|
if (_setmode(_fileno(stdin), _O_BINARY) < 0)
|
||||||
|
LOG_WARNING("cannot change stdin mode to binary");
|
||||||
|
#else
|
||||||
|
socket_nonblock(c->fd);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LOG_ERROR("unknown connection type: %d", type);
|
||||||
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* add to the end of linked list */
|
/* add to the end of linked list */
|
||||||
|
@ -310,14 +353,18 @@ int server_loop(command_context_t *command_context)
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
#if BUILD_ECOSBOARD == 0
|
#if BUILD_ECOSBOARD == 0
|
||||||
/* add STDIN to read_fds */
|
if (server_use_pipes == 0)
|
||||||
FD_SET(fileno(stdin), &read_fds);
|
{
|
||||||
|
/* add STDIN to read_fds */
|
||||||
|
FD_SET(fileno(stdin), &read_fds);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
openocd_sleep_prelude();
|
openocd_sleep_prelude();
|
||||||
kept_alive();
|
kept_alive();
|
||||||
// Only while we're sleeping we'll let others run
|
|
||||||
|
/* Only while we're sleeping we'll let others run */
|
||||||
retval = select(fd_max + 1, &read_fds, NULL, NULL, &tv);
|
retval = select(fd_max + 1, &read_fds, NULL, NULL, &tv);
|
||||||
openocd_sleep_postlude();
|
openocd_sleep_postlude();
|
||||||
|
|
||||||
|
@ -371,11 +418,14 @@ int server_loop(command_context_t *command_context)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
struct sockaddr_in sin;
|
if (service->type != CONNECTION_PIPE)
|
||||||
unsigned int address_size = sizeof(sin);
|
{
|
||||||
int tmp_fd;
|
struct sockaddr_in sin;
|
||||||
tmp_fd = accept(service->fd, (struct sockaddr *)&service->sin, &address_size);
|
unsigned int address_size = sizeof(sin);
|
||||||
close_socket(tmp_fd);
|
int tmp_fd;
|
||||||
|
tmp_fd = accept(service->fd, (struct sockaddr *)&service->sin, &address_size);
|
||||||
|
close_socket(tmp_fd);
|
||||||
|
}
|
||||||
LOG_INFO("rejected '%s' connection, no more connections allowed", service->name);
|
LOG_INFO("rejected '%s' connection, no more connections allowed", service->name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -389,11 +439,16 @@ int server_loop(command_context_t *command_context)
|
||||||
{
|
{
|
||||||
if ((FD_ISSET(c->fd, &read_fds)) || c->input_pending)
|
if ((FD_ISSET(c->fd, &read_fds)) || c->input_pending)
|
||||||
{
|
{
|
||||||
if (service->input(c) != ERROR_OK)
|
if ((retval = service->input(c)) != ERROR_OK)
|
||||||
{
|
{
|
||||||
connection_t *next = c->next;
|
connection_t *next = c->next;
|
||||||
|
if (service->type == CONNECTION_PIPE)
|
||||||
|
{
|
||||||
|
/* if connection uses a pipe then shutdown openocd on error */
|
||||||
|
shutdown_openocd = 1;
|
||||||
|
}
|
||||||
remove_connection(service, c);
|
remove_connection(service, c);
|
||||||
LOG_INFO("dropped '%s' connection", service->name);
|
LOG_INFO("dropped '%s' connection - error %d", service->name, retval);
|
||||||
c = next;
|
c = next;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -405,11 +460,15 @@ int server_loop(command_context_t *command_context)
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
#if BUILD_ECOSBOARD == 0
|
#if BUILD_ECOSBOARD == 0
|
||||||
if (FD_ISSET(fileno(stdin), &read_fds))
|
/* check for data on stdin if not using pipes */
|
||||||
|
if (server_use_pipes == 0)
|
||||||
{
|
{
|
||||||
if (getc(stdin) == 'x')
|
if (FD_ISSET(fileno(stdin), &read_fds))
|
||||||
{
|
{
|
||||||
shutdown_openocd = 1;
|
if (getc(stdin) == 'x')
|
||||||
|
{
|
||||||
|
shutdown_openocd = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -460,7 +519,6 @@ int server_init(void)
|
||||||
signal(SIGABRT, sig_handler);
|
signal(SIGABRT, sig_handler);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,9 +34,8 @@
|
||||||
|
|
||||||
enum connection_type
|
enum connection_type
|
||||||
{
|
{
|
||||||
CONNECTION_GDB,
|
CONNECTION_TCP,
|
||||||
CONNECTION_TELNET,
|
CONNECTION_PIPE
|
||||||
CONNECTION_TCL,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct connection_s
|
typedef struct connection_s
|
||||||
|
@ -76,6 +75,8 @@ extern int server_quit(void);
|
||||||
extern int server_loop(command_context_t *command_context);
|
extern int server_loop(command_context_t *command_context);
|
||||||
extern int server_register_commands(command_context_t *context);
|
extern int server_register_commands(command_context_t *context);
|
||||||
|
|
||||||
|
extern int server_use_pipes;
|
||||||
|
|
||||||
#define ERROR_SERVER_REMOTE_CLOSED (-400)
|
#define ERROR_SERVER_REMOTE_CLOSED (-400)
|
||||||
#define ERROR_CONNECTION_REJECTED (-401)
|
#define ERROR_CONNECTION_REJECTED (-401)
|
||||||
|
|
||||||
|
|
|
@ -179,7 +179,7 @@ int tcl_init(void)
|
||||||
tcl_port = 6666;
|
tcl_port = 6666;
|
||||||
}
|
}
|
||||||
|
|
||||||
retval = add_service("tcl", CONNECTION_TCL, tcl_port, 1, tcl_new_connection, tcl_input, tcl_closed, NULL);
|
retval = add_service("tcl", CONNECTION_TCP, tcl_port, 1, tcl_new_connection, tcl_input, tcl_closed, NULL);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -615,7 +615,7 @@ int telnet_init(char *banner)
|
||||||
|
|
||||||
telnet_service->banner = banner;
|
telnet_service->banner = banner;
|
||||||
|
|
||||||
add_service("telnet", CONNECTION_TELNET, telnet_port, 1, telnet_new_connection, telnet_input, telnet_connection_closed, telnet_service);
|
add_service("telnet", CONNECTION_TCP, telnet_port, 1, telnet_new_connection, telnet_input, telnet_connection_closed, telnet_service);
|
||||||
|
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -232,7 +232,6 @@ const Jim_Nvp nvp_target_debug_reason [] = {
|
||||||
{ .name = NULL, .value = -1 },
|
{ .name = NULL, .value = -1 },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
const Jim_Nvp nvp_target_endian[] = {
|
const Jim_Nvp nvp_target_endian[] = {
|
||||||
{ .name = "big", .value = TARGET_BIG_ENDIAN },
|
{ .name = "big", .value = TARGET_BIG_ENDIAN },
|
||||||
{ .name = "little", .value = TARGET_LITTLE_ENDIAN },
|
{ .name = "little", .value = TARGET_LITTLE_ENDIAN },
|
||||||
|
@ -249,8 +248,7 @@ const Jim_Nvp nvp_reset_modes[] = {
|
||||||
{ .name = NULL , .value = -1 },
|
{ .name = NULL , .value = -1 },
|
||||||
};
|
};
|
||||||
|
|
||||||
static int
|
static int max_target_number(void)
|
||||||
max_target_number( void )
|
|
||||||
{
|
{
|
||||||
target_t *t;
|
target_t *t;
|
||||||
int x;
|
int x;
|
||||||
|
@ -267,8 +265,7 @@ max_target_number( void )
|
||||||
}
|
}
|
||||||
|
|
||||||
/* determine the number of the new target */
|
/* determine the number of the new target */
|
||||||
static int
|
static int new_target_number(void)
|
||||||
new_target_number( void )
|
|
||||||
{
|
{
|
||||||
target_t *t;
|
target_t *t;
|
||||||
int x;
|
int x;
|
||||||
|
|
Loading…
Reference in New Issue