#!/usr/bin/python # -*- coding: latin-1 -*- # -------------------------------------------------------------------------------- # @Title: An exmple to show how to initiate the types T32_RegisterHandle, # T32_SymbolHandle and T32_AddressHandle and how to call the obj functions # @Description: # TRACE32 Remote API sample program written in Python, illustrating # the use of the types T32_RegisterHandle, T32_SymbolHandle and T32_AddressHandle # and the obj functions # # TRACE32's configuration file "config.t32" has to contain these lines: # RCL=NETASSIST # PORT=20000 # The port value may be changed but has to match with the port number # used in this python script. # # @Keywords: python # @Author: WBA # @Copyright: (C) 1989-2021 Lauterbach GmbH, licensed for use with TRACE32(R) only # -------------------------------------------------------------------------------- # $Id: objfunctions.py $ # import platform import ctypes # auto-detect the correct library if (platform.system() == "Windows") or (platform.system()[0:6] == "CYGWIN"): if ctypes.sizeof(ctypes.c_voidp) == 4: # WINDOWS 32bit t32api = ctypes.CDLL("./t32api.dll") # alternative using windows DLL search order: # t32api = ctypes.cdll.t32api else: # WINDOWS 64bit t32api = ctypes.CDLL("./t32api64.dll") # alternative using windows DLL search order: # t32api = ctypes.cdll.t32api64 elif platform.system() == "Darwin": # Mac OS X t32api = ctypes.CDLL("./t32api.dylib") else: if ctypes.sizeof(ctypes.c_voidp) == 4: # Linux 32bit t32api = ctypes.CDLL("./t32api.so") else: # Linux 64bit t32api = ctypes.CDLL("./t32api64.so") def check_error(error): """Raises a ValueError if error is not zero.""" if error != 0: raise ValueError(f"{error}") # declare the argument- and return-types of the functions used in this file t32api.T32_Config.argtypes = [ctypes.POINTER(ctypes.c_char)] t32api.T32_Config.restype = ctypes.c_int t32api.T32_Init.argtypes = [] t32api.T32_Init.restype = ctypes.c_int t32api.T32_Attach.argtypes = [ctypes.c_int] t32api.T32_Attach.restype = ctypes.c_int t32api.T32_Ping.argtypes = [] t32api.T32_Ping.restype = ctypes.c_int t32api.T32_RequestSymbolObjName.argtypes = [ctypes.POINTER(ctypes.c_void_p), ctypes.POINTER(ctypes.c_char)] t32api.T32_RequestSymbolObjName.restype = ctypes.c_int t32api.T32_QuerySymbolObj.argtypes = [ctypes.c_void_p] t32api.T32_QuerySymbolObj.restype = ctypes.c_int t32api.T32_GetSymbolObjAddress.argtypes = [ctypes.c_void_p, ctypes.POINTER(ctypes.c_void_p)] t32api.T32_GetSymbolObjAddress.restype = ctypes.c_int t32api.T32_GetAddressObjAddr64.argtypes = [ctypes.POINTER(ctypes.c_void_p)] t32api.T32_GetAddressObjAddr64.restype = ctypes.c_int t32api.T32_ReleaseAllObjects.argtypes = [] t32api.T32_ReleaseAllObjects.restype = ctypes.c_int t32api.T32_RequestRegisterObjR32Name.argtypes = [ctypes.POINTER(ctypes.c_void_p), ctypes.POINTER(ctypes.c_char)] t32api.T32_RequestRegisterObjR32Name.restype = ctypes.c_int t32api.T32_ReadRegisterObj.argtypes = [ctypes.c_void_p] t32api.T32_ReadRegisterObj.restype = ctypes.c_int t32api.T32_GetRegisterObjValue32.argtypes = [ctypes.c_void_p, ctypes.POINTER(ctypes.c_long)] t32api.T32_GetRegisterObjValue32.restype = ctypes.c_int t32api.T32_ReleaseRegisterObj.argtypes = [ctypes.POINTER(ctypes.c_void_p)] t32api.T32_ReleaseRegisterObj.restype = ctypes.c_int t32api.T32_Exit.argtypes = [] t32api.T32_Exit.restype = ctypes.c_int check_error(t32api.T32_Config(b"NODE=", b"localhost")) check_error(t32api.T32_Config(b"PORT=", b"20000")) check_error(t32api.T32_Config(b"PACKLEN=", b"1024")) check_error(t32api.T32_Init()) check_error(t32api.T32_Attach(1)) # configuration cpufamily = "RISCV" cpu = "RV32" try: c_buffer = (ctypes.c_char * 4096)() c_result_type = ctypes.c_uint32() check_error(t32api.T32_Ping()) # Check CPUFAMILY() check_error(t32api.T32_ExecuteFunction(b"CPUFAMILY()", c_buffer, len(c_buffer), c_result_type)) if c_buffer.value != cpufamily.encode(): raise ValueError(f"CPUFAMILY(): Expected '{cpufamily}' got '{c_buffer.value.decode()}'") check_error(t32api.T32_ExecuteCommand(f"SYStem.CPU {cpu}".encode(), c_buffer, len(c_buffer))) check_error(t32api.T32_ExecuteCommand(b"SYStem.Mode Up", c_buffer, len(c_buffer))) check_error( t32api.T32_ExecuteCommand(b"Data.LOAD ~~/demo/riscv/compiler/gcc/rv32/sieve/sieve.elf", c_buffer, len(c_buffer)) ) # query symbol "main" myAddress = ctypes.c_uint32(0) mySymbolHandle = ctypes.c_void_p(0) myAddressHandle = ctypes.c_void_p(0) check_error(t32api.T32_RequestSymbolObjName(ctypes.byref(mySymbolHandle), b"main")) check_error(t32api.T32_QuerySymbolObj(mySymbolHandle)) check_error(t32api.T32_GetSymbolObjAddress(mySymbolHandle, ctypes.byref(myAddressHandle))) check_error(t32api.T32_GetAddressObjAddr32(myAddressHandle, ctypes.byref(myAddress))) print(f"Symbol 'main': {hex(myAddress.value)}") check_error(t32api.T32_ReleaseSymbolObj(ctypes.byref(mySymbolHandle))) # set breakpoint to "main" myBreakpointHandle = ctypes.c_void_p(0) check_error(t32api.T32_RequestBreakpointObj(ctypes.byref(myBreakpointHandle))) check_error(t32api.T32_SetBreakpointObjAddress(myBreakpointHandle, myAddressHandle)) check_error(t32api.T32_WriteBreakpointObj(myBreakpointHandle, 1)) check_error(t32api.T32_ReleaseBreakpointObj(ctypes.byref(myBreakpointHandle))) # query register "PC" regValue = ctypes.c_long(0) myRegisterHandle32 = ctypes.c_void_p(0) check_error(t32api.T32_RequestRegisterObjR32Name(ctypes.byref(myRegisterHandle32), b"PC")) check_error(t32api.T32_ReadRegisterObj(myRegisterHandle32)) check_error(t32api.T32_GetRegisterObjValue32(myRegisterHandle32, ctypes.byref(regValue))) print(f"Register 'PC': {hex(regValue.value)}") check_error(t32api.T32_ReleaseRegisterObj(ctypes.byref(myRegisterHandle32))) check_error(t32api.T32_ReleaseAllObjects()) finally: check_error(t32api.T32_Exit())