]> git.sur5r.net Git - openocd/commitdiff
Move TCL overview from source tree to doxygen manual.
authorzwelch <zwelch@b42882b7-edfa-0310-969c-e2dbd0fdcd60>
Wed, 20 May 2009 08:48:19 +0000 (08:48 +0000)
committerzwelch <zwelch@b42882b7-edfa-0310-969c-e2dbd0fdcd60>
Wed, 20 May 2009 08:48:19 +0000 (08:48 +0000)
git-svn-id: svn://svn.berlios.de/openocd/trunk@1855 b42882b7-edfa-0310-969c-e2dbd0fdcd60

doc/manual/primer/tcl.txt [new file with mode: 0644]
src/tcl/README_ABOUT_TCL.txt [deleted file]

diff --git a/doc/manual/primer/tcl.txt b/doc/manual/primer/tcl.txt
new file mode 100644 (file)
index 0000000..f2c3d05
--- /dev/null
@@ -0,0 +1,438 @@
+/** @page primertcl OpenOCD TCL Primer
+
+@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
+
+ */
diff --git a/src/tcl/README_ABOUT_TCL.txt b/src/tcl/README_ABOUT_TCL.txt
deleted file mode 100644 (file)
index 233c5dd..0000000
+++ /dev/null
@@ -1,430 +0,0 @@
-****************************************
-****************************************
-
-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...