2

我正在尝试使用 python 自动化 Trace32 函数。我正在尝试使用 T32_WriteMemory() 函数将值写入内存地址。有人可以帮助我如何继续使用此功能吗?

以下是 T32 Api pdf (api_remote.pdf) 的参考:

int T32_WriteMemory(
   uint32_t  byteAddress
   int       access,
   uint8_t  *buffer,
   int       byteSize
); 

byteAddress : 开始写入的目标内存地址

access :内存访问说明符

缓冲区:输出

byteSize : 要读取的字节数

4

1 回答 1

6

要通过 TRACE32 从 python 脚本写入内存,请执行以下操作:

  1. 在 TRACE32 启用远程控制端口
  2. 获取用于 TRACE32 远程访问的已编译共享库 (t32api.dll/.so)
  3. 在 python 脚本中加载 t32api 库(使用 ctypes)
  4. 通过 t32api 库连接到您的 TRACE32 GUI
  5. 声明T32_WriteMemory的参数类型
  6. 创建一个字节缓冲区,其中包含要写入目标字节序的数据
  7. 从 t32api 库调用 T32_WriteMemory(使用 ctypes)
  8. 在结束脚本之前关闭与 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_tintchar*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")
于 2017-12-08T15:30:58.727 回答