#!/usr/bin/python # -*- coding: latin-1 -*- # -------------------------------------------------------------------------------- # @Title: Python example demonstrating various functions of the TRACE32 remote API # @Description: # After establishing a remote connection with TRACE32 PowerView a menu offers # various API commands for selection. For accessing real HW the data memory # location can be specified by . # # Syntax: t32apimenu.py [--node ] [--port ] [--address ] # # Example: t32apimenu.py --node localhost --port 20000 --address 0x400C000 # # 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 with this python script. # # # @Keywords: python # @Author: WBA # @Copyright: (C) 1989-2015 Lauterbach GmbH, licensed for use with TRACE32(R) only # -------------------------------------------------------------------------------- # $Id: t32apimenu.py 116756 2020-01-27 07:42:44Z jvogl $ # import sys, getopt, time, ctypes, array, os, platform from ctypes import * # 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") T32_OK = 0 T32_MEMORY_ACCESS_DATA=0 sel = ' ' address = 0xffffffff pcval = c_long(0xffffffff) wp = array.array('i', list(range(512))) wpbuffer = (c_ulong * 256).from_buffer(wp) wpbuffer[0]=0xcafefeca rw = array.array('i', list(range(4))) rwbuffer = (c_ulong * 2).from_buffer(rw) rwbuffer[0] = 0xcafefeca rwbuffer[1] = 0xbabebeba ui32val = array.array('i', list(range(16))) pui32val = (c_ulong * 8).from_buffer(ui32val) ui16val = array.array('i', list(range(64))) pui16val = (c_ushort * 32).from_buffer(ui16val) EXIT_SUCCESS=0 EXIT_FAILURE=1 T32_MEMORY_ACCESS_PROGRAM=0x1 retval = EXIT_SUCCESS PROGNAME=os.path.basename(__file__) def _find_getch(): try: import termios except ImportError: # Non-POSIX. Return msvcrt's (Windows') getch. import msvcrt return msvcrt.getch # POSIX system. Create and return a getch that manipulates the tty. import sys, tty def _getch(): fd = sys.stdin.fileno() old_settings = termios.tcgetattr(fd) try: tty.setraw(fd) ch = sys.stdin.read(1) finally: termios.tcsetattr(fd, termios.TCSADRAIN, old_settings) return ch return _getch getch = _find_getch() def main(argv): try: opts, args = getopt.getopt(argv,"hn:p:a:",["node=","port=","address="]) except getopt.GetoptError: print(" %s [--node ] [--port ] [--address ]" %(PROGNAME)) sys.exit(EXIT_FAILURE) node = 'localhost' port = '20000' hexaddr = '0xffffffff' string=create_string_buffer(50) string='Data.DUMP D:0x1000 ' sel=create_string_buffer(3) sel=' ' for opt, arg in opts: if opt == '-h': print("") print(" Syntax: %s [--node ] [--port ] [--address ]" %(PROGNAME)) print(" Example: %s --node localhost --port 20000 --address 0x400C000" % (PROGNAME)) print("") print(" Hexaddress is used by Read/WriteMemory if real hardware is accessed.") print("") sys.exit(EXIT_SUCCESS) elif opt in ("-n", "--node","-N","--NODE"): node = arg elif opt in ("-p", "--port","-P","--PORT"): port = arg elif opt in ("-a", "--address","-A","--ADDRESS"): hexaddr = arg address=hexaddr address=int(address,16) j=1 m=0 ### Debugger operation t32api.T32_Config(b"NODE=",node.encode('latin-1')) if t32api.T32_Config(b"PORT=",port.encode('latin-1'))!=T32_OK: print(' Invalid port number \'%s\' specified.'%(port)) sys.exit(EXIT_FAILURE) t32api.T32_Config(b"PACKLEN=",b"1024") print("") print(' Connecting...') for i in range (1, 3): if t32api.T32_Init()==T32_OK: if t32api.T32_Attach(1)==T32_OK: print(' Successfully established a remote connection with TRACE32 PowerView.') break else : if i==1: print(' Failed once to established a remote connection with TRACE32 PowerView.') t32api.T32_Exit() elif i==2 : print(' Failed twice to established a remote connection with TRACE32 PowerView.') print(' Terminating ...') sys.exit(EXIT_FAILURE) else : if i==1: print(' Failed once to initialize a remote connection with TRACE32 PowerView.') t32api.T32_Exit() elif i==2 : print(' Failed twice to initialize a remote connection with TRACE32 PowerView.') print(' Terminating ...') sys.exit(EXIT_FAILURE) # send input command to TRACE32 PowerView for execution and return any message if hexaddr[0]=='0' and hexaddr[1]=='x': list1 = list(string) for i in range (0,len(hexaddr)): list1[12+i] = hexaddr[i] if 12+len(hexaddr)] [--port ] [-address ]" %( PROGNAME)) print(" Example: %s.py --node localhost --port 20000 --address 0x400C000\n" % (PROGNAME)) print("") print(" Hexaddress is used by Read/WriteMemory if real hardware is accessed.") print("") print("") print(' Real hardware is accessed but no address for data access') print(' has been specified, Read/WriteMemory will access D:0x1000') address = 0x1000 else: t32api.T32_Cmd(b"SYStem.Up") t32api.T32_Cmd(b"Data.Assemble P:0x0++0x40 nop") t32api.T32_Cmd(b"EVAL CPU()") #/* for EVAL CPU() size of */ t32api.T32_EvalGetString(string.encode('latin-1')) #/* string is sufficient */ if ( string[:len('TC')] == 'TC'): t32api.T32_Cmd(b"Data.Assemble P:0x40 j 0x0") else: t32api.T32_Cmd(b"Data.Assemble P:0x40 b 0x0") t32api.T32_Cmd(b"Register.Set PC P:0x0"); t32api.T32_Cmd(b"WINPOS 40% 0 60% 40% , , APIWin4") t32api.T32_Cmd(b"Data.List") t32api.T32_Cmd(b"WINPOS 40% 40% 60% 40% , , APIWin5") t32api.T32_Cmd(b"Data.Dump D:0x1000") address = 0x1000 t32api.T32_Cmd(b"WINPOS 40% 75% 60% 25% , , APIWin6") t32api.T32_Cmd(b"Break.List") # select and execute remote API function while True : print("") print("") print(' Please select an action or exit with \'q\':') print("") print(' p Ping rm ReadMemory d do test.cmm') print(' s Step wm WriteMemory S Stop script') print(' g Go wp WritePipelined x TestSequence') print(' b Break rr ReadRegister j JtagTapAccess') print(' c CpuState wr WriteRegister T TraceData') print(' R Reset rb ReadBreakpoint i IntegratorData') print(' n Nop wb WriteBreakpoint') print(' f NopFail rp ReadProgCounter t TerminateTRACE32') print("") i = 0 k = 0 list1 = list(sel) list1 = '' sel= ''.join(list1) list1='tt' while (len(sel) == 0) or (((sel[0] == 'r') or (sel[0] == 'w')) and (len(sel) == 1)) : i=i+1 if i%4<2 : sys.stdout.write( '\r>' +sel ) else : sys.stdout.write( '\r>' +sel ) sys.stdout.flush() time.sleep(0.25) if k==0: sel=getch().decode('latin-1') k=k+1 else: list1 = list(sel) list1 = sel + getch().decode('latin-1') sel= ''.join(list1) k=k+1 sys.stdout.write( '\r>'+ sel) if ((sel[0] == 'q') or (sel[0] == 'Q')) : print("") print("") print(' Program has been terminated by pressing %c' %sel[0]) break retval = T32_OK if sel[0]=='p': retval = t32api.T32_Ping() elif sel[0]=='s': retval = t32api.T32_Step() elif sel[0]=='g': retval = t32api.T32_Go() elif sel[0]=='b': retval = t32api.T32_Break() elif sel[0]=='R': retval = t32api.T32_ResetCPU() elif sel[0]=='n': retval = t32api.T32_Nop() elif sel[0]=='f': t32api.T32_NopFail() elif sel[0]=='d': retval = t32api.T32_Cmd(b"do test.cmm") elif sel[0]=='S': retval = t32api.T32_Stop() elif sel[0]=='t': retval = t32api.T32_Terminate(0) elif sel[0]=='r': if sel[1]=='m' : retval = t32api.T32_ReadMemory(address, T32_MEMORY_ACCESS_DATA, pui32val, 8) if retval == T32_OK: print("") print("") print(' Read 8 bytes, started at address D:0x%s data is 0x%s 0x%s:'%(format(address,'0x'),format(pui32val[0],'0x') , format(pui32val[1],'0x'))) elif sel[1]=='r': retval = t32api.T32_ReadRegister(0xfc, 0, pui32val) if retval == T32_OK : print("") print("") sys.stdout.write (' Read registers R2-R7, content is:') sys.stdout.flush() for i in range (2,8): sys.stdout.write( ' 0x%s' %( format(pui32val[i],'0x' ))) sys.stdout.flush() elif sel[1]=='p': retval = t32api.T32_ReadPP(pui32val) if retval == T32_OK: print("") print("") print(' Read register ProgramCounter, content is 0x%s' %(format( pui32val[0],'0x'))) elif sel[1]=='b': retval = t32api.T32_ReadPP(pui32val) if (retval == T32_OK) : retval = t32api.T32_ReadBreakpoint(pui32val[0], T32_MEMORY_ACCESS_PROGRAM, pui16val, 32) if (retval == T32_OK) : print("") print("") print(' Tested for breakpoints at address P:0x%s -- 0x%s'%(format(pui32val[0],'0x'),format(pui32val[0]+0x1f,'0x'))) print("") noactive=0 for i in range (0,32): if pui16val[i] !=0: print(' Breakpoint is active at address P:0x%x' %(pui32val[0]+i)) noactive=1 if noactive==0: print(' No active breakpoints.') else: print("") print("") print(' Invalid selection!') elif sel[0]=='w': if sel[1]=='m': rwbuffer[0] ^= 0x70404070 rwbuffer[1] ^= 0x70404070 retval = t32api.T32_WriteMemory(address, T32_MEMORY_ACCESS_DATA,rwbuffer, 8) if (retval == T32_OK): print("") print("") print(' Wrote 8 bytes of new data, started at address D:0x%s ' %(format(address,'0x'))) print(' enter \'rm\' for readout.') elif sel[1]=='p': wpbuffer[0] ^= 0x70404070 for i in range (1,256): wpbuffer[i] = wpbuffer[0] retval = t32api.T32_WriteMemoryPipe(address, T32_MEMORY_ACCESS_DATA, wpbuffer, 1024)|t32api.T32_WriteMemoryPipe(0, 0, 0, 0) if (retval == T32_OK): print("") print("") print(' Wrote 1024 bytes of new data, started at address D:0x%s , see TRACE32 Data.Dump window.' %(format(address,'0x'))) elif sel[1]=='r': m=m+1 pui32val[0] = m for i in range (2,8): pui32val[i] = pui32val[0] + i retval = t32api.T32_WriteRegister(0xfc, 0, pui32val) if (retval == T32_OK): print("") print("") print(' Wrote new data to registers R2-R7, enter \'rr\' for readout.') elif sel[1]=='b': if ((j == 1) or (pcval == 0xffffffff)) : j = 0 #set retval = t32api.T32_ReadPP(byref(pcval)) else: j = 1; #delete if (retval == T32_OK) : retval = t32api.T32_WriteBreakpoint(pcval,T32_MEMORY_ACCESS_PROGRAM,(j<<8)|(1<<4)|(1<<3),8) if (retval == T32_OK): retval = t32api.T32_WriteBreakpoint(pcval.value+0xf,T32_MEMORY_ACCESS_PROGRAM,(j<<8)|(1<<0),1) if (retval == T32_OK): if j==1: print("") print("") print(' Deleted breakpoints at adresses P:0x%s--0x%s and P:0x%s'%(format(pcval.value,'0x') ,format(pcval.value + 0x7,'0x'),format(pcval.value + 0xf,'0x'))) print(' enter \'rb\' for readout.') else : print("") print("") print(' Set breakpoints at adresses P:0x%s--0x%s and P:0x%s'%(format(pcval.value,'0x') ,format(pcval.value + 0x7,'0x'),format(pcval.value + 0xf,'0x'))) print(' enter \'rb\' for readout.') else: print("") print("") print(' Invalid selection!') elif sel[0]=='c': retval = t32api.T32_GetState(byref(systemstate)) if (retval == T32_OK) : states= ["down", "halted", "stopped", "running"] systemstate.value=(systemstate.value) & 0x3; #safeguard the little trick print("") print("") print(' Current system state is:', states[systemstate.value]) elif sel[0]=='x': print("") print("") for i in range(1,11) : retval = t32api.T32_Step() if (retval == T32_OK) : retval = t32api.T32_ReadPP(pui32val) if (retval == T32_OK): print(' Performed single step, value of ProgramCounter is 0x%s' %(format(pui32val[0],'0x'))) elif sel[0]=='j': buffer = array.array('i', list(range(4))) pbuffer = (c_ubyte * 4).from_buffer(buffer) pbuffer[0] = ord('a') pbuffer[1] = ord('b') pbuffer[2] = ord('c') pbuffer[3] = ord('d') retval = t32api.T32_TAPAccessShiftIR(0, 32, pbuffer, pbuffer) if (retval == T32_OK): print("") print("") print(' Data received from TAP controller is: 0x%s 0x%s 0x%s 0x%s' %(format(pbuffer[0],'02x'),format(pbuffer[1],'02x'),format(pbuffer[2],'02x'),format(pbuffer[3],'02x'))) elif sel[0]=='T' or sel[0]=='i': states = ["off", "armed", "triggered", "breaked"] total = c_int() min = c_int() max = c_int() buf = array.array('i', list(range(80))) pbuf = (c_ubyte * 80).from_buffer(buf) for i in range (0,80): pbuf[i] = 0xaa #Trace|Integrator if (sel[0]=='T'): retval = t32api.T32_GetTraceState(0, byref(systemstate), byref(total), byref(min), byref(max)) else: retval = t32api.T32_GetTraceState(1, byref(systemstate), byref(total), byref(min), byref(max)) if (retval == T32_OK) : systemstate.value=systemstate.value & 0x3 #/*safeguard the little trick*/ if (sel[0]=='T'): print("") print("") print(' Trace state is: ',states[systemstate.value], ' total buffer size is %s' %format(total.value,'0d')) print(' Trace records range from entry',int(min.value) ,' to', int(max.value),'latest ones are:') else: print("") print("") print(' Integrator state is: ',states[systemstate.value], ' total buffer size is %s' %format(total.value,'0d')) print(' Trace records range from entry',int(min.value) ,' to', int(max.value),'latest ones are:') if (max.value - min.value + 1 > 20): num=20 else: num=max.value - min.value + 1 if ((num > 0) and (systemstate.value == 0)) : if sel[0]=='T': retval = t32api.T32_ReadTrace(0, max.value - num + 1, num, 0x10, pbuf)# 4 bytes are written to 'buf' for else: retval = t32api.T32_ReadTrace(1, max.value - num + 1, num, 0x10, pbuf) if (retval == T32_OK) : # each mask-bit with value '1' print("") print("") for i in range (0,num*4,4 ): print(' Record %s: Physical program address: 0x%s%s%s%s' %(int(max.value - num + 1 + i/4),format(pbuf[i+3], '02x'),format(pbuf[i+2], '02x'),format(pbuf[i+1], '02x'),format(pbuf[i], '02x')))# trace data is always little endian else: print("") print("") print(' Invalid selection!') if (retval != T32_OK): print("") print("") print(' !!!Failed to execute remote command!!!') print("") if t32api.T32_Exit()!= T32_OK: print(' Failed to close the remote connection port on the dos shell application\'s side.') sys.exit(EXIT_FAILURE) else : sys.exit(retval) if __name__ == "__main__": main(sys.argv[1:])