9.7.1 Debug Scripting
The debug scripting interface is function-based and depends on certain named functions defined in a Python file. The function will then be called when the corresponding event occurs inside Microchip Studio.
Error checking is kept at a minimum for the functions exported into the Python environment, so the time used on initialization during ordinary sessions is kept low, meaning that there are many ways to crash Microchip Studio through this interface.
To load a Python file, place a file named debughooks.py in the Debug folder of your project, next to the ELF file, or one folder up where the project file is. It is also possible to place this file inside the Microchip Studio installation directory to load the script for all projects.
def should_process_breakpoint(studio_interface, breakpoint_address, breakpoint_id, obj): """ Called to determine if a breakpoint should cause Microchip Studio to enter debug mode. If this function returns False, Microchip Studio will not break at the breakpoint. """ return True def has_processed_breakpoint(studio_interface, breakpoint_address, breakpoint_id, obj): """ This function is called if Microchip Studio is breaking at a breakpoint. The GUI is now in halted mode. """ pass def on_reset(studio_interface, reset_address): """ This function is called when the target is reset. The address where the reset went to is 'reset_address'. """ pass def on_eval_expr(studio_interface, expression): """ This function is called for each expression that is evaluated in Microchip Studio. This includes the watch window and other windows that show data from the target. Pass the 'expression' string through to evaluate it, or return another expression to be evaluated to override the expression. This override is not visible in the Microchip Studio GUI. """ return expression
should_process_breakpoint
is
undefined, breakpoints might start to misbehave as the return value of an undefined
function is in itself undefined.The main interface back into the Microchip Studio is the studio_interface
object
is shown in the code above. This object contains some functions to show messages and do
target interaction.
Print
function in the studio_interface
object shows text in
the output window inside Microchip Studio. The function takes two arguments; the string
to print and thethe tab name in the output window. The example below prints all the
evaluated expressions to the Expressionstab.
def on_eval_expr(studio_interface, expression): studio_interface.Print("Evaluating {}".format(expression), "Expressions") return expression
Print
is set to INFO
, meaning that the output
may be masked by Microchip Studio. To lower the threshold, go to , select Status Management, and set the
Display Threshold to INFO.Use the ExecStmt
function in the studio_interface
object to
execute statements in the debugger, which can, for instance, be used to set variables.
See MSDN Debugger.ExecuteStatement Method for more
information.
The WriteMemory
and ReadMemory
are symmetric functions for reading and writing memory on the target. It is important to use a System.Array[System.Byte]
object to pass the data between the script and Microchip Studio.
import System def should_process_breakpoint(studio_interface, breakpoint_address, breakpoint_id, obj): vals = System.Array[System.Byte]([1, 2, 3, 4, 5, 6, 7, 8, 9]) studio_interface.WriteMemory(data=vals, adr=0, type="eeprom") ret = studio_interface.ReadMemory(adr=0, type="eeprom", count=9) studio_interface.Print("ret == vals => {!r}".format(ret == vals), "Python") return True
CalcNumericValue
is a shorthand for the CalcValue
call. It will return the numeric value of the symbol or the provided default value if the function fails to retrieve the value of the symbol. def should_process_breakpoint(studio_interface, breakpoint_address, breakpoint_id, obj): a = studio_interface.CalcNumericValue("a", 0) if a == 0: studio_interface.Print("a was 0 or default", "Value scripts") else: studio_interface.Print("a = {}".format(a), "Value scripts") return True
CalcValue
function is used to retrieve information about a symbol in the
scope where the target code is running. The return value of this call is a list of
information containing the address of the symbol, symbol information, and value. The
objects sent to this list contain all known information about a symbol, but the most
helpful field is the last element, which contains the value of the evaluated symbol.
def should_process_breakpoint(studio_interface, breakpoint_address, breakpoint_id, obj): a = studio_interface.CalcValue("a") # a now contains all information about the variable a. # It is a list with the following members: # a = [ # <Atmel.VsIde.AvrStudio.Services.TargetService.TCF.Services.ValueInfo>, # <Atmel.VsIde.AvrStudio.Services.TargetService.TCF.Services.SymbolInfo>, # <Atmel.VsIde.AvrStudio.Services.TargetService.TCF.Services.ExpressionInfo>, # '1' ] <-- This is the value of the symbol as a string, here it had the value 1 studio_interface.Print("Value of a = {}".format(a[3]), "Value Scripts") return True
CalcValue
call contain objects that are
either internal or documented in the Microchip Studio SDK. Use the python
dir()
command to look at the exported fields.