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:
Lars Rademacher
2013-10-21 00:50:02 +02:00
parent 85fffe007e
commit 83d72a091e
1148 changed files with 571445 additions and 0 deletions

View 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.
*/

View 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
*/

View 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
*/

View 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.
*/

View 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
*/