debuggers: import openocd-0.7.0
Initial check-in of openocd-0.7.0 as it can be downloaded from http://sourceforge.net/projects/openocd/files/openocd/0.7.0/ Any modifications will follow. Change-Id: I6949beaefd589e046395ea0cb80f4e1ab1654d55
This commit is contained in:
167
debuggers/openocd/doc/manual/primer/autotools.txt
Normal file
167
debuggers/openocd/doc/manual/primer/autotools.txt
Normal file
@ -0,0 +1,167 @@
|
||||
/** @page primerautotools OpenOCD Autotools Primer
|
||||
|
||||
This page provides an overview to OpenOCD's use of the GNU autotool suite:
|
||||
- @ref primerautoconf
|
||||
- @ref primerautomake
|
||||
- @ref primerlibtool
|
||||
|
||||
Most developers do not need to concern themselves with these tools, as
|
||||
the @ref primerbootstrap script runs these tools in the required sequence.
|
||||
|
||||
@section primerbootstrap Autotools Bootstrap
|
||||
|
||||
The @c bootstrap script should be used by developers to run the
|
||||
autotools in the correct sequence.
|
||||
|
||||
When run after a fresh checkout, this script generates the build files
|
||||
required to compile the project, producing the project configure script.
|
||||
After running @c configure, the @ref primermaintainermode settings will
|
||||
handle most situations that require running these tools again. In some
|
||||
cases, a fresh bootstrap may be still required.
|
||||
|
||||
@subsection primerbootstrapcures Problems Solved By Bootstrap
|
||||
|
||||
For example, the build system can fail in unexpected ways after running
|
||||
<code>git pull</code>. Here, the <code>make maintainer-clean</code>
|
||||
should be used to remove all of the files generated by the @c bootstrap
|
||||
script and subsequent build processes.
|
||||
|
||||
In this particular case, one may also need to remove stray files by hand
|
||||
after running this command to ensure everything is rebuilt properly.
|
||||
This step should be necessary only if the @c maintainer-clean was run
|
||||
@b after altering the build system files with git. If it is run
|
||||
@b before any updates, the build system should never leave artifacts
|
||||
in the tree.
|
||||
|
||||
Without such precautions, changes can be introduced that leave the tree
|
||||
timestamps in an inconsistent state, producing strange compile errors
|
||||
that are resolve after such diligence.
|
||||
|
||||
@subsection primermaintainerclean Autotools Cleaning
|
||||
|
||||
Normally, all files generated by the bootstrap script, configure
|
||||
process, and build system should be removed after running <code>make
|
||||
maintainer-clean</code>. Automatically generated files that remain
|
||||
after this should be listed in @c MAINTAINERCLEANFILES,
|
||||
@c DISTCLEANFILES, or @c CLEANFILES, depending on which stage of the
|
||||
build process they are produced.
|
||||
|
||||
@section primerautoconf Autoconf Configuration Script
|
||||
|
||||
The @c autoconf program generates the @c configure script from
|
||||
@c configure.in, using serious Perl voodoo. The resulting script is
|
||||
included in the project distribution packages and run by users to
|
||||
configure the build process for their system.
|
||||
|
||||
@subsection primermaintainermode Maintainer Mode
|
||||
|
||||
After a fresh checkout, @c bootstrap, and a simple @c configure, you may
|
||||
experience errors when running @c make that some files cannot be found
|
||||
(e.g. @c version.texi), and a second @c make will "mysteriously" solve
|
||||
the problems. The isssue is well-known and expected, if unfortunate.
|
||||
|
||||
The OpenOCD project requires that all developers building from the
|
||||
git repository use the @c --enable-maintainer-mode option when
|
||||
running the @c configure script. This option ensures that certain files
|
||||
are created during the build process that would normally be packaged in
|
||||
the distribution tarball. The @c bootstrap script will remind you of
|
||||
this requirement when it runs.
|
||||
|
||||
In addition to solving these problems, this option enables Makefile
|
||||
rules (provided by automake) that allow the normal @c make process to
|
||||
rebuild the autotools outputs, included the automake-generated Makefiles
|
||||
themselves. This avoids the heavy-handed approach of running the
|
||||
@c bootstrap script after changing one of these files.
|
||||
|
||||
@section primerautomake Automake Makefiles
|
||||
|
||||
The @c automake program generates @c Makefile.in files (from @c
|
||||
Makefile.am files). These files are later processed by the configure
|
||||
script produced by @c autoconf.
|
||||
|
||||
@subsection primerautomakenewfiles Creating Makefile.am Files
|
||||
|
||||
This section shows how to add a @c Makefile.am in a new directory (or
|
||||
one that lacks one).
|
||||
-# The new directory must be listed in the @c SUBDIRS variable in the
|
||||
parent directory's Makefile.am:
|
||||
@code
|
||||
$ echo 'SUBDIRS += directory' >>../Makefile.am
|
||||
@endcode
|
||||
-# Create an bare-bones Makefile.am file in directory that needs it:
|
||||
@code
|
||||
$ echo "MAINTAINERCLEANFILES = Makefile.in" >Makefile.am
|
||||
@endcode
|
||||
-# The @c configure.in script must be updated, so it generates the required
|
||||
Makefile when the @a configure script is run by the user:
|
||||
@verbatim
|
||||
AC_OUTPUT([
|
||||
...
|
||||
path/to/new/Makefile
|
||||
])
|
||||
@endverbatim
|
||||
|
||||
Note: these instructions are @b not meant to be used literally, rather
|
||||
they are shown for demonstration purposes.
|
||||
|
||||
The default MAINTAINERCLEANFILES rule ensures that the
|
||||
automake-generated @c Makefile.in file will be removed when developers
|
||||
run <code>make maintainer-clean</code>. Additional rules may be added
|
||||
after this; however, the project should bootstrap and tear down cleanly
|
||||
after taking these minimal steps, with the new directory being visited
|
||||
during the @c make sequence.
|
||||
|
||||
@subsection primerautomaketweaks Updating Makefile.am Files
|
||||
|
||||
Adding, removing, and renaming files from the project tree usually
|
||||
requires updating the autotools inputs. This section will help describe
|
||||
how to do this as questions arise.
|
||||
|
||||
@section primerlibtool Libtool and Libraries
|
||||
|
||||
The @c libtool program provides the means of generating libraries in a
|
||||
portable and painless manner (relatively speaking).
|
||||
|
||||
This section will contain an answer to "what does libtool give OpenOCD?"
|
||||
and "what do developers need to consider in new code?"
|
||||
|
||||
@section primerautotoolsmation Autotools Automation
|
||||
|
||||
This section outlines three ways the autotools provides automation to
|
||||
assist with testing and distribution:
|
||||
- @ref primerautocheck -- automatic unit and smoke tests
|
||||
- @ref primerautodistcheck -- automatic distribution and packaging tests
|
||||
|
||||
@subsection primerautocheck make check
|
||||
|
||||
The <code>make check</code> command will run the OpenOCD test suite,
|
||||
once it has been integrated as such. This section will contain
|
||||
information about how to extend the testing build system components to
|
||||
implement new checks.
|
||||
|
||||
@subsection primerautodistcheck make distcheck
|
||||
|
||||
The <code>make distcheck</code> command produces an archive of the
|
||||
project deliverables (using <code>make dist</code>) and verifies its
|
||||
integrity for distribution by attemptng to use the package in the same
|
||||
manner as a user.
|
||||
|
||||
These checks includes the following steps:
|
||||
-# Unpack the project archive into its expected directory.
|
||||
-# Configure and build the project in a temporary out-of-tree directory.
|
||||
-# Run <code>make check</code> to ensure the distributed code passes all tests.
|
||||
-# Run <code>make install</code> into a temporary installation directory.
|
||||
-# Check that <code>make uninstall</code> removes all files that were installed.
|
||||
-# Check that <code>make distclean</code> removes all files created
|
||||
during all other steps (except the first).
|
||||
|
||||
If all of these steps complete successfully, the @c make process will
|
||||
output a friendly message indicating the archive is ready to be
|
||||
distributed.
|
||||
|
||||
*/
|
||||
/** @file
|
||||
|
||||
This file contains the @ref primerautotools page.
|
||||
|
||||
*/
|
||||
138
debuggers/openocd/doc/manual/primer/commands.txt
Normal file
138
debuggers/openocd/doc/manual/primer/commands.txt
Normal file
@ -0,0 +1,138 @@
|
||||
/** @page primercommand Command Development Primer
|
||||
|
||||
This page provides a primer for writing commands by introducing @c hello
|
||||
module. The full source code used in this example can be found in
|
||||
hello.c, and the @ref primercmdcode section shows how to use it.
|
||||
|
||||
A summary of this information can be found in @ref helpercommand .
|
||||
|
||||
@section primercmdhandler Command Handlers
|
||||
|
||||
Defining new commands and their helpers is easy. The following code
|
||||
defines a simple command handler that delegates its argument parsing:
|
||||
@code
|
||||
COMMAND_HANDLER(handle_hello_command)
|
||||
{
|
||||
const char *sep, *name;
|
||||
int retval = CALL_COMMAND_HANDLER(handle_hello_args);
|
||||
if (ERROR_OK == retval)
|
||||
command_print(CMD_CTX, "Greetings%s%s!", sep, name);
|
||||
return retval;
|
||||
}
|
||||
@endcode
|
||||
|
||||
Here, the @c COMMAND_HANDLER macro establishes the function signature,
|
||||
see in command.h by the @c __COMMAND_HANDLER macro.
|
||||
|
||||
The COMMAND_HELPER macro function allows defining functions with an
|
||||
extended version of the base signature. These helper functions can be
|
||||
called (with the appropriate parameters), the @c CALL_COMMAND_HANDLER
|
||||
macro to pass any e as parameters to the following helper function:
|
||||
|
||||
The subsequent blocks of code are a normal C function that can do
|
||||
anything, so only complex commands deserve should use comamnd helper
|
||||
functions. In this respect, this example uses one to demonstrate how --
|
||||
not when -- they should be used.
|
||||
|
||||
@code
|
||||
static COMMAND_HELPER(handle_hello_args, const char **sep, const char **name)
|
||||
{
|
||||
if (argc > 1)
|
||||
{
|
||||
LOG_ERROR("%s: too many arguments", CMD_NAME);
|
||||
return ERROR_COMMAND_SYNTAX_ERROR;
|
||||
}
|
||||
if (1 == CMD_ARGC)
|
||||
{
|
||||
*sep = ", ";
|
||||
*name = CMD_ARGV[0];
|
||||
}
|
||||
else
|
||||
*sep = *name = "";
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
@endcode
|
||||
|
||||
Of course, you may also call other macros or functions, but that extends
|
||||
beyond the scope of this tutorial on writing commands.
|
||||
|
||||
@section primercmdreg Command Registration
|
||||
|
||||
Before this new function can be used, it must be registered somehow.
|
||||
For a new module, registering should be done in a new function for
|
||||
the purpose, which must be called from @c openocd.c:
|
||||
@code
|
||||
|
||||
static const struct command_registration hello_command_handlers[] = {
|
||||
{
|
||||
.name = "hello",
|
||||
.mode = COMMAND_ANY,
|
||||
.handler = handle_hello_command,
|
||||
.help = "print a warm greeting",
|
||||
.usage = "[name]",
|
||||
},
|
||||
{
|
||||
.chain = foo_command_handlers,
|
||||
}
|
||||
COMMAND_REGISTRATION_DONE
|
||||
};
|
||||
|
||||
int hello_register_commands(struct command_context_s *cmd_ctx)
|
||||
{
|
||||
return register_commands(cmd_ctx, NULL, handle_command_handlers);
|
||||
}
|
||||
@endcode
|
||||
|
||||
Note that the "usage" text should use the same EBNF that's found
|
||||
in the User's Guide: literals in 'single quotes', sequences of
|
||||
optional parameters in [square brackets], and alternatives in
|
||||
(parentheses|with|vertical bars), and so forth. No angle brackets.
|
||||
|
||||
That's it! The command should now be registered and available to scripts.
|
||||
|
||||
@section primercmdchain Command Chaining
|
||||
|
||||
This example also shows how to chain command handler registration, so
|
||||
your modules can "inherit" commands provided by other (sub)modules.
|
||||
Here, the hello module includes the foo commands in the same context
|
||||
that the 'hello' command will be registered.
|
||||
|
||||
If the @c chain field had been put in the 'hello' command, then the
|
||||
@c foo module commands would be registered under it. Indeed, that
|
||||
technique is used to define the 'foo bar' and 'foo baz' commands,
|
||||
as well as for the example drivers that use these modules.
|
||||
|
||||
The code for the 'foo' command handlers can be found in @c hello.c.
|
||||
|
||||
@section primercmdcode Trying These Example Commands
|
||||
|
||||
These commands have been inherited by the dummy interface, faux flash,
|
||||
and testee target drivers. The easiest way to test these is by using the
|
||||
dummy interface.
|
||||
|
||||
Once OpenOCD has been built with this example code, the following command
|
||||
demonstrates the abilities that the @c hello module provides:
|
||||
@code
|
||||
openocd -c 'interface dummy' \
|
||||
-c 'dummy hello' \
|
||||
-c 'dummy hello World' \
|
||||
-c 'dummy hello {John Doe}' \
|
||||
-c 'dummy hello John Doe' # error: too many arguments
|
||||
@endcode
|
||||
|
||||
If saved in @c hello.cfg, then running <code>openocd -f hello.cfg</code>
|
||||
should produce the following output before displaying the help text and
|
||||
exiting:
|
||||
@code
|
||||
Greetings!
|
||||
Greetings, World!
|
||||
Greetings, John Doe!
|
||||
Error: hello: too many arguments
|
||||
Runtime error, file "openocd.cfg", line 14:
|
||||
hello: too many arguments
|
||||
dummy hello [<name>]
|
||||
prints a warm welcome
|
||||
@endcode
|
||||
|
||||
*/
|
||||
124
debuggers/openocd/doc/manual/primer/docs.txt
Normal file
124
debuggers/openocd/doc/manual/primer/docs.txt
Normal file
@ -0,0 +1,124 @@
|
||||
/** @page primerdocs OpenOCD Documentation Primers
|
||||
|
||||
This page provides an introduction to OpenOCD's documentation processes.
|
||||
|
||||
OpenOCD presently produces several kinds of documentation:
|
||||
- The User's Guide:
|
||||
- Focuses on using the OpenOCD software.
|
||||
- Details the installation, usage, and customization.
|
||||
- Provides descriptions of public Jim/TCL script commands.
|
||||
- Written using GNU texinfo.
|
||||
- Created with 'make pdf' or 'make html'.
|
||||
- See @subpage primertexinfo and @ref styletexinfo.
|
||||
- The References: (as proposed)
|
||||
- Focuses on using specific hardware with OpenOCD.
|
||||
- Details the supported interfaces, chips, boards, and targets.
|
||||
- Provides overview, usage, reference, and FAQ for each device.
|
||||
- Written using LaTeX language with custom macros.
|
||||
- Created with 'make references'.
|
||||
- See @subpage primerlatex and @ref stylelatex.
|
||||
- The Manual:
|
||||
- Focuses on developing the OpenOCD software.
|
||||
- Details the architecutre, driver interfaces, and processes.
|
||||
- Provides "full" coverage of C source code (work-in-progress).
|
||||
- Written using Doxygen C language conventions (i.e. in comments).
|
||||
- Created with 'make doxygen'.
|
||||
- See @subpage primerdoxygen and @ref styledoxygen.
|
||||
|
||||
The following sections provide more information for anyone that wants to
|
||||
contribute new or updated documentation to the OpenOCD project.
|
||||
|
||||
*/
|
||||
/** @page primertexinfo Texinfo Primer
|
||||
|
||||
The OpenOCD User's Guide presently exists entirely within the
|
||||
doc/openocd.texi document. That file contains documentation with
|
||||
mark-up suitable for being parsed by the GNU Texinfo utilities
|
||||
(http://www.gnu.org/software/texinfo/).
|
||||
|
||||
When you add a new command, driver, or driver option, it needs to be
|
||||
documented in the User's Guide. Use the existing documentation for
|
||||
models, but feel free to make better use of Texinfo mechanisms. See
|
||||
the Texinfo web site for the Texinfo manual and more information.
|
||||
|
||||
OpenOCD style guidelines for Texinfo documentation can be found on the
|
||||
@ref styletexinfo page.
|
||||
|
||||
*/
|
||||
/** @page primerlatex LaTeX Primer
|
||||
|
||||
The OpenOCD project provides a number of reference guides using the
|
||||
LaTeX typesetting language.
|
||||
|
||||
- OpenOCD Quick Reference Sheets
|
||||
- OpenOCD Hardware Reference Guides
|
||||
|
||||
These documents have not yet been produced, so this Primer serves as
|
||||
a placeholder to describe how they are created and can be extended.
|
||||
The same holds true for the @ref stylelatex page.
|
||||
|
||||
*/
|
||||
/** @page primerdoxygen Doxygen Primer
|
||||
|
||||
Doxygen-style comments are used to provide documentation in-line with
|
||||
the OpenOCD source code. These comments are used to document functions,
|
||||
variables, structs, enums, fields, and everything else that might need
|
||||
to be documented for developers. Additional files containing comments
|
||||
that supplement the code comments in order to provide complete developer
|
||||
documentation.
|
||||
|
||||
Even if you already know Doxygen, please read this Primer to learn
|
||||
how OpenOCD developers already use Doxygen features in the project tree.
|
||||
For more information about OpenOCD's required style for using Doxygen,
|
||||
see the @ref styledoxygen page and look at existing documentation in the
|
||||
@c doc/manual tree.
|
||||
|
||||
@section primerdoxytext Doxygen Input Files
|
||||
|
||||
Doxygen has been configured parse all of the C source code files (*.c
|
||||
and *.h) in @c src/ in order to produce a complete reference of all
|
||||
OpenOCD project symbols. In addition to the source code files, other
|
||||
files will also be scanned for comment blocks; some are referenced
|
||||
explicitly by the @c INPUT variable in the Doxygen configuration file.
|
||||
|
||||
By default, the Doxygen configuration enables a "full" set of features,
|
||||
including generation of dependency graphs (using the GraphViz package).
|
||||
These features may be disabled by editing the @c Doxyfile.in file at the
|
||||
top of the project tree; the configuration file includes comments that
|
||||
provide detailed documentation for each option.
|
||||
|
||||
To support out-of-tree building of the documentation, the @c Doxyfile.in
|
||||
@c INPUT values will have all instances of the string @c "@srcdir@"
|
||||
replaced with the current value of the make variable
|
||||
<code>$(srcdir)</code>. The Makefile uses a rule to convert
|
||||
@c Doxyfile.in into the @c Doxyfile used by <code>make doxygen</code>.
|
||||
|
||||
@section primerdoxyoocd OpenOCD Input Files
|
||||
|
||||
OpenOCD uses the @c INPUT mechanism to include additional documentation to
|
||||
provide The Manual for OpenOCD Developers. These extra files contain
|
||||
high-level information intended to supplement the relatively low-level
|
||||
documentation that gets extracted from the source code comments.
|
||||
|
||||
OpenOCD's Doxygen configuration file will search for all @c .txt files
|
||||
that can be found under the @c doc/manual directory in the project tree.
|
||||
New files containing valid Doxygen markup that are placed in or under
|
||||
that directory will be detected and included in The Manual automatically.
|
||||
|
||||
@section primerdoxyman Doxygen Reference Manual
|
||||
|
||||
The full documentation for Doxygen can be referenced on-line at the project
|
||||
home page: http://www.doxygen.org/index.html. In HTML versions of this
|
||||
document, an image with a link to this site appears in the page footer.
|
||||
|
||||
*/
|
||||
/** @file
|
||||
|
||||
This file contains the Doxygen source code for the @ref primerdocs.
|
||||
The @ref primerdocs page also contains the following sections:
|
||||
|
||||
- @ref primertexinfo
|
||||
- @ref primerlatex
|
||||
- @ref primerdoxygen
|
||||
|
||||
*/
|
||||
170
debuggers/openocd/doc/manual/primer/jtag.txt
Normal file
170
debuggers/openocd/doc/manual/primer/jtag.txt
Normal file
@ -0,0 +1,170 @@
|
||||
/** @page primerjtag OpenOCD JTAG Primer
|
||||
|
||||
JTAG is unnecessarily confusing, because JTAG is often confused with
|
||||
boundary scan, which is just one of its possible functions.
|
||||
|
||||
JTAG is simply a communication interface designed to allow communication
|
||||
to functions contained on devices, for the designed purposes of
|
||||
initialisation, programming, testing, debugging, and anything else you
|
||||
want to use it for (as a chip designer).
|
||||
|
||||
Think of JTAG as I2C for testing. It doesn't define what it can do,
|
||||
just a logical interface that allows a uniform channel for communication.
|
||||
|
||||
See @par
|
||||
http://en.wikipedia.org/wiki/Joint_Test_Action_Group
|
||||
|
||||
and @par
|
||||
http://www.inaccessnetworks.com/projects/ianjtag/jtag-intro/jtag-state-machine-large.png
|
||||
|
||||
The first page (among other things) shows a logical representation
|
||||
describing how multiple devices are wired up using JTAG. JTAG does not
|
||||
specify, data rates or interface levels (3.3V/1.8V, etc) each device can
|
||||
support different data rates/interface logic levels. How to wire them
|
||||
in a compatible way is an exercise for an engineer.
|
||||
|
||||
Basically TMS controls which shift register is placed on the device,
|
||||
between TDI and TDO. The second diagram shows the state transitions on
|
||||
TMS which will select different shift registers.
|
||||
|
||||
The first thing you need to do is reset the state machine, because when
|
||||
you connect to a chip you do not know what state the controller is in,you need
|
||||
to clock TMS as 1, at least 5 times. This will put you into "Test Logic
|
||||
Reset" State. Knowing this, you can, once reset, then track what each
|
||||
transition on TMS will do, and hence know what state the JTAG state
|
||||
machine is in.
|
||||
|
||||
There are 2 "types" of shift registers. The Instruction shift register
|
||||
and the data shift register. The sizes of these are undefined, and can
|
||||
change from chip to chip. The Instruction register is used to select
|
||||
which Data register/data register function is used, and the data
|
||||
register is used to read data from that function or write data to it.
|
||||
|
||||
Each of the states control what happens to either the data register or
|
||||
instruction register.
|
||||
|
||||
For example, one of the data registers will be known as "bypass" this is
|
||||
(usually) a single bit which has no function and is used to bypass the
|
||||
chip. Assume we have 3 identical chips, wired up like the picture(wikipedia)
|
||||
and each has a 3 bits instruction register, and there are 2 known
|
||||
instructions (110 = bypass, 010 = "some other function") if we want to use
|
||||
"some other function", on the second chip in the line, and not change
|
||||
the other chips we would do the following transitions.
|
||||
|
||||
From Test Logic Reset, TMS goes:
|
||||
|
||||
0 1 1 0 0
|
||||
|
||||
which puts every chip in the chain into the "Shift IR state"
|
||||
Then (while holding TMS as 0) TDI goes:
|
||||
|
||||
0 1 1 0 1 0 0 1 1
|
||||
|
||||
which puts the following values in the instruction shift register for
|
||||
each chip [110] [010] [110]
|
||||
|
||||
The order is reversed, because we shift out the least significant bit
|
||||
first. Then we transition TMS:
|
||||
|
||||
1 1 1 0 0
|
||||
|
||||
which puts us in the "Shift DR state".
|
||||
|
||||
Now when we clock data onto TDI (again while holding TMS to 0) , the
|
||||
data shifts through the data registers, and because of the instruction
|
||||
registers we selected ("some other function" has 8 bits in its data
|
||||
register), our total data register in the chain looks like this:
|
||||
|
||||
0 00000000 0
|
||||
|
||||
The first and last bit are in the "bypassed" chips, so values read from
|
||||
them are irrelevant and data written to them is ignored. But we need to
|
||||
write bits for those registers, because they are in the chain.
|
||||
|
||||
If we wanted to write 0xF5 to the data register we would clock out of
|
||||
TDI (holding TMS to 0):
|
||||
|
||||
0 1 0 1 0 1 1 1 1 0
|
||||
|
||||
Again, we are clocking the least-significant bit first. Then we would
|
||||
clock TMS:
|
||||
|
||||
1 1 0
|
||||
|
||||
which updates the selected data register with the value 0xF5 and returns
|
||||
us to run test idle.
|
||||
|
||||
If we needed to read the data register before over-writing it with F5,
|
||||
no sweat, that's already done, because the TDI/TDO are set up as a
|
||||
circular shift register, so if you write enough bits to fill the shift
|
||||
register, you will receive the "captured" contents of the data registers
|
||||
simultaneously on TDO.
|
||||
|
||||
That's JTAG in a nutshell. On top of this, you need to get specs for
|
||||
target chips and work out what the various instruction registers/data
|
||||
registers do, so you can actually do something useful. That's where it
|
||||
gets interesting. But in and of itself, JTAG is actually very simple.
|
||||
|
||||
@section primerjtag More Reading
|
||||
|
||||
A separate primer contains information about @subpage primerjtagbs for
|
||||
developers that want to extend OpenOCD for such purposes.
|
||||
|
||||
*/
|
||||
/** @page primerjtagbs JTAG Boundary Scan Primer
|
||||
|
||||
The following page provides an introduction on JTAG that focuses on its
|
||||
boundary scan capabilities: @par
|
||||
http://www.engr.udayton.edu/faculty/jloomis/ece446/notes/jtag/jtag1.html
|
||||
|
||||
OpenOCD does not presently have clear means of using JTAG for boundary
|
||||
scan testing purposes; however, some developers have explored the
|
||||
possibilities. The page contains information that may be useful to
|
||||
those wishing to implement boundary scan capabilities in OpenOCD.
|
||||
|
||||
@section primerbsdl The BSDL Language
|
||||
|
||||
For more information on the Boundary Scan Description Language (BSDL),
|
||||
the following page provides a good introduction: @par
|
||||
http://www.radio-electronics.com/info/t_and_m/boundaryscan/bsdl.php
|
||||
|
||||
@section primerbsdlvendors Vendor BSDL Files
|
||||
|
||||
NXP LPC: @par
|
||||
http://www.standardics.nxp.com/support/models/lpc2000/
|
||||
|
||||
Freescale PowerPC: @par
|
||||
http://www.freescale.com/webapp/sps/site/overview.jsp?code=DRPPCBSDLFLS
|
||||
|
||||
Freescale i.MX1 (too old): @par
|
||||
http://www.freescale.com/webapp/sps/site/prod_summary.jsp?code=i.MX1&nodeId=0162468rH311432973ZrDR&fpsp=1&tab=Design_Tools_Tab
|
||||
|
||||
Renesas R32C/117: @par
|
||||
http://sg.renesas.com/fmwk.jsp?cnt=r32c116_7_8_root.jsp&fp=/products/mpumcu/m16c_family/r32c100_series/r32c116_7_8_group/
|
||||
- The device page does not come with BSDL file; you have to register to
|
||||
download them. @par
|
||||
http://www.corelis.com/support/BSDL.htm
|
||||
|
||||
TI links theirs right off the generic page for each chip;
|
||||
this may be the case for other vendors as well. For example:
|
||||
|
||||
- DaVinci DM355 -- http://www.ti.com/litv/zip/sprm262b
|
||||
- DaVinci DM6446
|
||||
- 2.1 silicon -- http://www.ti.com/litv/zip/sprm325a
|
||||
- older silicon -- http://www.ti.com/litv/zip/sprm203
|
||||
- OMAP 3530
|
||||
- CBB package -- http://www.ti.com/litv/zip/sprm315b
|
||||
- 515 ball s-PGBA, POP, 0.4mm pitch
|
||||
- CUS package -- http://www.ti.com/litv/zip/sprm314a
|
||||
- 515 ball s-PGBA, POP, 0.5mm pitch
|
||||
- CBC package -- http://www.ti.com/litv/zip/sprm346
|
||||
- 423 ball s-PGBA, 0.65mm pitch
|
||||
|
||||
Many other files are available in the "Semiconductor Manufacturer's BSDL
|
||||
files" section of the following site: @par
|
||||
http://www.freelabs.com/~whitis/electronics/jtag/
|
||||
|
||||
*/
|
||||
/** @file
|
||||
This file contains the @ref primerjtag and @ref primerjtagbs page.
|
||||
*/
|
||||
440
debuggers/openocd/doc/manual/primer/tcl.txt
Normal file
440
debuggers/openocd/doc/manual/primer/tcl.txt
Normal file
@ -0,0 +1,440 @@
|
||||
/** @page primertcl OpenOCD TCL Primer
|
||||
|
||||
The @subpage scripting page provides additional TCL Primer material.
|
||||
|
||||
@verbatim
|
||||
|
||||
****************************************
|
||||
****************************************
|
||||
|
||||
This is a short introduction to 'un-scare' you about the language
|
||||
known as TCL. It is structured as a guided tour through the files
|
||||
written by me [Duane Ellis] - in early July 2008 for OpenOCD.
|
||||
|
||||
Which uses the "JIM" embedded Tcl clone-ish language.
|
||||
|
||||
Thing described here are *totally* TCL generic... not Jim specific.
|
||||
|
||||
The goal of this document is to encourage you to add your own set of
|
||||
chips to the TCL package - and most importantly you should know where
|
||||
you should put them - so they end up in an organized way.
|
||||
|
||||
--Duane Ellis.
|
||||
duane@duaneellis.com
|
||||
|
||||
****************************************
|
||||
****************************************
|
||||
|
||||
Adding "chip" support - Duane Ellis July 5 - 2008.
|
||||
|
||||
The concept is this:
|
||||
In your "openocd.cfg" file add something like this:
|
||||
|
||||
source [find tcl/chip/VENDOR/FAMILY/NAME.tcl]
|
||||
|
||||
For example...
|
||||
source [find tcl/chip/atmel/at91/at91sam7x256.tcl]
|
||||
|
||||
You'll notice that it makes use of:
|
||||
|
||||
tcl/cpu/arm/<NAME>.tcl.
|
||||
|
||||
Yes, that is where you should put "core" specific things.
|
||||
Be careful and learn the difference:
|
||||
|
||||
THE "CORE" - is not the entire chip!
|
||||
|
||||
Definition:
|
||||
That "file" listed above is called a "CHIP FILE".
|
||||
|
||||
It may be standalone, or may need to "source" other "helper" files.
|
||||
|
||||
The reference [7/5/2008] is the at91sam7x256.tcl file.
|
||||
|
||||
****************************************
|
||||
****************************************
|
||||
=== TCL TOUR ===
|
||||
Open: at91sam7x256.tcl
|
||||
=== TCL TOUR ===
|
||||
|
||||
A walk through --- For those who are new to TCL.
|
||||
|
||||
Examine the file: at91sam7x256.tcl
|
||||
|
||||
It starts with:
|
||||
source [find path/filename.tcl]
|
||||
|
||||
In TCL - this is very important.
|
||||
|
||||
Rule #1 Everything is a string.
|
||||
Rule #2 If you think other wise See #1.
|
||||
Reminds you of:
|
||||
Rule #1: The wife is correct.
|
||||
Rule #2: If you think otherwise, See #1
|
||||
|
||||
Any text contained inside of [square-brackets]
|
||||
is just like `back-ticks` in BASH.
|
||||
|
||||
Hence, the [find FILENAME] executes the command find with a single
|
||||
parameter the filename.
|
||||
|
||||
========================================
|
||||
|
||||
Next you see a series of:
|
||||
|
||||
set NAME VALUE
|
||||
|
||||
It is mostly "obvious" what is going on.
|
||||
|
||||
Exception: The arrays.
|
||||
|
||||
You would *THINK* Tcl supports arrays.
|
||||
In fact, multi-dim arrays. That is false.
|
||||
|
||||
For the index for"FLASH(0,CHIPSELECT)" is actually the string
|
||||
"0,CHIPSELECT". This is problematic. In the normal world, you think
|
||||
of array indexes as integers.
|
||||
|
||||
For example these are different:
|
||||
|
||||
set foo(0x0c) 123
|
||||
set foo(12) 444
|
||||
|
||||
Why? Because 0x0c {lowercase} is a string.
|
||||
Don't forget UPPER CASE.
|
||||
|
||||
You must be careful - always... always... use simple decimal
|
||||
numbers. When in doubt use 'expr' the evaluator. These are all the
|
||||
same.
|
||||
|
||||
set x 0x0c
|
||||
set foo([expr $x]) "twelve"
|
||||
|
||||
set x 12
|
||||
set foo([expr $x]) "twelve"
|
||||
|
||||
set x "2 * 6"
|
||||
set foo([expr $x]) "twelve"
|
||||
|
||||
**************************************************
|
||||
***************************************************
|
||||
=== TCL TOUR ===
|
||||
Open the file: "bitsbytes.tcl"
|
||||
|
||||
There is some tricky things going on.
|
||||
===============
|
||||
|
||||
First, there is a "for" loop - at level 0
|
||||
{level 0 means: out side of a proc/function}
|
||||
|
||||
This means it is evaluated when the file is parsed.
|
||||
|
||||
== SIDEBAR: About The FOR command ==
|
||||
In TCL, "FOR" is a funny thing, it is not what you think it is.
|
||||
|
||||
Syntactically - FOR is a just a command, it is not language
|
||||
construct like for(;;) in C...
|
||||
|
||||
The "for" command takes 4 parameters.
|
||||
(1) The "initial command" to execute.
|
||||
(2) the test "expression"
|
||||
(3) the "next command"
|
||||
(4) the "body command" of the FOR loop.
|
||||
|
||||
Notice I used the words "command" and "expression" above.
|
||||
|
||||
The FOR command:
|
||||
1) executes the "initial command"
|
||||
2) evaluates the expression if 0 it stops.
|
||||
3) executes the "body command"
|
||||
4) executes the "next command"
|
||||
5) Goto Step 2.
|
||||
|
||||
As show, each of these items are in {curly-braces}. This means they
|
||||
are passed as they are - KEY-POINT: un evaluated to the FOR
|
||||
command. Think of it like escaping the backticks in Bash so that the
|
||||
"under-lying" command can evaluate the contents. In this case, the FOR
|
||||
COMMAND.
|
||||
|
||||
== END: SIDEBAR: About The FOR command ==
|
||||
|
||||
You'll see two lines:
|
||||
|
||||
LINE1:
|
||||
set vn [format "BIT%d" $x]
|
||||
|
||||
Format is like "sprintf". Because of the [brackets], it becomes what
|
||||
you think. But here's how:
|
||||
|
||||
First - the line is parsed - for {braces}. In this case, there are
|
||||
none. The, the parser looks for [brackets] and finds them. The,
|
||||
parser then evaluates the contents of the [brackets], and replaces
|
||||
them. It is alot this bash statement.
|
||||
|
||||
EXPORT vn=`date`
|
||||
|
||||
LINE 2 & 3
|
||||
set $vn [expr (1024 * $x)]
|
||||
global $vn
|
||||
|
||||
In line 1, we dynamically created a variable name. Here, we are
|
||||
assigning it a value. Lastly Line 3 we force the variable to be
|
||||
global, not "local" the the "for command body"
|
||||
|
||||
===============
|
||||
The PROCS
|
||||
|
||||
proc create_mask { MSB LSB } {
|
||||
... body ....
|
||||
}
|
||||
|
||||
Like "for" - PROC is really just a command that takes 3 parameters.
|
||||
The (1) NAME of the function, a (2) LIST of parameters, and a (3) BODY
|
||||
|
||||
Again, this is at "level 0" so it is a global function. (Yes, TCL
|
||||
supports local functions, you put them inside of a function}
|
||||
|
||||
You'll see in some cases, I nest [brackets] alot and in others I'm
|
||||
lazy or wanted it to be more clear... it is a matter of choice.
|
||||
===============
|
||||
|
||||
|
||||
**************************************************
|
||||
***************************************************
|
||||
=== TCL TOUR ===
|
||||
Open the file: "memory.tcl"
|
||||
===============
|
||||
|
||||
Here is where I setup some 'memory definitions' that various targets can use.
|
||||
|
||||
For example - there is an "unknown" memory region.
|
||||
|
||||
All memory regions must have 2 things:
|
||||
|
||||
(1) N_<name>
|
||||
(2) NAME( array )
|
||||
And the array must have some specific names:
|
||||
( <idx>, THING )
|
||||
Where: THING is one of:
|
||||
CHIPSELECT
|
||||
BASE
|
||||
LEN
|
||||
HUMAN
|
||||
TYPE
|
||||
RWX - the access ability.
|
||||
WIDTH - the accessible width.
|
||||
|
||||
ie: Some regions of memory are not 'word'
|
||||
accessible.
|
||||
|
||||
The function "address_info" - given an address should
|
||||
tell you about the address.
|
||||
|
||||
[as of this writing: 7/5/2008 I have done
|
||||
only a little bit with this -Duane]
|
||||
|
||||
===
|
||||
MAJOR FUNCTION:
|
||||
==
|
||||
|
||||
proc memread32 { ADDR }
|
||||
proc memread16 { ADDR }
|
||||
proc memread8 { ADDR }
|
||||
|
||||
All read memory - and return the contents.
|
||||
|
||||
[ FIXME: 7/5/2008 - I need to create "memwrite" functions]
|
||||
|
||||
**************************************************
|
||||
***************************************************
|
||||
=== TCL TOUR ===
|
||||
Open the file: "mmr_helpers.tcl"
|
||||
===============
|
||||
|
||||
This file is used to display and work with "memory mapped registers"
|
||||
|
||||
For example - 'show_mmr32_reg' is given the NAME of the register to
|
||||
display. The assumption is - the NAME is a global variable holding the
|
||||
address of that MMR.
|
||||
|
||||
The code does some tricks. The [set [set NAME]] is the TCL way
|
||||
of doing double variable interpolation - like makefiles...
|
||||
|
||||
In a makefile or shell script you may have seen this:
|
||||
|
||||
FOO_linux = "Penguins rule"
|
||||
FOO_winXP = "Broken Glass"
|
||||
FOO_mac = "I like cat names"
|
||||
|
||||
# Pick one
|
||||
BUILD = linux
|
||||
#BUILD = winXP
|
||||
#BUILD = mac
|
||||
FOO = ${FOO_${BUILD}}
|
||||
|
||||
The "double [set] square bracket" thing is the TCL way, nothing more.
|
||||
|
||||
----
|
||||
|
||||
The IF statement - and "CATCH" .
|
||||
|
||||
Notice this IF COMMAND - (not statement) is like this:
|
||||
[7/5/2008 it is this way]
|
||||
|
||||
if ![catch { command } msg ] {
|
||||
...something...
|
||||
} else {
|
||||
error [format string...]
|
||||
}
|
||||
|
||||
The "IF" command expects either 2 params, or 4 params.
|
||||
|
||||
=== Sidebar: About "commands" ===
|
||||
|
||||
Take a look at the internals of "jim.c"
|
||||
Look for the function: Jim_IfCoreCommand()
|
||||
And all those other "CoreCommands"
|
||||
|
||||
You'll notice - they all have "argc" and "argv"
|
||||
|
||||
Yea, the entire thing is done that way.
|
||||
|
||||
IF is a command. SO is "FOR" and "WHILE" and "DO" and the
|
||||
others. That is why I keep using the phase it is a "command"
|
||||
|
||||
=== END: Sidebar: About "commands" ===
|
||||
|
||||
Parameter 1 to the IF command is expected to be an expression.
|
||||
|
||||
As such, I do not need to wrap it in {braces}.
|
||||
|
||||
In this case, the "expression" is the result of the "CATCH" command.
|
||||
|
||||
CATCH - is an error catcher.
|
||||
|
||||
You give CATCH 1 or 2 parameters.
|
||||
The first 1st parameter is the "code to execute"
|
||||
The 2nd (optional) is where to put the error message.
|
||||
|
||||
CATCH returns 0 on success, 1 for failure.
|
||||
The "![catch command]" is self explaintory.
|
||||
|
||||
|
||||
The 3rd parameter to IF must be exactly "else" or "elseif" [I lied
|
||||
above, the IF command can take many parameters they just have to
|
||||
be joined by exactly the words "else" or "elseif".
|
||||
|
||||
The 4th parameter contains:
|
||||
|
||||
"error [format STRING....]"
|
||||
|
||||
This lets me modify the previous lower level error by tacking more
|
||||
text onto the end of it. In this case, i want to add the MMR register
|
||||
name to make my error message look better.
|
||||
|
||||
---------
|
||||
Back to something inside show_mmr32_reg{}.
|
||||
|
||||
You'll see something 'set fn show_${NAME}_helper' Here I am
|
||||
constructing a 'function name' Then - I look it up to see if it
|
||||
exists. {the function: "proc_exists" does this}
|
||||
|
||||
And - if it does - I call the function.
|
||||
|
||||
In "C" it is alot like using: 'sprintf()' to construct a function name
|
||||
string, then using "dlopen()" and "dlsym()" to look it up - and get a
|
||||
function pointer - and calling the function pointer.
|
||||
|
||||
In this case - I execute a dynamic command. You can do some cool
|
||||
tricks with interpretors.
|
||||
|
||||
----------
|
||||
|
||||
Function: show_mmr32_bits()
|
||||
|
||||
In this case, we use the special TCL command "upvar" which tcl's way
|
||||
of passing things by reference. In this case, we want to reach up into
|
||||
the callers lexical scope and find the array named "NAMES"
|
||||
|
||||
The rest of the function is pretty straight forward.
|
||||
|
||||
First - we figure out the longest name.
|
||||
Then print 4 rows of 8bits - with names.
|
||||
|
||||
|
||||
**************************************************
|
||||
***************************************************
|
||||
=== TCL TOUR ===
|
||||
Open the file: "chips/atmel/at91/usarts.tcl"
|
||||
===============
|
||||
|
||||
First - about the AT91SAM series - all of the usarts
|
||||
are basically identical...
|
||||
|
||||
Second - there can be many of them.
|
||||
|
||||
In this case - I do some more TCL tricks to dynamically
|
||||
create functions out of thin air.
|
||||
|
||||
Some assumptions:
|
||||
|
||||
The "CHIP" file has defined some variables in a proper form.
|
||||
|
||||
ie: AT91C_BASE_US0 - for usart0,
|
||||
AT91C_BASE_US1 - for usart1
|
||||
... And so on ...
|
||||
|
||||
Near the end of the file - look for a large "foreach" loop that
|
||||
looks like this:
|
||||
|
||||
foreach WHO { US0 US1 US2 US3 US4 .... } {
|
||||
|
||||
}
|
||||
|
||||
In this case, I'm trying to figure out what USARTs exist.
|
||||
|
||||
Step 1 - is to determine if the NAME has been defined.
|
||||
ie: Does AT91C_BASE_USx - where X is some number exist?
|
||||
|
||||
The "info exists VARNAME" tells you if the variable exists. Then -
|
||||
inside the IF statement... There is another loop. This loop is the
|
||||
name of various "sub-registers" within the USART.
|
||||
|
||||
Some more trick are played with the [set VAR] backtick evaluation stuff.
|
||||
And we create two variables
|
||||
|
||||
We calculate and create the global variable name for every subregister in the USART.
|
||||
And - declare that variable as GLOBAL so the world can find it.
|
||||
|
||||
Then - we dynamically create a function - based on the register name.
|
||||
|
||||
Look carefully at how that is done. You'll notice the FUNCTION BODY is
|
||||
a string - not something in {braces}. Why? This is because we need TCL
|
||||
to evaluate the contents of that string "*NOW*" - when $vn exists not
|
||||
later, when the function "show_FOO" is invoked.
|
||||
|
||||
Lastly - we build a "str" of commands - and create a single function -
|
||||
with the generated list of commands for the entire USART.
|
||||
|
||||
With that little bit of code - I now have a bunch of functions like:
|
||||
|
||||
show_US0, show_US1, show_US2, .... etc ...
|
||||
|
||||
And show_US0_MR, show_US0_IMR ... etc...
|
||||
|
||||
And - I have this for every USART... without having to create tons of
|
||||
boiler plate yucky code.
|
||||
|
||||
****************************************
|
||||
****************************************
|
||||
END of the Tcl Intro and Walk Through
|
||||
****************************************
|
||||
****************************************
|
||||
|
||||
FUTURE PLANS
|
||||
|
||||
Some "GPIO" functions...
|
||||
|
||||
@endverbatim
|
||||
|
||||
*/
|
||||
Reference in New Issue
Block a user