428 lines
11 KiB
Plaintext
428 lines
11 KiB
Plaintext
; --------------------------------------------------------------------------------
|
|
; @Title: Example for logging variable values
|
|
; @Description:
|
|
; Provides a convenient way for users to log values of a variable
|
|
; to screen or file over time.
|
|
; Timestamps may be added.
|
|
; Provides an example of an ERROR handler and a command event
|
|
; @Keywords: Error handling, event driven PRACTICE, logging, practice. DIALOG.SetFile.SELECT
|
|
; @Author: RIC
|
|
; @Copyright: (C) 1989-2016 Lauterbach GmbH, licensed for use with TRACE32(R) only
|
|
; --------------------------------------------------------------------------------
|
|
; $Id: logging_variables.cmm 17647 2021-04-28 10:45:54Z rweiss $
|
|
|
|
|
|
PMACRO.EXPLICIT
|
|
|
|
; Macro declarations
|
|
; Declare three macros as global so that they are available for the custom command.
|
|
; This command is created later on in the script.
|
|
GLOBAL &AREAname &varname &bpfile
|
|
|
|
; Everything else is declared as PRIVATE
|
|
PRIVATE &filename ×tamp &spot &change &memaccess
|
|
PRIVATE &timeval ×witch &tnum &tbase
|
|
; End Macro declarations
|
|
|
|
;Call sub-routine to see IF E: memory class is supported
|
|
GOSUB CheckMemAccess
|
|
RETURNVALUES &memaccess
|
|
|
|
; Store User's BP
|
|
; Store user's Breakpoints away so we can retrieve them later
|
|
; Get a temporary file from the host OS
|
|
&bpfile=OS.TMPFILE()
|
|
|
|
; We'll need to manually add the ".CMM" extension
|
|
&bpfile="&bpfile"+".cmm"
|
|
|
|
; Store Breakpoints to temporary file
|
|
STOre "&bpfile" Break
|
|
|
|
; Now clear all the existing Breakpoints
|
|
Break.Delete /ALL
|
|
; End Store User's BP
|
|
|
|
|
|
; Since we will be logging stuff to the screen whilst the target
|
|
; is running we need to ensure that the screen is regularly
|
|
; updated/refreshed.
|
|
SCREEN.ALways
|
|
|
|
; This uses the Event Driven mechanism in PRACTICE to create a new temporary command
|
|
; called CLSAV. This will be executed by the "stop logging" button. At that point
|
|
; this block will be executed, which will stop the target, close any files and
|
|
; restore any saved Breakpoints. It will finally close the dialog and quit the script.
|
|
ON CMD CLSAV GOSUB
|
|
(
|
|
; Halt the target and wait until it has finished
|
|
Break
|
|
WAIT !STATE.RUN()
|
|
|
|
; Delete the temporary Breakpoint on the variable
|
|
IF "&spot"=="/ONSPOT"
|
|
Break.Delete Var.RANGE(&varname)
|
|
|
|
; Close the AREA, which will also close any files associated with it
|
|
AREA.CLOSE &AREAname
|
|
|
|
IF DIALOG.BOOLEAN(FL)
|
|
PRINT "File saved"
|
|
|
|
; Close the dialog
|
|
DIALOG.END
|
|
|
|
; Restore any saved Breakpoints
|
|
IF FILE.EXIST("&bpfile")
|
|
DO "&bpfile"
|
|
ENDDO
|
|
|
|
; This should never be reached but is here just in case;-)
|
|
RETURN
|
|
)
|
|
|
|
|
|
; create and open a dialog named "varlogdialog"
|
|
WinPOS ,,,,,,varlogdialog
|
|
WinResist.DIALOG.view
|
|
(&+
|
|
; Add an icon and a header to the dialog
|
|
ICON "[:view]"
|
|
HEADER "Log a Variable"
|
|
|
|
POS 0. 0. 40. 3.
|
|
BOX "Variable Name :"
|
|
POS 2. 1. 28. 1.
|
|
; Use a DEFEDIT to put focus here when the dialog opens
|
|
VAR: DEFEDIT "" ""
|
|
POS 30. 1. 9. 1.
|
|
VNAME: BUTTON "[:symbols]Browse"
|
|
(
|
|
; This command will open a symbol browser window. When the user double-clicks a symbol
|
|
; the selected value is returned to the EDIT box (VAR) above.
|
|
sYmbol.Browse * /Click "DIALOG.Set VAR ""*""" /Delete
|
|
)
|
|
|
|
POS 0. 3. 40. 6.
|
|
BOX "Log to :"
|
|
POS 2. 4. 10. 1.
|
|
SCR: CHECKBOX "To Screen" ""
|
|
POS 2. 5. 10. 1.
|
|
FL: CHECKBOX "To File"
|
|
(
|
|
; Enable or disable other objects depending upon whether the user will write
|
|
; the variable to a file or not.
|
|
IF DIALOG.BOOLEAN(FL)
|
|
(
|
|
DIALOG.Enable FNAME
|
|
DIALOG.Enable BFNAME
|
|
DIALOG.Enable A.A
|
|
DIALOG.Enable A.B
|
|
)
|
|
ELSE
|
|
(
|
|
DIALOG.Disable FNAME
|
|
DIALOG.Disable BFNAME
|
|
DIALOG.Disable A.A
|
|
DIALOG.Disable A.B
|
|
)
|
|
)
|
|
POS 2. 6. 28. 1.
|
|
FNAME: EDIT "" ""
|
|
POS 30. 6. 9. 1.
|
|
BFNAME: BUTTON "[:symbols]Browse"
|
|
(
|
|
; Open a file browse dialog
|
|
DIALOG.SetFile.SELECT FNAME *.*
|
|
; Check if the file exists. If it does give the user the option of over-writing
|
|
; or appending to the file
|
|
LOCAL &fnameexist
|
|
&fnameexist=DIALOG.STRing(FNAME)
|
|
IF OS.FILE("&fnameexist")==TRUE()
|
|
(
|
|
; If the file exists, set the dyntext object to inform the user
|
|
; Then enable the append/overwrite options
|
|
DIALOG.Set FEXST "File Already Exists:"
|
|
DIALOG.Enable A.A
|
|
DIALOG.Enable A.B
|
|
DIALOG.Set A.A "ON"
|
|
)
|
|
ELSE
|
|
(
|
|
DIALOG.Set FEXST ""
|
|
DIALOG.Disable A.A
|
|
DIALOG.Disable A.B
|
|
)
|
|
)
|
|
; Create a Dynamic text object. The text in this control can
|
|
; be changed by the script at runtime.
|
|
POS 2. 7. 18. 1.
|
|
FEXST: DYNTEXT ""
|
|
POS 19. 7. 9. 1.
|
|
A.A: CHOOSEBOX "Append" ""
|
|
POS 29. 7. 10. 1.
|
|
A.B: CHOOSEBOX "Overwrite" ""
|
|
|
|
POS 0. 9. 40. 5.
|
|
BOX "Options :"
|
|
POS 2. 10. 11. 1.
|
|
TS: CHECKBOX "Timestamped" ""
|
|
POS 2. 11. 11. 1.
|
|
I.POLL: CHOOSEBOX "periodically"
|
|
(
|
|
; Enable or disable other controls based upon the user's selection here
|
|
IF DIALOG.BOOLEAN(I.POLL)
|
|
(
|
|
DIALOG.Enable TMVAL
|
|
DIALOG.Enable TMBASE
|
|
)
|
|
ELSE
|
|
(
|
|
DIALOG.Disable TMVAL
|
|
DIALOG.Disable TMBASE
|
|
)
|
|
)
|
|
POS 14. 11. 5. 1.
|
|
TMVAL: EDIT "" ""
|
|
POS 19. 11. 5. 1.
|
|
TMBASE: PULLDOWN "us,ms,s" ""
|
|
|
|
POS 26. 11. 12. 1.
|
|
I.BRK: CHOOSEBOX "On Writes" ""
|
|
POS 2. 12. 15. 1.
|
|
CHAN: CHECKBOX "Log only changes" ""
|
|
|
|
POS 23. 14. 15. 1.
|
|
OKA: BUTTON "[:stop]Stop Logging..."
|
|
(
|
|
; This is a new command which was defined earlier in the script.
|
|
; It allows the script to keep running and use the command as an event driven
|
|
; mechanism to stop the logging.
|
|
CLSAV
|
|
)
|
|
POS 2. 14. 15. 1.
|
|
OKB: BUTTON "[:Go]Start Logging..."
|
|
(
|
|
; Get the value of the variable
|
|
PRIVATE &tmpstr
|
|
&tmpstr=DIALOG.STRing(VAR)
|
|
|
|
; If no variable has been entered, let the user know
|
|
IF "&tmpstr"==""
|
|
(
|
|
DIALOG.OK "Please enter a variable name before continuing"
|
|
)
|
|
ELSE IF !sYmbol.EXIST("&tmpstr")
|
|
(
|
|
; Check to see if the symbol is valid
|
|
; If not, let the user know.
|
|
DIALOG.OK "The symbol (&tmpstr) does not exist." "Please try again"
|
|
; Clear out the broken symbol
|
|
DIALOG.SET VAR ""
|
|
)
|
|
ELSE
|
|
(
|
|
; check to see if it is a variable and not somethign else
|
|
IF sYmbol.TYPE("&tmpstr")!=0x03
|
|
(
|
|
DIALOG.OK "Selected symbol (&tmpstr) is not a variable." "Please enter a valid variable."
|
|
)
|
|
ELSE
|
|
(
|
|
; If we get here, we have a valid symbol that is a variable
|
|
; Now we can continue with the rest of the script
|
|
DIALOG.Disable OKB
|
|
DIALOG.Enable OKA
|
|
CONTinue
|
|
)
|
|
)
|
|
)
|
|
)
|
|
|
|
|
|
; Initial setup for the controls on the dialog.
|
|
|
|
DIALOG.Set A.B
|
|
DIALOG.Set I.BRK
|
|
DIALOG.Set SCR
|
|
DIALOG.Set TMVAL "100."
|
|
DIALOG.Disable FNAME
|
|
DIALOG.Disable BFNAME
|
|
DIALOG.Disable A.A
|
|
DIALOG.Disable A.B
|
|
DIALOG.Disable OKA
|
|
|
|
IF &memaccess
|
|
(
|
|
DIALOG.Disable TMVAL
|
|
DIALOG.Disable TMBASE
|
|
)
|
|
ELSE
|
|
(
|
|
DIALOG.Disable I.POLL
|
|
DIALOG.Disable TMVAL
|
|
DIALOG.Disable TMBASE
|
|
)
|
|
|
|
; This STOP forces the dialog to be modal.
|
|
STOP
|
|
|
|
; The script will continue from here when the user clicks the "start logging" button
|
|
|
|
; If the target is running we'll need to halt it to set any Breakpoints, etc.
|
|
IF STATE.RUN()
|
|
(
|
|
Break
|
|
WAIT !STATE.RUN()
|
|
)
|
|
|
|
; Set some initial values for the command options
|
|
&varname=DIALOG.STRing(VAR)
|
|
&spot=""
|
|
&timeval=""
|
|
×witch=""
|
|
|
|
; Polling will only be supported where the target provides the E: memory class
|
|
; If polling is not available, the script will use a SPOT Breakpoint to
|
|
; temporarily halt the target, update the log and then restart the target.
|
|
IF DIALOG.BOOLEAN(I.POLL)
|
|
(
|
|
&tnum=DIALOG.STRing(TMVAL)
|
|
&tbase=DIALOG.STRing(TMBASE)
|
|
×witch="/ONTIME"
|
|
&timeval=&tnum&tbase
|
|
)
|
|
ELSE
|
|
(
|
|
&timeval=""
|
|
IF DIALOG.BOOLEAN(I.BRK)
|
|
(
|
|
&spot="/ONSPOT"
|
|
Break.Set Var.RANGE(&varname) /Write /Spot
|
|
)
|
|
ELSE
|
|
(
|
|
&spot=""
|
|
)
|
|
)
|
|
|
|
; If the user has requested timestamps, set the option to provide this
|
|
IF DIALOG.BOOLEAN(TS)
|
|
(
|
|
×tamp="/TIMESTAMP"
|
|
)
|
|
ELSE
|
|
(
|
|
×tamp=""
|
|
)
|
|
|
|
|
|
; Create a user defined AREA window with 500 lines of scrollback.
|
|
; The 'To Screen' results will be displayed here
|
|
&AREAname="ricolog"
|
|
AREA.Create &AREAname ,500
|
|
|
|
IF DIALOG.BOOLEAN(FL)
|
|
(
|
|
; If the user has chosen to log to a file, work out whether they wish
|
|
; to create a new file or append to an existing one.
|
|
; Then open the AREA file with the correct parameter.
|
|
&filename=DIALOG.STRing(FNAME)
|
|
IF DIALOG.BOOLEAN(A.A)
|
|
AREA.OPEN &AREAname &filename /APPEND
|
|
ELSE
|
|
AREA.OPEN &AREAname &filename /CREATE
|
|
)
|
|
|
|
IF DIALOG.BOOLEAN(CHAN)
|
|
(
|
|
&change="/CHANGES"
|
|
)
|
|
ELSE
|
|
(
|
|
&change=""
|
|
)
|
|
|
|
; Open the new AREA window
|
|
WinPOS ,,,,,,logvar1 n
|
|
AREA.view &AREAname
|
|
|
|
; Print the command to be executed to the top of the AREA window
|
|
; This will also go to the file if the user has selected to log to a file.
|
|
PRINT "Var.LOG &varname /AREA &AREAname &spot ×tamp ×witch &timeval &change"
|
|
|
|
; Also log the current time and date.
|
|
PRINT CLOCK.DATE()
|
|
PRINT CLOCK.TIME()
|
|
|
|
; Issue the final version of the Var.LOG command
|
|
; The full version will be built up from all of the options that the user has
|
|
; selected via the DIALOG.
|
|
Var.LOG &varname /AREA &AREAname &spot ×tamp ×witch &timeval &change
|
|
|
|
; Start the target running to start logging.
|
|
Go
|
|
|
|
|
|
; This stop is here so that the defined command stays in the TRACE32 stack.
|
|
; It also prevents the script from completing
|
|
STOP
|
|
|
|
; This should never be reached but is here just in case;-)
|
|
ENDDO
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
; Subroutines
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
|
|
; sub routine CheckMemAccess
|
|
;
|
|
; Parameters: None
|
|
; Returns: &memaccess to determine whether E: memory class is
|
|
; available or not
|
|
;
|
|
; Determine whther or not the E: memory class is supported.
|
|
CheckMemAccess:
|
|
(
|
|
PRIVATE &memaccess
|
|
&memaccess=FALSE()
|
|
; Try the easy method first.
|
|
IF VERSION.BUILD()>72159.
|
|
(
|
|
; Create an error handler. This one will just ignore any errors and allow the script to keep running
|
|
ON ERROR CONTinue
|
|
|
|
; Clear any pending error results
|
|
ERROR.RESet
|
|
|
|
; Try to enable the DUALPORT memory option
|
|
SYStem.Option DUALPORT ON
|
|
; print something to clear the message line in case an error occured
|
|
PRINT ""
|
|
; Check IF the commannd failed
|
|
IF ERROR.OCCURRED()
|
|
(
|
|
; IF the command failed, assume we have no DUALPORT memory acess to the target.
|
|
IF ERROR.ID()=="##cbf_invcomm"
|
|
&memaccess=FALSE()
|
|
)
|
|
ELSE
|
|
(
|
|
; Command didn't fail so we have DUALPORT access
|
|
&memaccess=TRUE()
|
|
)
|
|
; Clear the error handler
|
|
ON ERROR inherit
|
|
|
|
)
|
|
ELSE
|
|
(
|
|
;For now, inform user they need a newer version and quit
|
|
DIALOG.OK "Please upgrade to TRACE32 version 72159 or later."
|
|
ENDDO
|
|
)
|
|
RETURN "&memaccess"
|
|
) |