Reputation: 21
I am trying to automate the Trace32 functions using python. And I am trying to write a value to a memory address using T32_WriteMemory() function. Can someone help me how to go ahead with this function?
Below is the reference from the T32 Api pdf (api_remote.pdf):
int T32_WriteMemory(
uint32_t byteAddress
int access,
uint8_t *buffer,
int byteSize
);
byteAddress : target memory address to start write
access : memory access specifier
buffer : output
byteSize : number of bytes to read
Upvotes: 2
Views: 3677
Reputation: 4183
To write memory from a python script via TRACE32 do the following:
In detail:
1. Enable the port for remote control at TRACE32
Add the following lines to your TRACE32 configuration file (config.t32):
RCL=NETASSIST
PORT=20000
There must be an empty line before and after that block. Of course you can also choose an other number for port. A TRACE32 GUI started with these setting opens a UDP/IP port to listen for possible requests to remote control TRACE32.
2. Get the compiled shared libraries for TRACE32 remote access
You'll find the required shared libraries in your TRACE32 installation at <T32>/demo/api/capi/dll
(On Windows this is usually C:\t32\demo\api\capi\dll) You can also download it at http://www.lauterbach.com/scripts.html (search there for "capi" or "python")
For Windows there is t32api.dll and t32api64.dll. For Linux there is t32api.so or t32api64.so. (t32api64.* is for a 64-bit python interpreter, while t32api.* is for a 32-bit python interpreter.)
In the following I assume that you place the t32api-library at the same directory than your python script.
3. Load the t32api library in your python script
import platform
import ctypes
ostype = ctypes.sizeof(ctypes.c_voidp) * 8
if (platform.system()=='Windows') or (platform.system()[0:6]=='CYGWIN') :
# WINDOWS
t32api = ctypes.CDLL("./t32api64.dll" if ostype==64 else "./t32api.dll")
elif platform.system()=='Darwin' :
# Mac OS X
t32api = ctypes.CDLL("./t32api.dylib")
else :
# Linux
t32api = ctypes.CDLL("./t32api64.so" if ostype==64 else "./t32api.so")
In the t32api-library is not at the same directory than your python script, you have to adapt the paths of course.
4. Connect via the t32api library to your TRACE32 GUI
# Declare UDP/IP socket of the TRACE32 instance to access
t32api.T32_Config(b"NODE=",b"localhost")
t32api.T32_Config(b"PORT=",b"20000")
# Connect to TRACE32
error = t32api.T32_Init()
if error != 0 :
sys.exit("Can't connect to TRACE32!")
# Select to debugger component of TRACE32 (B:: prompt)
t32api.T32_Attach(1)
If you've chosen another port in step 1, you have to change the line t32api.T32_Config(b"PORT=",b"20000")
accordingly.
5. Declare the parameter types of T32_WriteMemory
t32api.T32_WriteMemory.argtypes = [ctypes.c_uint32, ctypes.c_int, ctypes.c_char_p, ctypes.c_int]
t32api.T32_WriteMemory.restype = ctypes.c_int
The first line tells python that T32_WriteMemory is a C-function which has four parameters with the types uint32_t, int, char* and int. The second line tells python that the return value is of type int.
6. Create a byte buffer with the data to write in your target endianness
wdata = 0x12345678 # <- Your own value here !
wbuffer = wdata.to_bytes(4, byteorder='little')
Here, 0x12345678 is the value I have choose to write. My target CPU, which I debug via TRACE32, has it's memory organized in little-endian byte-order. So I've chosen "byteorder='little'" in the second line which creates the byte-buffer.
7. Call the T32_WriteMemory from the t32api library
# Set parameters for the memory access
byteAddress = 0x46c8 # <- Your address here !
access = 0x20
byteSize = 4 # amount of bytes to write (e.g. 4 bytes)
# Write data to memory via TRACE32
error = t32api.T32_WriteMemory(byteAddress, access, wbuffer, byteSize)
if error != 0 :
print("write failed")
access = 0x20
enables memory access while the CPU is running (if SYStem.MemAccess is enabled in TRACE32 and the CPU supports run-time access) Set it to 0 otherwise, or see the TRACE32 API documentation (api_remote.pdf) for other values.
8. Close connection to TRACE32 before ending your script
t32api.T32_Exit()
Reading memory goes like this:
# Declare argument types of T32_T32_ReadMemory
t32api.T32_T32_ReadMemory.argtypes = [ctypes.c_uint32,ctypes.c_int, ctypes.c_char_p,ctypes.c_int]
t32api.T32_T32_ReadMemory.restype = ctypes.c_int
# Create a buffer for the result
rbuffer = ctypes.create_string_buffer(byteSize)
# Request memory content via TRACE32
error = t32api.T32_ReadMemory(byteAddress, access, rbuffer, byteSize)
if error == 0 :
# Extract 32-bit value in little endian order from the buffer
data32 = int.from_bytes(rbuffer[0:4], byteorder='little')
print("read 0x%08X from D:0x%08X" % (data32, byteAddress))
else:
print("read failed")
Upvotes: 6