; -------------------------------------------------------------------------------- ; @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" )