Training Practice
Training Practice
TRACE32 Directory
TRACE32 Index
E-Learning ................................................................................................................................... 4
Version 16-Apr-2019
E-Learning
Ready-to-Run Scripts
Ready-to-run PRACTICE scripts provided by the Lauterbach experts are published and updated daily here:
http://www.lauterbach.com/scripts.html
Area of Use
ChDir.DO <filename> Change to the directory where the script <filename> is located
and start the script.
DO <filename> Start script <filename>.
PATH [+] <path_name> Define search paths for PRACTICE scripts.
DO memtest
ChDir.DO c:/t32/demo/powerpc/hardware
PATH c:/t32/tests
The commands STOre and ClipSTOre generate scripts that allow to reactivate the specified TRACE32
<setting> at any time.
<setting>
ClipSTOre SYStem
SYSTEM.RESET
SYSTEM.CPU SPC56EC74
SYSTEM.CONFIG CORENUMBER 2.
SYSTEM.CONFIG CORE 1. 1.
CORE.ASSIGN 1.
SYSTEM.MEMACCESS NEXUS
SYSTEM.CPUACCESS DENIED
SYSTEM.OPTION IMASKASM OFF
SYSTEM.OPTION IMASKHLL OFF
SYSTEM.BDMCLOCK 4000000.
SYSTEM.CONFIG TRISTATE OFF
SYSTEM.CONFIG SLAVE OFF
SYSTEM.CONFIG TAPSTATE 7.
SYSTEM.CONFIG TCKLEVEL 0.
SYSTEM.CONFIG.DEBUGPORT Analyzer0
SYSTEM.CONFIG CJTAGFLAGS 0x3
SYSTEM.MODE UP
ClipSTOre Break
Break.RESet
Break.Set func24 /Program
Break.Set main\38 /Program
Break.Set sieve /Program /Onchip /COUNT 1000.
Var.Break.Set mstatic1; /Write
TOOLBAR ON
STATUSBAR ON
FramePOS 15.625 8.9286 193. 47.
WinPAGE.RESet
WinPAGE.Create P000
WinCLEAR
WinPAGE.select P000
ENDDO
The LOG command allows users to create a record of most of the activities in the TRACE32 PowerView
GUI.
LOG.OPEN <file> Create and open a file for the command LOG. The default extension
for LOG files is (.log).
LOG.CLOSE Close the command LOG file.
LOG.OFF Switch off command LOG temporarily.
LOG.ON Switch on command LOG.
LOG.type Display command LOG while recording.
… // Recording
B::B::List
B::Go func24
// B::LOG.ON
B::B::PER , "Analog to Digital Converter"
B::B::PER.Set.simple ANC:0xFFE00000 %L (d.l(ANC:0xFFE00000)&~0x40000000)|0x40000000
The command history records only commands entered into the command line.
The default extension for HISTory-files is (.log)
AutoSTOre , HISTory
which automatically saves the command history in your temporary directory when you exit TRACE32 and
recalls the command history when you start TRACE32 again.
ChDir.PEDIT <filename> Change to the directory where the script <filename> is located and
open script in script editor PEDIT.
PEDIT <filename> Open script <filename> in script editor PEDIT.
In TRACE32, the PRACTICE script editor PEDIT provides syntax highlighting, configurable auto-indentation,
multiple undo and redo.
In addition to, or as an alternative to the built-in PRACTICE script editor PEDIT, you can work with an
external editor. To configure syntax highlighting for PRACTICE scripts in an external editor, take these steps:
1. Redirect the call of the TRACE32 editor EDIT to an external editor by using the TRACE32
command SETUP.EDITEXT.
2. Install the syntax highlighting files provided by Lauterbach for the external editor.
Lauterbach provides syntax highlighting files for some common text editors. Please refer to
~~/demo/practice/syntaxhighlighting for details. ~~ stands for the
<trace32_installation_directory>, which is c:/T32 by default.
A short video that provides an introduction into PRACTICE debugging is available on:
http://www.lauterbach.com/tut_practice.html
PRACTICE debug-pull-down
Goto Till Run PRACTICE script until the selected line (command CONTinue
<line_number>).
Edit Here Open PRACTICE editor to edit the PRACTICE script. The cursor is
automatically set to the selected line.
The PRACTICE stack displays the program nesting and the PRACTICE macros.
So far, we have seen that simple scripts can be created that can restore various settings to the current
debug session. PRACTICE provides a lot more capability than this; it is a fully featured language with its own
syntax and advanced features. This section will cover the language syntax, program elements, features and
functions. Examples of PRACTICE scripts can be found in ~~/demo/practice or at
http://www.lauterbach.com/scripts.html
Program Elements
Comments
Comments start with // or ; and end with the next line break.
Since the TRACE32 hll expression grammar allows ; to end an hll expression, ; has a special meaning for
the Var command group. Here a few examples.
Var.View flags[3];ast.count;i
Commands
There are three types of commands that can be used in PRACTICE scripts:
• All TRACE32 commands which are also used interactively in the command line
• I/O commands
Functions
Functions are used to retrieve information about the state of the target system or the state of the
development tool(s).
Labels
Labels have to be entered in the first column and they end with “:”. For more information on labels please
refer to the section on subroutines.
&i=7.
Command List
// Script double_if.cmm
WHILE TRUE()
(
READ #1 &testfunc &correct_result
IF "&testfunc"!=""
(
IF Var.VALUE(&testfunc)==&correct_result
(
APPEND "test_protocol.txt"\
FORMAT.STRing("&testfunc=&correct_result",50.,' ')\
FORMAT.UnixTime("c",DATE.UnixTime(),DATE.utcOffSet())
)
ELSE
(
PRIVATE &result
&result=CONVert.HEXTOINT(Var.VALUE(&testfunc))
APPEND "test_protocol.txt"\
FORMAT.STRing("&testfunc failed with &result (&correct_result)",50.,' ')\
FORMAT.UnixTime("c",DATE.UnixTime(),DATE.utcOffSet())
)
)
ELSE
(
CLOSE #1
ENDDO
)
)
ENDDO
To better understand the scope of PRACTICE macros given later in this training, it is important to know how
TRACE32 maintains information on the PRACTICE stack.
TRACE32 adds a new block-frame to the PRACTICE stack, whenever instructions are blocked by round
brackets.
; Var.IF example
Var.IF (flags[0]==flags[5])
PRINT "Values are equal."
ELSE
PRINT "Values do not match."
ENDDO
;Example 1
;Print the character X 100 times
AREA.view
RePeaT 100. PRINT "X"
;Example 2
Var.Break.Set flags /Write //Set a Write breakpoint to array
//flags
Command List
<label>
(
<block>
RETURN Execute <block> and RETURN to caller.
)
NOTE: Labels must start in the first column of a line and end with a colon. No
preceding white space allowed.
// Script test_func_param.cmm
WHILE TRUE()
(
READ #1 &testfunc &correct_result
IF "&testfunc"!=""
(
GOSUB perform_test
)
ELSE
(
CLOSE #1
ENDDO
)
)
ENDDO
perform_test:
(
IF Var.VALUE(&testfunc)==&correct_result
(
APPEND test_protocol.txt\
FORMAT.STRing("&testfunc=&correct_result",50.,' ')\
FORMAT.UnixTime("c",DATE.UnixTime(),DATE.utcOffSet())
)
ELSE
(
PRIVATE &result
&result=CONVert.HEXTOINT(Var.VALUE(&testfunc))
APPEND test_protocol.txt\
FORMAT.STRing("&testfunc failed with &result (&correct_result)",50.,' ')\
FORMAT.UnixTime("c",DATE.UnixTime(),DATE.utcOffSet())
)
RETURN
)
Command List
// Script test_sequence.cmm
DO target_setup.cmm
DO check_boot.cmm
ENDDO
terminate_script:
(
DIALOG.OK "Script terminated by test failure"
ENDDO
)
// Script check_boot.cmm
Go main
IF STATE.RUN()
(
Break.direct
)
IF Register(PC)==ADDRESS.OFFSET(main)
(
APPEND test_protocol.txt FORMAT.STRing("System booted successfully",70.,' ') \
FORMAT.UnixTime("c",DATE.UnixTime(),DATE.utcOffSet())
)
ELSE
(
APPEND test_protocol.txt FORMAT.STRing("Booting failed",70.,' ') \
FORMAT.UnixTime("c",DATE.UnixTime(),DATE.utcOffSet())
JUMPTO terminate_script
)
DIALOG.OK <text> Create a dialog that provides a <text>-message to the user. The script
execution is stopped until the user pushes the OK button in the dialog.
Command List
Example
// Script test_sequence.cmm
DO target_setup.cmm
DO check_boot.cmm
ENDDO
terminate_script:
(
DIALOG.OK "Script terminated by test failure"
ENDDO
)
TRACE32 adds a new do-frame to the PRACTICE stack whenever a script is started
Macros are the variables of the script language PRACTICE. They work as placeholders for a sequence of
characters.
Macro names in PRACTICE always start with an ampersand sign (‘&’), followed by a sequence of letters (a-
z, A-Z), numbers (0-9) and the underscore sign (’_’). The first character after the & sign must not be a
number. Macro names are case sensitive, so &a is different from &A.
Declare a Macro
Empty PRACTICE macros can be declared along with their scope by using one of the following PRACTICE
commands:
They are visible in nested blocks, but not in called subroutines and
called scripts.
LOCAL {<macro>} Create LOCAL macros.
GLOBAL macros are visible to all scripts, subroutines and blocks until
they are explicitly removed by the command PMACRO.RESet. They
can only be removed if no script is running.
// Script test_func_param.cmm
WHILE TRUE()
(
READ #1 &testfunc &correct_result
IF "&testfunc"!=""
(
GOSUB perform_test
)
ELSE
(
CLOSE #1
ENDDO
)
)
ENDDO
perform_test:
(
IF Var.VALUE(&testfunc)==&correct_result
(
APPEND "test_protocol.txt"\
FORMAT.STRing("&testfunc=&correct_result",50.,' ')\
FORMAT.UnixTime("c",DATE.UnixTime(),DATE.utcOffSet())
)
ELSE
(
PRIVATE &result
&result=CONVert.HEXTOINT(Var.VALUE(&testfunc))
APPEND "test_protocol.txt"\
FORMAT.STRing("&testfunc failed with &result (&correct_result)",50.,' ')\
FORMAT.UnixTime("c",DATE.UnixTime(),DATE.utcOffSet())
)
RETURN
)
The PRACTICE interpreter will implicitly declare a new LOCAL macro when an assignment is done and
cannot find a macro of that name in the current scope.
The command PMACRO.EXPLICIT advises the PRACTICE interpreter to generate an error if a PRACTICE
macro is used in an assignment, but was not declared in advance. It also advises the PRACTICE interpreter
to generate an error if the same macro was intentionally created a second time within its scope.
// Script
// Assign a string
&my_string="Hello World"
&my_range="0x40004000++0xfff"
&my_var=Var.STRing(cstr1)
// Assign a numbers
&my_number=100.
&my_float=5.667e13
&my_var_value=Var.VALUE(ast.count)
&my_expression=&my_number*&my_var_value
// Assign a boolean
&my_boolean=TRUE()
&my_boolean_result=STATE.RUN()
ENDDO
After a content is assigned to a macro, tooltips allows to inspect its current content.
To better understand the usage of macros, it is the best to look at the way the PRACTICE interpreter
executes a script line.
The PRACTICE interpreter executes a script line by line. Each line is (conceptually) processed in three
steps:
PRINT {<data>} PRINT specified <data> to TRACE32 message line and to TRACE32
message area.
Example 1
PRIVATE &a
&a="5+4"
PRINT &a
We look at the PRINT &a line. To execute this line, the interpreter will first:
PRIVATE &a
&a="Hello World"
PRINT &a
Let’s look at the three steps the interpreter will take to execute the PRINT &a command:
2. Evaluate expressions
PRINT Hello World -> error
3. Execute command, which will not happen because of the error in the second step.
The second step fails because in PRACTICE a single word like Hello (which is not enclosed in double
quotes) refers to a debug symbol, loaded, for example, from an ELF file.
When the PRACTICE interpreter encounters such a debug symbol, the expression evaluation will try to
replace the debug symbol by the address to which the symbol refers. If there is no debug symbol called
Hello (which is likely), the PRACTICE interpreter will output the error message symbol not found.
If by pure accident there are debug symbols called Hello and World the addresses of these symbols will
be printed.
This example demonstrates how the pure macro replacement step will basically always work, since you
always can replace a macro by its character sequence; but the result might not make sense.
Macros are replaced by their character sequence. If you want to explicitly use this character sequence as a
string, then you should enclose the macro in double quotes, for example:
PRIVATE &a
&a="Hello World"
PRINT "&a"
To understand what happens it is again best to look at the three steps which are taken to execute the
PRINT "&a" command.
2. Evaluate expressions.
Nothing to do for this example.
3. Execute command.
// Script string_example.cmm
// PRINT command
PRINT "Directory " "&drive" "\T32_" "&architecture" "\demo"
PRINT "Directory "+"&drive"+"\T32_"+"&architecture"+"\demo"
PRINT "Directory &(drive)\T32_&(architecture)\demo"
// Macro assignment
&demo_directory="&drive"+"\T32_"+"&architecture"+"\demo"
DIR &demo_directory
&demo_directory="&(drive)\T32_&(architecture)\demo"
DIR &demo_directory
// Command parameter
DIR "&(drive)\T32_&(architecture)\demo"
DIR <directory> Display a list of files and folders for the specified directory.
// Script numbers.cmm
&convert1=CONVERT.HEXTOINT(&my_bin)
&convert2=CONVERT.HEXTOINT(&my_hex)
…
The PRACTICE stack shows the macro values and their radix.
// Script append_example.cmm
PRIVATE &target_id
&target_id="D:0x40004000"
DEL "my_append.txt"
//...
TRACE32 command
TRACE32 functions
CABLE.SERIAL() Returns the first serial number of the plugged debug cable.
VERSION.BUILD() Returns build number of TRACE32 software as a decimal number.
// Script append_example_format.cmm
PRIVATE &target_id
&target_id="D:0x40004000"
DEL "my_append.txt"
TRACE32 function
PRACTICE macros are not available in the command line. They are only available when running a script.
But you can proceed as follows to test a macro assignment:
For all complex data structures TRACE32-internal variables can be used. The following two commands can
be used to declare a TRACE32-internal variable.
TRACE32-internal variables require that a program is loaded via the Data.LOAD command. All data types
provided by this program can then be used (sYmbol.List.Type).
• TRACE32-internal variables have the same scope as PRACTICE macros (e.g. they are on the
PRACTICE stack).
• TRACE32-internal variables are displayed and modified via the Var command group.
; script newlocal.cmm
LOCAL &my_symbol
ENTRY &my_symbol
&n=sYmbol.TYPE(&my_symbol)
Var.PRINT %String \typeresult[&n]
ENDDO
Var.Assign %<format> <variable> Modify variable, no log is generated in the message line or in the
AREA window.
Task of part 1 of the script: Start the target program execution and wait until the program execution is
stopped at the entry of the function main.
// Script run_through_code.cmm
// Part 1
// Prepare debugging
DO "target_setup.cmm"
Go main
WAIT !STATE.RUN() 2.s
IF STATE.RUN()
(
Break
)
…
TRACE32 commands
TRACE32 function
// Part 2
…
IF Register(PC)==ADDRESS.OFFSET(main)
(
APPEND "test_protocol.txt" FORMAT.STRing("System booted successfully",70.,' ')\
FORMAT.UnixTime("c",DATE.UnixTime(),0)
)
ELSE
(
APPEND "test_protocol.txt" FORMAT.STRing("Booting failed",70.,' ')\
FORMAT.UnixTime("c",DATE.UnixTime(),0)
ENDDO
)
The backslash \ in conjunction with at least one space serves as a line continuation character.
TRACE32 function
Addresses in TRACE32
ADDRESS.OFFSET(main)
• An access class (here P:) which consists of one or more letters/numbers followed by a colon (:)
PRINT ADDRESS.OFFSET(main)
PRACTICE commands:
TRACE32 functions:
// Prepare debugging
DO "target_setup.cmm"
Go main
IF STATE.RUN()
(
Break.direct
)
IF Register(PC)==ADDRESS.OFFSET(main)
(
APPEND "test_protocol.txt" FORMAT.STRing("System booted successfully",70.,' ')\
FORMAT.UnixTime("c",DATE.UnixTime(),DATE.utcOffSet())
)
ELSE
(
APPEND "test_protocol.txt" FORMAT.STRing("Booting failed",70.,' ')\
FORMAT.UnixTime("c",DATE.UnixTime(),DATE.utcOffSet())
ENDDO
)
…
Task of the script: After an appropriate program address e.g. main is reached, you can check if certain
memory addresses are initialized with their correct value.
// Script check_memory_locations.cmm
…
IF Data.Long(D:0x40004058)!=0x0
(
APPEND "test_protocol.txt"\
FORMAT.STRing("Initialization of address D:0x40004058 failed",70.,' ')\
FORMAT.UnixTime("c",DATE.UnixTime(),DATE.utcOffSet())
)
IF Data.Long(ANC:0xC3FDC0C4)!=0x0
(
APPEND "test_protocol.txt"\
FORMAT.STRing("Initialization of Global Status Register failed",70.,' ')\
FORMAT.UnixTime("c",DATE.UnixTime(),DATE.utcOffSet())
)
…
TRACE32 function
Data.Long(<address>) Returns the contents of the specified address as a 32-bit hex. value.
Task of the script: After an appropriate program address e.g. main is reached, you can check if a certain
memory range is initialized with their correct values. An easy way to provide the correct values is a binary
file.
// Script check_memory_range.cmm
…
Data.LOAD.Binary "range_correct" 0x40004000 /DIFF
IF FOUND()
(
PRIVATE &s
APPEND "test_protocol.txt"\
FORMAT.STRing("Initialization of 0x40004000--0x4000401F failed ",70.,' ')\
FORMAT.UnixTime("c",DATE.UnixTime(),DATE.utcOffSet())
&s=TRACK.ADDRESS()
APPEND "test_protocol.txt"\
FORMAT.STRing("First difference found at: &s",70.,' ')
)
…
TRACE32 command
TRACE32 functions
PRACTICE macros start with & to make them different from variables
from the program under debug.
Private PRACTICE macros are only visible inside the declaring block
and are erased when the block ends.
// Script check_memory_range_details.cmm
TRACE32 commands
PRACTICE commands
If PRACTICE scripts are executed, the screen is only updated after a PRINT command.
Task of the script: After an appropriate program address e.g. main is reached, you can check if certain
variables are initialized with their correct value.
// Script check_var.cmm
…
Var.IF stra2[1][0].pastruct5[0]!=0.
(
APPEND "test_protocol.txt"\
FORMAT.STRing("Initialization of stra2[1][0].pastruct5[0] failed",70.,' ')\
FORMAT.UnixTime("c",DATE.UnixTime(),DATE.utcOffSet())
PRACTICE command
PRACTICE function
Task of script: Write the content of various variables to a file. Use the same formatting as Var.View
command.
// Script record_var.cmm
…
PRinTer.FileType ASCIIE
PRinTer.OPEN "test_var.lst"
WinPos ,,,,,0
WinPrint.Var.View %String cstr1
WinPos ,,,,,0
WinPrint.Var.View %Open str2
WinPos ,,,,,0
WinPrint.Var.View vfloat
PRinTer.CLOSE
…
TRACE32 commands
Task of the script: Write the contents of the variable vbfield to a file whenever the program execution stops
at the specified breakpoint. Use CSV as output format.
// Script test_var_vbfield.cmm
…
Break.RESet
Var.Break.Set vbfield /Write
REPEAT 10.
(
Go
WAIT !STATE.RUN() 2.s
IF STATE.RUN()
(
Break
ENDDO
)
Var.EXPORT "vbfield_export.csv" vbfield /Append
)
…
PRACTICE command
// Use expression of your programming language (C, C++, …) to specify write breakpoint
Var.Break.Set <hll_expression> /Write
// Since the number of write breakpoints is limited, it is recommended to reset the current breakpoint
// settings
Break.RESet
// Append content of variables as CSV (Comma Separated Values) to file <filename>
Var.EXPORT <filename> [{%<format>}] {<variable>} /Append
;Example 2
RePeaT 50. ;Print a * at the end of
( ;the previous line then
PRINT %CONTinue "*" ;wait 100 ms. Do this 50
WAIT 100.ms ;times.
)
;Example 3
LOCAL &code
AREA.Create A000 , 2100. ;Change the number of
AREA.view A000 ;lines in the AREA window
;to 2100
OPEN #1 "~~/t32.men" /Read
RePeaT ;Read until the end of
( ;file
READ #1 %LINE &code
PRINT "&code"
)
WHILE EOF()==FALSE()
CLOSE #1
Task of the script: Test functions with specified parameters and generate a test protocol.
// Script test_function.cmm
...
PRIVATE &result
&result=FORMAT.Decimal(8.,Var.VALUE(func5(2,6,9)))
APPEND "test_protocol.txt" \
FORMAT.STRing("func5(2,6,9) tested with result &result",70.,' ') \
FORMAT.UnixTime("c",DATE.UnixTime(),DATE.utcOffSet())
&result=FORMAT.Decimal(8.,Var.VALUE(func5(14,87,93)))
APPEND "test_protocol.txt" \
FORMAT.STRing("func5(14,87,93) tested with result &result",70.,' ') \
FORMAT.UnixTime("c",DATE.UnixTime(),DATE.utcOffSet())
&result=FORMAT.Decimal(8.,Var.VALUE(func5(44,44,44)))
APPEND "test_protocol.txt" \
FORMAT.STRing("func5(44,44,44) tested with result &result",70.,' ') \
FORMAT.UnixTime("c",DATE.UnixTime(),DATE.utcOffSet())
...
PRACTICE function
Task of script: Test functions, but provide function name, parameters and expected result by a parameter
file. Generate a test protocol.
// Script test_func_param.cmm
WHILE TRUE()
(
READ #1 &testfunc &correct_result
IF "&testfunc"!=""
(
GOSUB perform_test
)
ELSE
(
CLOSE #1
ENDDO
)
)
ENDDO
perform_test:
(
IF Var.VALUE(&testfunc)==&correct_result
(
APPEND "test_protocol.txt"\
FORMAT.STRing("&testfunc=&correct_result",50.,' ')\
FORMAT.UnixTime("c",DATE.UnixTime(),DATE.utcOffSet())
)
ELSE
(
PRIVATE &result
&result=CONVert.HEXTOINT(Var.VALUE(&testfunc))
APPEND "test_protocol.txt"\
FORMAT.STRing("&testfunc failed with &result (&correct_result)",50.,' ')\
FORMAT.UnixTime("c",DATE.UnixTime(),DATE.utcOffSet())
)
RETURN
)
func5(22,12,17) 56.
func5(14,87,93) 8105.
func5(44,44,44) 1980.
PRACTICE command
GOSUB <label> Call a subroutine. The start of the subroutine is identified by <label>.
Labels must start in the first column of a line and end with a colon. No
preceding white space allowed.
Local PRACTICE macros are visible inside the declaring block, in all
called scripts and in all called subroutines.
They are erased when the declaring block ends. The declaring block
here is the script itself.
WHILE <condition> Execute <block> as long as <condition> is true.
(
<block>
)
OPEN #<buffer_number> <filename> /Read Open file <filename> for reading. The file is
referenced by its #<buffer_number> by the
following commands.
READ #<buffer_number> {<macro>} Read next line from file referenced by
#<buffer_number> into PRACTICE macros.
TRACE32 function
ENTRY <parlist>
IF "&address_range"==""
(
PRINT "Address range parameter is missing"
ENDDO
)
IF "&data_old"==""
(
PRINT "Old data parameter is missing"
ENDDO
)
IF "&data_new"==""
(
PRINT "New data parameter is missing"
ENDDO
)
IF FOUND()
(
Data.Set TRACK.ADDRESS() &data_new
Data.Print TRACK.ADDRESS()
DIALOG.OK "Patch done"
)
ELSE
DIALOG.OK "Patch failed"
ENDDO
Example 2: Pass parameters to a subroutine and get back the return value
Pass parameter to subroutine
test:
ENTRY &address_range &data
Data.Find &address_range &data
&result=ADDRESS.OFFSET(TRACK.ADDRESS())
RETURN &result
test:
ENTRY %LINE &values
Data.Find &values
&result=ADDRESS.OFFSET(TRACK.ADDRESS())
RETURN &result
Alternatively, the function PARAMETERS can be used to read parameters passed to a script or subroutine
and, if the macros do not already exist in the current scope, assign them to automatically created PRIVATE
macros. The parameters must be enclosed in quotation marks (").
Example 4: Pass arguments using PARAMETERS to a subroutine and get back the return value
Pass parameters to subroutine
test:
PARAMETERS &address_range &data
Data.Find &address_range &data
&result=ADDRESS.OFFSET(TRACK.ADDRESS())
RETURN &result
IF "&data_old"==""
(
&data_old=0x00
)
IF "&data_new"==""
(
&data_new=0xFF
)
IF FOUND()
(
Data.Set TRACK.ADDRESS() &data_new
Data.Print TRACK.ADDRESS()
DIALOG.OK "Patch Done"
)
ELSE
(
DIALOG.OK "Patch Failed."
)
ENDDO
Passing parameters into scripts like this means that the user must know the order in which each parameter
must be specified. A more flexible approach is to use the function STRing.SCANAndExtract().
;Extract the arguments into the correct PRACTICE variables, returning the
;default value if the user does not specify something.
&addr=STRing.SCANAndExtract(STRING.UPpeR("&p"), "ADDRESS=", "0x12000")
&dvalue=STRing.SCANAndExtract(STRING.UPpeR("&p"),"DATA=", "0x00")
&count=STRing.SCANAndExtract(STRING.UPpeR("&p"),"COUNT=","5.")
print_args:
PRINT "Usage:"
PRINT
PRINT "do arg_test.cmm ADDRESS=<addr> DATA=<data> COUNT=<count>"
PRINT "Where:"
PRINT " <addr> is the address to write <data> to."
PRINT " <count> is the number of times to write the <data> value."
PRINT
PRINT "Script will complete using default values."
PRINT
RETURN
PRIVATE &result
AREA.view
AREA.CLEAR
DATA.LOAD.BINARY checksum.bin 0x40000000
IF &result
PRINT %COLOR.GREEN "First checksum verification passed"
ELSE
PRINT %COLOR.RED "First checksum verification failed"
WAIT 1.s
; Modify memory
Data.Set 0x40000100 %Long 0x12345678
IF &result
PRINT %COLOR.GREEN "Second checksum verification passed"
ELSE
PRINT %COLOR.RED "Second checksum verification failed"
ENDDO
verify_checksum:
(
PRIVATE &result
PARAMETERS &expected_checksum &address_range
PRIVATE macros that are out scope are printed in gray in the PRACTICE stack.
PRACTICE command
PRINT %COLOR.<color> {<data>} Print the specified data in the specified color to the
TRACE32 message area.
TRACE32 function
Using the PRACTICE commands PARAMETERS/RETURNVALUES solve the following issues known for
the ENTRY command.
// Script entry_issue1.cmm
AREA.view
AREA.CLEAR
LOCAL &x
&x=0x25
ENDDO
level1:
(
ENTRY &x
RETURN
)
AREA.view
AREA.CLEAR
LOCAL &x
&x=0x25
ENDDO
level1:
(
PARAMETERS &x
RETURN
)
Notice that the LOCAL macros of the caller(s) are out of scope for the PARAMETERS command. So
a new PRIVATE macro &x is created.
The ENTRY command regards whitespace as a parameter delimiter. If one of the parameters for the
called script/subroutine is a string containing whitespaces and it is not quoted, the script is stopped by
an error, because not enough macros are provided to take all parameters.
// Script entry_issue2.cmm
ENDDO
level1:
(
PRIVATE &r &s &t
ENTRY &r &s &t
RETURN
)
If the string containing whitespaces is quoted, the quotes become part of the string if the ENTRY
command is used.
// Script entry_issue3.cmm
ENDDO
level1:
(
PRIVATE &r &s &t
ENTRY &r &s &t
&r=&r // Removes quotes from string
RETURN
)
// Script entry_issue3_params.cmm
ENDDO
level1:
(
PARAMETERS &r &s &t
RETURN
)
PRACTICE can interact with the Operating System on the host computer. A well written PRACTICE script
can hide the differences in underlying Operating System and present a unified experience to the user.
Sometimes differences in the underlying host Operating System require the PRACTICE script to be a bit
more flexible in order to be truly portable. The function OS.VERSION(0) can be used to detect the host
Operating System.
;Printout host OS
IF OS.VERSION(0)>=0x50
PRINT "Unkown OS"
ELSE IF OS.VERSION(0)>=0x40
PRINT "Mac OS X"
ELSE IF OS.VERSION(0)>=0x30
PRINT "HP-UX"
ELSE IF OS.VERSION(0)>=0x20
PRINT "Solaris"
ELSE IF OS.VERSION(0)>=0x10
PRINT "Linux"
ELSE
PRINT "MS Windows"
ENDDO
Results can be sent to the system clipboard, a file or a connected printer. Physical printers must be
configured correctly in the TRACE32 configuration file (usually ~~/config.t32), although Windows users
will not need to do anything here.
To print results:
1. Select a printer using PRinTer.select (for manual selection via GUI), PRinTer.FILE or
PRinTer.ClipBoard.
3. Open a connection to the printer with PRinTer.OPEN. Use PRinTer.EXPORT to generate CSV
data.
4. Re-direct the output from the command to the chosen printer using WinPrint.<command>
For a more detailed explanation of the commands and options, refer to “PRinTer” in PowerView Command
Reference, page 222 (ide_ref.pdf).
PRinTer.FILE "&file"
PRinTer.FileType ASCIIE
WinPrint.Data.dump 0x2200--0x22FF
&file="&file"+".lst"
; Display the results
TYPE "&file"
ENDDO
PRinTer.EXPORT.default "&file"
&file="&file"+".lst"
TYPE "&file"
&file=STRing.Replace("&file","-1.lst","-2.lst",0)
TYPE "&file"
ENDDO
; Close the file, set the format to ASCIIE, then re-open the
; file to append new data
PRinTer.CLOSE
PRinTer.FileType ASCIIE
PRinTer.OPEN "&file" /Append
PRinTer.CLOSE
&file="&file"+".lst"
TYPE "&file"
ENDDO
Environment variables can be accessed from a PRACTICE script by using the function
OS.ENV("<env_var>"). The value of the variable is returned and can be assigned to a PRACTICE macro.
A more extensive example which will run on Windows, Linux or MacOS can be found at
~~/demo/practice/my_environment.cmm.
The OS.* family of commands can be used to launch programs on the host Operating System from within a
PRACTICE scripts. A brief overview is given here but more information can be found at “OS” in PowerView
Command Reference, page 204 (ide_ref.pdf).
OS.Area <command_line> Execute a command on the host. The results will be displayed
in the AREA window. the script will block until the command
has completed.
OS.Command <command_line> Execute multiple commands on the host (use host native
piping). PRACTICE macros can be inserted into the
command line. On Windows hosts, the first argument must be
the command interpreter (CMD.EXE). On Windows hosts the
PRACTICE script does not block. On other hosts use ’&’ to
force non-blocking behavior.
OS.Hidden <command_line> Execute a command; the output is discarded. PRACTICE
script blocks until the command completes.
OS.screen <command_line> Open a host shell and execute the command line. This is non-
blocking.
OS.Window <command_line> Execute a host command and all output will be re-directed to a
new TRACE32 window. This is non-interactive and the
PRACTICE script blocks until the command has completed.
A PRACTICE script can manipulate files in the host Operating System file system (display, copy, delete,
etc.). A number of commands are available and it is recommended to use these instead of the underlying
Operating Systems’ native commands to make scripts more portable. More information can be found at
“File and Folder Operations” in PowerView User’s Guide, page 79 (ide_user.pdf).
In addition, PRACTICE supports 9 file handles (#1 through #9) that are used to open, close, read and write
files.
• Open file
• Close file
CLOSE #<buffer>
DIALOG.view
(
HEADER "Write Test"
POS 0. 0. 30. 4.
BOX "Please Enter your details"
POS 1. 1. 10. 1.
TEXT "First name:"
POS 1. 2. 10. 1.
TEXT "Last name:"
POS 12. 1. 17. 1.
F: DEFEDIT "" ""
POS 12. 2. 17. 1.
S: EDIT "" ""
POS 24. 4. 6. 1.
DEFBUTTON "OK" "CONTinue"
)
STOP
&fname=DIALOG.STRING(F)
&sname=DIALOG.STRING(S)
DIALOG.END
&file=OS.TMPFILE()
OPEN #1 "&file" /CREATE
; Write first line
WRITE #1 "File saved for &fname &sname"
&file=OS.TMPFILE()
OPEN #2 "&file" /Binary /Create
WRITEB #2 0x48 0x65 0x6C 0x6C 0x6F
WRITEB #2 0x20 0x57 0x6F 0x72 0x6C 0x64
CLOSE #2
TYPE &file
ENDDO
OPEN #1 "&tfile"
; Read first two lines and throw them away
; These are the header and column titles
READ #1 %LINE &line
READ #1 %LINE &line
WHILE !FILE.EOF(1)
(
READ #1 %LINE &line
IF "&line"!=""
(
; Extract only the task name part of the line
&tmpline=STRing.MID("&line",10.,16.)
&tasklist="&tasklist"+"&tmpline"+","
)
)
CLOSE #1
DIALOG.view
(
HEADER "FreeRTOS Task List"
POS 0. 1. 25. 10.
TSK: LISTBOX "" ""
POS 12. 12. 10. 1.
DEFBUTTON "Close" "CONTinue"
)
DIALOG.Set TSK "" "&tasklist"
STOP
DIALOG.END
ENDDO
The date and time can be retrieved using the DATE.DATE() and DATE.TIME() functions respectively. More
information about date and time functions can be found at “DATE Functions” in PowerView Function
Reference, page 27 (ide_func.pdf).
AREA.view
PRINT DATE.DATE()
PRINT DATE.TIME()
ENDDO
These can be used to add timestamps to reports or log files or to include the time and date in log file names.
TYPE "logdir/&logfile"
ENDDO
Output Command
Input Command
ENTRY &result
IF &result
(
PRINT "Test started"
DO test2
)
ELSE
PRINT "Test aborted"
ENDDO
DIALOG.File *sre
ENTRY &filename
Data.LOAD.S3record &filename
ENDDO
An I/O window is needed for PRACTICE inputs and outputs. This ia handled by an AREA window.
AREA.Create [<area> ]
AREA.Select [<area>]
3. Select the screen position of the AREA window. This command is used here, because it allows
you to assign a name to an AREA window. This is useful, if you want to delete this window after
the I/O procedure.
AREA.view [<area>]
1. Resets the AREA window settings to the default settings: the message area (AREA A000) is
used for error and system messages. No other AREA window is active.
AREA.RESet
AREA.Create IO-AREA
AREA.Select IO-AREA
WinPOS ,,,,,, IO1
AREA.view IO-AREA
WAIT 2.s
AREA.RESet
WinCLEAR IO1
ENDDO
…
ON ERROR GOTO
(
DIALOG.OK "Abortion by error!"
ENDDO (0!=0)
)
…
IF !(STATE.POWER())
STOP
startup:
SYStem.CPU TC1796
WAIT 0.5s
SYStem.UP
ENDDO
TRACE32 provides a number of simple dialogs which can be used to inform the user of something or to
prompt them to make a simple choice.
Text can be split across multiple lines in these simple dialogs. The list below shows the methods of achieving
this.
DIALOG.OK "Hello"+CONVert.CHAR(0x0D)+"World!"
DIALOG.OK "Hello"+CONVert.CHAR(0x0A)+"World!"
DIALOG.OK "Hello"+CONVert.CHAR(0x0A0D)+"World!"
Three of these use the CONVert.CHAR() function to insert carriage return (0x0D, '\r') and/or line feed
(0x0A, '\n') characters into the string. The fourth version simply presents two strings and TRACE32 will
put one per line.
Complex dialogs can be created in PRACTICE scripts. These allow users to develop custom interfaces for
their scripts. Dialogs can be created in one of two ways. The first requires putting the dialog code into a
separate file with a .dlg extension and calling it with the DIALOG.view command.
DIALOG.view <filename> Creates a dialog based upon the code in the dialog file,
<filename>.
; File basicdialog.dlg
POS 1. 1. 10.
TEXT "A Basic Dialog"
; File dialogscript.cmm
DIALOG.view basicdialog.dlg
SCREEN.WAIT //update screen
WAIT 3.s
DIALOG.END
ENDDO
The second method includes the dialog code within the script itself.
DIALOG.view
(
POS 1. 1. 10.
TEXT "A Basic Dialog"
)
SCREEN.WAIT //update screen
WAIT 3.s
DIALOG.END
ENDDO
Both examples produce the same result. Dialogs automatically size themselves to encompass all of the
controls placed within it.
By using the PRACTICE command STOP in this example, the dialog becomes modal. The script will
wait until the user (or the script) continues execution. This CONTinue comes when the command
associated with the BUTTON control is executed. This is activated when the user clicks the button.
Adding the prefix WinResist will cause the dialog to remain displayed after a call to WinCLEAR.
Multiple command prefixes can be applied to each dialog.
WinRESIZE [<width>] [<height>] [<windowname>] Resizes the open window that has the
name <windowname>. If no name is
specified, the top most window is resized.
A <windowname> can be created with the
WinPOS or NAME commands.
WinExt.DIALOG
(
HEADER "Hidden Option"
POS 0. 0. 20. 4.
BOX ""
POS 1. 1. 15. 1.
TEXT "Please select an option"
POS 1. 2. 8. 1.
A.A: CHOOSEBOX "Option A" ""
POS 9. 2. 8. 1.
A.B: CHOOSEBOX "Option B" ""
POS 22. 2. 8. 1.
A.C: CHOOSEBOX "Option C" ""
POS 5. 4. 7. 1.
BUTTON "Options>>"
(
WinRESIZE 32. 5.
)
POS 22. 4. 8. 1.
BUTTON "<<Options"
(
WinRESIZE 20. 5.
)
)
;Set dialog’s initial size
WinRESIZE 20. 5.
STOP
DIALOG.END
ENDDO
Control Positioning
Control placement starts at (0, 0) which is the top left of the dialog. The default size is 9 units wide and 1 unit
high. After a control is placed the next position is calculated by advancing the Y co-ordinate by one and
keeping the same X co-ordinate. The size defaults to the same size as the last placed control. To override
the size and position of the next control to be placed, use the POS command.
POS [<x>] [<y>] [<width>] [<height>] Defines the size and position of the next control to be
placed on a dialog window.
, The value of the previous POS argument is used. In the example here
the previous value for the <width> is preserved.
; <x> <y> <width> <height>
POS 3. 7. , 2.
<no_argument> The value of the previous POS argument is used, starting from right to
left. In the example below, the values for <width> and <height> will be
taken from the previous POS command.
; <x> <y> <width> <height>
POS 3. 7.
The examples above have a period "." after the numbers in the arguments to POS. This instructs TRACE32
to treat these as decimal numbers.
DIALOG.view
(
POS 1. 1. 5. 1.
BUTTON "Hello and Welcome!" ""
POS 1. 3. 15. 1.
BUTTON "Hello and Welcome!" ""
POS 10. 5. 6. 1.
BUTTON "Close" "CONTinue"
)
STOP
DIALOG.END
ENDDO
Some dialog controls must be associated with a PRACTICE label. This provides some extra capabilities:
• The PRACTICE script can extract user input or control state information via the label.
• The PRACTICE script can set a value into the control by using the label.
• If a control has a command block associated with it, this can be executed.
DIALOG
(
POS 1. 1. 10. 1.
CB1: CHECKBOX "Enable"
(
IF DIALOG.BOOLEAN(CB1)
DIALOG.Enable T1
ELSE
DIALOG.Disable T1
)
POS 1. 2. 10. 1.
T1: EDIT "" ""
)
;Set starting state for controls after the DIALOG command but before
;the STOP.
DIALOG.DISABLE T1
STOP
ENDDO
A B
A When the dialog opens the CHECKBOX is enabled and the EDIT control is not.
Information from a control is made available to the PRACTICE script through the label associated with that
control. The method of extraction is to use the DIALOG.STRing() function.
LOCAL &userInput
DIALOG.view
(
POS 1. 1. 10. 1.
TXT: EDIT "" ""
POS 1. 2. 10. 1.
BUTTON "OK" "CONTinue"
)
STOP
&userInput=DIALOG.STRing(TXT)
AREA.view
PRINT "User entered: &userInput"
ENDDO
check_item:
ENTRY &newitem
&newitem=&newitem ;Remove any extra quotes
IF "&toppings"=="" ;Is this the first item to be added to the list
&toppings="&newitem"
ELSE
&toppings="&toppings"+","+"&newitem"
DIALOG.Set TOP "" "&toppings"
RETURN
Controls that can be associated with a label can be set or have data entered into them using the
DIALOG.Set command.
DIALOG.Set <label> <value> Set the <value> to the control associated with <label>.
DIALOG.view
(
POS 1. 1. 5. 1.
T1: DYNTEXT "Hello"
POS 1. 2. 15. 1.
C1: CHECKBOX "Checkbox" ""
POS 10. 5. 6. 1.
BUTTON "Toggle"
(
IF DIALOG.BOOLEAN(C1)
(
DIALOG.Set T1 "Hello"
DIALOG.Set C1 FALSE()
)
ELSE
(
DIALOG.Set T1 "World"
DIALOG.Set C1 TRUE()
)
)
)
DIALOG.Disable C1
STOP
DIALOG.END
ENDDO
It is possible to execute the command or block associated with any other control. This is done using the
DIALOG.EXecute command.
DIALOG.view
(
POS 1. 1. 10. 1.
T1: DYNTEXT "Placeholder"
POS 1. 2. 10. 1.
T2: DYNTEXT "Placeholder"
POS 15. 1. 9. 1.
B1: BUTTON "Set Text 1"
(
DIALOG.Set T1 "Hello"
)
POS 15. 3. 9. 1.
B2: BUTTON "Set Text 2"
(
DIALOG.Set T2 "World"
)
POS 15. 5. 9. 1.
B3: BUTTON "Set both"
(
DIALOG.EXecute B1
DIALOG.EXecute B2
)
)
STOP
DIALOG.END
ENDDO
PRACTICE provides several commands for file and directory browsing. There are two broad categories:
those that return a value like a subroutine and those that can set the returned value to a label.
LOCAL &filename
DIALOG.File.open *.cmm
ENTRY %LINE &filename ;Use ENTRY to obtain result from
;DIALOG.FILE. Added %LINE option in
;case the filename had spaces in it.
PRINT "&filename selected."
The above example also uses the OS.FILE.NAME() and OS.FILE.PATH() functions to extract the file name
and file path respectively.
LOCAL &fname
DIALOG.view
(
POS 1. 1. 25. 1.
FILE: EDIT "" ""
POS 30. 1. 5. 1.
B: BUTTON "..." "DIALOG.SetFile FILE *"
POS 30. 3. 5. 1
BUTTON "OK" "CONTinue"
)
STOP
&fname=DIALOG.STRing(FILE)
DIALOG.END
PRINT "File - &fname"
ENDDO
The DIALOG.SetFile command has been attached to the BUTTON. Commands can be attached to some
controls. If the command is a single line it can be enclosed in quotes ("). If the command is more complex it
can be a PRACTICE block (enclosed in parentheses).
TRACE32 has a number of built-in icons which can be used in dialog or menu programming. These are
added by using the syntax [:<icon_name>] in the text part of a control.
DIALOG.view
(
POS 1. 1. 8. 1.
BUTTON "[:profile]Profile" ""
)
STOP
ENDDO
A list of internal icons can be displayed. Select the icon and the name is displayed.
A complete list of dialog controls can be found in “PowerView Command Reference” (ide_ref.pdf). In this
section we will examine a few of them in the context of a complex example. The full version of this script can
be found in ~~/demo/practice/dialogs/dialog_example_generic.cmm
First, declare some local macros to be used in the script. Some of them are given default values. Some lines
have been split using the "\" character to make the script more readable here. Some assignments, like
&instr are made using multiple assignments to build up a longer value.
&expand=0.
&progress=0.
Display the dialog. The characters "&+" after the opening parenthesis allow for runtime macro substitution
into the dialog controls. The code below will create a header and add a text line and edit field to the dialog.
DIALOG.view
(&+
HEADER "Dialog Example"
POS 1. 0. 20. 1.
TEXT "Please enter your name:"
POS 22. 0. 24. 1.
MYNAME: DEFEDIT "" ""
The next few lines add a box and a group of radio buttons (CHOOSEBOXes) into the box pane. Each
CHOOSEBOX is part of the same group. The label name takes the form <group>.<member> and TRACE32
ensures that only one member of each group can be selected at any one time. Each CHOOSEBOX has a
command associated with it which will be executed when the user selects that control.
POS 1. 1. 20. 5.
BOX "Options"
POS 2. 2. 15. 1.
O.BOND: CHOOSEBOX "James Bond"
(&-
IF "&bondsel"==""
DIALOG.Set SEL "" "&bond"
ELSE
DIALOG.Set SEL "&bondsel" "&bond"
)
O.BMAN: CHOOSEBOX "Batman"
(&-
IF "&batmansel"==""
DIALOG.Set SEL "" "&batman"
ELSE
DIALOG.Set SEL "&batmansel" "&batman"
)
O.CAPN: CHOOSEBOX "Star Trek"
(&-
IF "&captainsel"==""
DIALOG.Set SEL "" "&captain"
ELSE
DIALOG.Set SEL "&captainsel" "&captain"
)
Here is the code that draws the list and initially populates it with the &bond list. When an item in the list is
double-clicked by the user the command is executed and, again, macro substitution is temporarily disabled.
The current member of the CHOOSEBOX group is determined and the macro for the selection from that
group is updated. Then one of the CHECKBOXes is checked to indicate that a selection for that group has
been made. A macro containing the percentage completion is updated and this is used to update the
progress bar. Once progress exceed 99% the OK button on the dialog is enabled, using DIALOG.Enable.
This excerpt draws a box with three CHECKBOXes and a progress bar in it. The CHECKBOX controls will
be disabled and only updated via the script to prevent un-wanted user interaction.
POS 1. 6. 45. 3.
BOX "Selection made"
POS 2. 7. 12. 1.
B_SEL: CHECKBOX "Bond Selected" ""
POS 18. 7. 12. 1.
BM_SEL: CHECKBOX "Batman Selected" ""
POS 32. 7. 12. 1.
C_SEL: CHECKBOX "Captain Selected" ""
POS 1. 9. 45. 3.
BOX "Progress"
POS 2. 10. 43. 1.
PBAR: BAR
POS 1. 12. 1. 1.
TB1: TREEBUTTON ""
(&-
IF &expand==0
(
WinRESIZE 48. 18.
&expand=1
DIALOG.Set TB1 "ON"
)
ELSE
(
WinRESIZE 48. 13.
&expand=0
DIALOG.Set TB1 "OFF"
)
This code adds a TEXTBUTTON next to the TREEBUTTON providing the user with a larger area to click.
The TEXTBUTTON uses DIALOG.EXecute to execute the command of the TREEBUTTON.
This code draws a button with the text “OK” and which will execute the command CONTinue when clicked
by the user. It then creates an INFOTEXT control which will display the text stored in macro &instr. The
other options to INFOTEXT configure the border style, font and background color. The closing parenthesis
indicates the end of the dialog controls.
DIALOG.Set O.BOND
DIALOG.Disable B_SEL
DIALOG.Disable BM_SEL
DIALOG.Disable C_SEL
WinRESIZE 48. 13.
DIALOG.Disable BOK
STOP
The user’s name is extracted from the EDIT control and a message box is displayed showing their choices.
When the user closes the message box (DIALOG.OK), the dialog itself will be closed and the script will
terminate.
&myname=DIALOG.STRing(MYNAME)
DIALOG.OK "Thanks &myname. Your selections were:" "" "Favorite James Bond
is &bondsel" \
"Favorite Batman is &batmansel" "Favorite Captain is &captainsel"
DIALOG.END
ENDDO
PRACTICE scripts need some modification to function effectively in a modern multicore debug environment.
This section contains advice and guidance on how to achieve this. Where the target is configured for
Symmetric Multi-Processing (SMP), a single instance of TRACE32 PowerView is used to control all cores. In
this case many PRACTICE commands add an option /CORE <n> option to indicate that the command
should be run with reference to a particular core or cores. This section will focus now on Asymmetric Multi-
Processing (AMP) systems where multiple instances of TRACE PowerView are used to control
heterogenous cores.
For simple multicore debug sessions it may be sufficient to have one instance of TRACE32 PowerView
configure the main core and then launch a second instance which would attach to and configure the other
debug session. Such a system might look like the examples below.
ENDDO
Some systems require a more flexible approach, especially where communication between instances of
PowerView is required.
TRACE32 PowerView implements a communication system called INTERCOM which allows instances to
communicate with each other via UDP. More information about this can be found at “InterCom” in
PowerView Command Reference, page 152 (ide_ref.pdf). This requires a small modification to the
configuration file (normally ~~/config.t32) file to enable. A modified file is shown below with the
changes highlighted.
PBI=
USB
CORE=1
IC=NETASSIST
PORT=20001
The PORT= indicates that this instance of TRACE32 PowerView will listen for incoming requests on this UDP
port. The ports must be unique.
A separate configuration file is needed for each instance of TRACE32 with a unique CORE= and PORT=
identifier. Alternatively, a single generic configuration file may be used and the values passed in via the
command line, for example:
IC=NETASSIST
PORT=${1}
PBI=
${2}
CORE=${3}
${4}
Start with:
ENDDO
The main script can wait until the other instances are available by using the InterCom.WAIT command. The
example above would be extended like this.
INTERCOM.WAIT localhost:20002
INTERCOM.WAIT localhost:20003
ENDDO
Now that all instances are synchronised, commands can be issued to each instance. This can be done
using the InterCom.execute command and can be wrapped in a PRACTICE macro to make the script more
readable.
; Using INTERCOM.execute
SYStem.CPU e200z6
INTERCOM.execute localhost:20002 SYStem.CPU e200z6
INTERCOM.execute localhost:20003 SYStem.CPU e200z2
; Using a macro
LOCAL &core2 &core3
&core2="INTERCOM.execute localhost:20002"
&core3="INTERCOM.execute localhost:20003"
SYStem.CPU e200z6
&core2 SYStem.CPU e200z6
&core3 SYStem.CPU e200z2
A script may run on the PC of the person who developed it but it may not run as well (or at all) on the PC of a
colleague or a customer. This section will help you to design PRACTICE scripts that will be more robust and
more portable.
There are several things to take into consideration when designing a robust PRACTICE script.
Scripts should avoid hard coding any paths; users will likely have their own PCs set out to their own tastes.
Network drives may also be mapped to different letters.
This example will only work if the ELF file is located in the current working directory.
; This will only work if the ELF file is located in the current directory
Data.LOAD.Elf "myprog.elf"
This example will work only if the ELF file is located in this path. It will not work on a colleague’s PC who has
stored the project in C:\users\barry\Project_1\.
PRIVATE &pwd
&PWD=OS.PresentWorkingDirectory()
ChDir "C:\users\rico\Project_1\out"
Data.LOAD.Elf "myprog.elf"
ChDir "&pwd"
An alternative approach would use relative directory paths. TRACE32 provides a number of functions or
built-in path prefixes. For example:
Users could always be presented with a file chooser to browse for the ELF file to be loaded.
Data.LOAD.Elf "*.elf"
The script could be called with the top level directory for the project as an argument.
A better version would be to check if the file exists and prompt the user to browse for it if it is not where
expected.
A complete list of all path prefixes is provided in “Path Prefixes” in PowerView User’s Guide, page 49
(ide_user.pdf).
There will be differences between host Operating Systems. Scripts should be written in such a way as to
remove the impact of these differences from the user.
If a script uses a forward slash ("/") in a path name, TRACE32 will automatically use the correct slash for the
underlying host Operating System.
Use the TRACE32 built-in commands for file system manipulation. These will automatically be resolved to
the correct commands for the host Operating System. A full list of these commands an be found in See “File
and Folder Operations” in PowerView User’s Guide, page 79 (ide_user.pdf) but include:
The built-in macro "~~" which resolves to the TRACE32 system directory can be used to overcome
differences in host Operating Systems.
• Windows uses CR + LF
LOCAL &text
OPEN #1 "~~~~/log.txt"
READ #2 %LINE &text
WHILE !EOF()
(
PRINT "&text"
READ #2 %LINE &text
)
CLOSE #2
When TRACE32 writes a file, it uses the correct end of line sequence for the current host Operating System.
Scripts can be made to write portable files by using this trick.
The function OS.VERSION(0) can be used to determine the host operating system. Using this allows scripts
to adapt to underlying fundamental differences. An example can be found on page RICO.
Debug Hardware
A script may need to adapt depending upon the debug hardware that is used. Some scripts may not be
appropriate for certain hardware. The script should check and then inform the user before quitting. A number
of functions exist for TRACE32 hardware detection and more information can be found in “General
Function Reference” (general_func.pdf). A few are listed below. Each returns TRUE if the relevant
hardware is detected.
• AUTOFOCUS()
• hardware.COMBIPROBE()
• hardware.POWERDEBUG()
• hardware.POWERTRACE2()
• INTERFACE.SIM()
IF !AUTOFOCUS()
(
DIALOG.OK "Autofocus pre-processor required." \
"Please connect correct hardware." \
"Press ’OK’ to exit the script."
ENDDO
)
;Rest of the script goes here
The function CPUFAMILY() will return the name of the family. Any core which can be debugged with the
same t32m* executable is part of the family. Each family will have its own set of unique functions.
IF CPUFAMILY()=="ARM"
(
IF CABLE.TWOWIRE()
SYStem.CONFIG SWD
)
The function CPU() will return the value of the processor selected by the user in the SYStem.state window.
LOCAL &device
SYStem.RESet
SYStem.CPU ARM7TDMI // Default CPU
SYStem.DETECT IDCode
&device=IDCODE(0)&0x0fffffff
Some CPUs do not support byte addressable memory; the smallest addressable unit may be 16, 24 or 32
bits. The script below provides a means of determining this value.
LOCAL &width
TRACE32 Version
A script should never assume which TRACE32 PowerView features are available to it; it always a good idea
to check. The two main functions for this are:
IF VERSION.BUILD()<56572.
(
DIALOG.OK "This script requires TRACE32 build greater than 56572."
ENDDO
)
TRACE32 Settings
TRACE32 is highly customizable and a script should make no assumptions about how a user has their
software configured.
Scripts should not assume a default radix as this is a CONTinue option and users will set it according to their
own preference.
A script should always enforce the radix that it wishes to use to avoid such confusion.
LOCAL &var
&var=0x42+23.
PRINT "The result is 0x"+FORMAT.HEX(0,&var)
LOCAL &var
&var=0x42+23.
PRINT "The result is 0x" %Hex &var
If a script intends to make use of breakpoints or will open more than a single window, it may be a good idea
to store the users’ current settings and then restore them after the script has completed its work This can be
done using the STOre command.
WinCLEAR
ENDDO
An alternative approach would be to determine the local screen resolution and open a pre-configured
set of windows which match the current screen size. An example of how to do this has been provided in
~~/demo/practice/screen_size.cmm which attempts to extract the screen resolution from the
; Call the script which will return the values for screen width and
; screen height
DO ~~/demo/practice/screen_size.cmm
RETURNVALUES &scrw &scrh
; This handy little trick for PRACTICE will convert the ’string’ macro
; into a ’numerical’ macro so it can be used in a test
&scrw="&(scrw)"
IF &scrw<1280.
(
PRINT "Loading Small screen layout."
; Here, either call a script with windows optimized for a
; small screen or GOSUB to a routine which will open the correct window
; layout
)
ELSE
(
PRINT "Loading Large screen layout."
; Call correct script or GOSUB to routine which opens windows for a
; higher resolution screen.
)
ENDDO
If a PRACTICE script encounters an error it will halt at the line that produced the error. Using the command
SETUP.WARNSTOP it is possible to also configure a PRACTICE script to halt on a command that merely
produces a warning. More advanced error handling can be used in scripts so that they can recover more
gracefully should something fail. This relies on the event driven features of PRACTICE and in it’s simplest
form looks like the example here. The script will keep running even though an error will be produced.
The call to ON ERROR inherit will restore the previous error handler; error handlers may be stacked. A
better error handler might look like this.
IF VERSION.BUILD()<72159.
(
DIALOG.OK "Your version of TRACE32 is too old to run this script."
ENDDO
)
ON ERROR GOSUB
RETURN
ENDDO
Designing a script to be re-useable requires that some thought is given to checking argument values passed
in by the user. The script cannot assume that the arguments it gets will always be correct. Using
STRing.SCANAndExtract() can ensure that argument order does not matter but does not enforce the
contents of an argument. PRACTICE macros can always be treated as strings and something like the
IsNum sub-routine below can check that a macro only contains a numerical value in either decimal or hex
format.
ENDDO
IsNum:
PARAMETERS &txt
LOCAL &ret &len &i &char
&ret=TRUE()
&len=STRing.LENgth("&txt")
IF STRing.ComPare(STRing.LoWeR("&txt"),"0x*")==TRUE()
(
; Possibly a hex number
&i=2.
)
ELSE
(
; Assume a decimal number
&i=0.
)
RePeaT (&len-&i)
(
&char=STRing.MID(STRing.LoWeR("&txt"),&i,1)
IF STRing.FIND("0123456789.","&char")==FALSE()
&ret=FALSE()
&i=&i+1
)
RETURN "&ret"
It is possible to create a custom command in TRACE32. This is done by using the command GLOBALON .
The command <name> is created but is restricted to a maximum of 9 characters. In the example script
below, call it without arguments to register the command, call it with a single argument of "REMOVE" to
remove the command.
IF "&test"==""
(
; No arguments so register the command
; Command name is limited to 9 characters
LOCAL &this_script
&this_script=OS.PresentPracticeFile()
GLOBALON CoMmanD TESTRUN DO "&this_script"
)
ELSE IF "&test"=="REMOVE"
(
; Use this to remove the global command
GLOBALON CoMmanD TESTRUN
)
ELSE
(
RePeaT &count
(
GOSUB &test "&testfile"
)
)
ENDDO
test1:
PARAMETERS &tf
PRINT "Running test1 with data file (&tf)"
RETURN
test2:
PARAMETERS &tf
PRINT "Running test2 with data file (&tf)"
RETURN
Common Pitfalls
This final section focuses on some of the common mistakes that can be made in PRACTICE scripts.
Try not to use blocking commands unless you are debugging your script. Commands like STOP and ENTER
will stop the script from executing but will give the user no indication that the script has halted or is awaiting
further input. It is a better idea to use a dialog instead.
Watch for white space. It is required after an IF or WHILE command but should not appear in expressions.
; INCORRECT example
IF(&i<5.)
; CORRECT examples
IF (&i<5.)
IF &i<5.
; INCORRECT expression
&x = ( 5. + 8. * 2 ) / ( 3 + &i )
; CORRECT expression
&x=(5.+8.*2.)/(3/+&i)
; INCORRECT example
Data.LOAD.Elf STRing.TRIM("&dir")+"/myprog.elf"
; CORRECT example
&dir=STRing.TRIM("&dir")
Data.LOAD.Elf "&dir/myprog.elf"
Always use the correct declaration of PRACTICE macros. Review the difference between LOCAL and
PRIVATE.
Always assume that the default radix is not what you require. Force your macros to the correct radix. For
example, use 0x10 or 16. but never 10 on it’s own.
Use the built-in commands for TRACE32 directories instead of hard coding paths to scripts or files.
Use TRACE32 built-in commands for host OS file manipulation (copy, change directory, delte, etc.). This
makes the script portable across different host Operating Systems.