要通过 TRACE32 从 python 脚本写入内存,请执行以下操作:
- 在 TRACE32 启用远程控制端口
- 获取用于 TRACE32 远程访问的已编译共享库 (t32api.dll/.so)
- 在 python 脚本中加载 t32api 库(使用 ctypes)
- 通过 t32api 库连接到您的 TRACE32 GUI
- 声明T32_WriteMemory的参数类型
- 创建一个字节缓冲区,其中包含要写入目标字节序的数据
- 从 t32api 库调用 T32_WriteMemory(使用 ctypes)
- 在结束脚本之前关闭与 TRACE32 的连接
详细地:
1.在TRACE32开启远程控制端口
将以下行添加到您的 TRACE32 配置文件 (config.t32):
RCL=NETASSIST
PORT=20000
该块之前和之后必须有一个空行。当然你也可以选择其他的端口号。使用这些设置启动的 TRACE32 GUI 会打开一个 UDP/IP 端口以侦听远程控制 TRACE32 的可能请求。
2.获取TRACE32远程访问编译好的共享库
您可以在 TRACE32 安装中找到所需的共享库<T32>/demo/api/capi/dll
(在 Windows 上,这通常是 C:\t32\demo\api\capi\dll)。您也可以在http://www.lauterbach.com/scripts 下载它。 html(在此处搜索“capi”或“python”)
对于 Windows,有 t32api.dll 和 t32api64.dll。对于 Linux,有 t32api.so 或 t32api64.so。(t32api64.* 用于 64 位 python 解释器,而 t32api.* 用于 32 位 python 解释器。)
在下文中,我假设您将 t32api-library 放在与 python 脚本相同的目录中。
3.在你的python脚本中加载t32api库
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")
在 t32api-library 与您的 python 脚本不在同一目录中,您当然必须调整路径。
4. 通过 t32api 库连接到您的 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)
如果您在步骤 1 中选择了另一个端口,则必须t32api.T32_Config(b"PORT=",b"20000")
相应地更改线路。
5.声明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
第一行告诉 python T32_WriteMemory 是一个 C 函数,它有四个参数,类型为uint32_t、int、char*和int。第二行告诉 python 返回值的类型是int。
6. 创建一个字节缓冲区,其中包含要写入目标字节序的数据
wdata = 0x12345678 # <- Your own value here !
wbuffer = wdata.to_bytes(4, byteorder='little')
在这里,0x12345678 是我选择写入的值。我通过 TRACE32 调试的目标 CPU 的内存以 little-endian 字节顺序组织。所以我在创建字节缓冲区的第二行中选择了“byteorder='little'”。
7. 从 t32api 库调用 T32_WriteMemory
# 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
在 CPU 运行时启用内存访问(如果在 TRACE32 中启用了 SYStem.MemAccess 并且 CPU 支持运行时访问),否则将其设置为 0,或查看 TRACE32 API 文档 (api_remote.pdf) 以获取其他值。
8. 在结束脚本之前关闭与 TRACE32 的连接
t32api.T32_Exit()
读内存是这样的:
# 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")