代码拉取完成,页面将自动刷新
# jlink_operations.py (JLink 操作模块)
import ctypes
import os
import sys
from enum import Enum
import io
class JLinkException(Exception):
pass
class JTAG_ID_DATA(ctypes.Structure):
_fields_ = [
("NumDevices", ctypes.c_int), # 设备数量
("ScanLen", ctypes.c_ushort), # 扫描链总位数
("aId", ctypes.c_uint * 3), # JTAG ID 数组
("aScanLen", ctypes.c_ubyte * 3), # 扫描链长度数组
("aIrRead", ctypes.c_ubyte * 3), # 从指令寄存器读取的数据
("aScanRead", ctypes.c_ubyte * 3), # 从扫描链读取的数据
]
# 定义枚举
class JLINKARM_CM4_REG(Enum):
JLINKARM_CM4_REG_R0 = 0 # Index 0
JLINKARM_CM4_REG_R1 = 1 # Index 1
JLINKARM_CM4_REG_R2 = 2 # Index 2
JLINKARM_CM4_REG_R3 = 3 # Index 3
JLINKARM_CM4_REG_R4 = 4 # Index 4
JLINKARM_CM4_REG_R5 = 5 # Index 5
JLINKARM_CM4_REG_R6 = 6 # Index 6
JLINKARM_CM4_REG_R7 = 7 # Index 7
JLINKARM_CM4_REG_R8 = 8 # Index 8
JLINKARM_CM4_REG_R9 = 9 # Index 9
JLINKARM_CM4_REG_R10 = 10 # Index 10
JLINKARM_CM4_REG_R11 = 11 # Index 11
JLINKARM_CM4_REG_R12 = 12 # Index 12
JLINKARM_CM4_REG_R13 = 13 # Index 13: Pseudo reg! It needs to be mapped to SP_MSP or SP_PSP depending on current Controlregister
JLINKARM_CM4_REG_R14 = 14 # Index 14
JLINKARM_CM4_REG_R15 = 15 # Index 15
JLINKARM_CM4_REG_XPSR = 16 # Index 16
JLINKARM_CM4_REG_MSP = 17 # Index 17
JLINKARM_CM4_REG_PSP = 18 # Index 18
JLINKARM_CM4_REG_RAZ = 19 # Index 19: Reserved
JLINKARM_CM4_REG_CFBP = 20 # Index 20: CONTROL/FAULTMASK/BASEPRI/PRIMASK (packed into 4 bytes of word)
JLINKARM_CM4_REG_APSR = 21 # Index 21: Pseudo reg. (Part of XPSR)
JLINKARM_CM4_REG_EPSR = 22 # Index 22: Pseudo reg. (Part of XPSR)
JLINKARM_CM4_REG_IPSR = 23 # Index 23: Pseudo reg. (Part of XPSR)
JLINKARM_CM4_REG_PRIMASK = 24 # Index 24: Pseudo reg. (Part of CFBP)
JLINKARM_CM4_REG_BASEPRI = 25 # Index 25: Pseudo reg. (Part of CFBP)
JLINKARM_CM4_REG_FAULTMASK = 26 # Index 26: Pseudo reg. (Part of CFBP)
JLINKARM_CM4_REG_CONTROL = 27 # Index 27: Pseudo reg. (Part of CFBP)
JLINKARM_CM4_REG_BASEPRI_MAX = 28 # Index 28: Pseudo reg. (Part of CFBP)
JLINKARM_CM4_REG_IAPSR = 29 # Index 29: Pseudo reg. (Part of XPSR)
JLINKARM_CM4_REG_EAPSR = 30 # Index 30: Pseudo reg. (Part of XPSR)
JLINKARM_CM4_REG_IEPSR = 31 # Index 31: Pseudo reg. (Part of XPSR)
JLINKARM_CM4_REG_FPSCR = 32 # Index 32
JLINKARM_CM4_REG_FPS0 = 33 # Index 33
JLINKARM_CM4_REG_FPS1 = 34 # Index 34
JLINKARM_CM4_REG_FPS2 = 35 # Index 35
JLINKARM_CM4_REG_FPS3 = 36 # Index 36
JLINKARM_CM4_REG_FPS4 = 37 # Index 37
JLINKARM_CM4_REG_FPS5 = 38 # Index 38
JLINKARM_CM4_REG_FPS6 = 39 # Index 39
JLINKARM_CM4_REG_FPS7 = 40 # Index 40
JLINKARM_CM4_REG_FPS8 = 41 # Index 41
JLINKARM_CM4_REG_FPS9 = 42 # Index 42
JLINKARM_CM4_REG_FPS10 = 43 # Index 43
JLINKARM_CM4_REG_FPS11 = 44 # Index 44
JLINKARM_CM4_REG_FPS12 = 45 # Index 45
JLINKARM_CM4_REG_FPS13 = 46 # Index 46
JLINKARM_CM4_REG_FPS14 = 47 # Index 47
JLINKARM_CM4_REG_FPS15 = 48 # Index 48
JLINKARM_CM4_REG_FPS16 = 49 # Index 49
JLINKARM_CM4_REG_FPS17 = 50 # Index 50
JLINKARM_CM4_REG_FPS18 = 51 # Index 51
JLINKARM_CM4_REG_FPS19 = 52 # Index 52
JLINKARM_CM4_REG_FPS20 = 53 # Index 53
JLINKARM_CM4_REG_FPS21 = 54 # Index 54
JLINKARM_CM4_REG_FPS22 = 55 # Index 55
JLINKARM_CM4_REG_FPS23 = 56 # Index 56
JLINKARM_CM4_REG_FPS24 = 57 # Index 57
JLINKARM_CM4_REG_FPS25 = 58 # Index 58
JLINKARM_CM4_REG_FPS26 = 59 # Index 59
JLINKARM_CM4_REG_FPS27 = 60 # Index 60
JLINKARM_CM4_REG_FPS28 = 61 # Index 61
JLINKARM_CM4_REG_FPS29 = 62 # Index 62
JLINKARM_CM4_REG_FPS30 = 63 # Index 63
JLINKARM_CM4_REG_FPS31 = 64 # Index 64
JLINKARM_CM4_REG_DWT_CYCCNT = 65 # Index 65
JLINKARM_CM4_REG_MSP_NS = 66 # New reg.
JLINKARM_CM4_REG_PSP_NS = 67 # New reg.
JLINKARM_CM4_REG_MSP_S = 68 # New reg.
JLINKARM_CM4_REG_PSP_S = 69 # New reg.
JLINKARM_CM4_REG_MSPLIM_S = 70 # New reg.
JLINKARM_CM4_REG_PSPLIM_S = 71 # New reg.
JLINKARM_CM4_REG_MSPLIM_NS = 72 # New reg.
JLINKARM_CM4_REG_PSPLIM_NS = 73 # New reg.
JLINKARM_CM4_REG_CFBP_S = 74 # New reg.
JLINKARM_CM4_REG_CFBP_NS = 75 # New reg.
JLINKARM_CM4_REG_PRIMASK_NS = 76 # Pseudo reg. (Part of CFBP)
JLINKARM_CM4_REG_BASEPRI_NS = 77 # Pseudo reg. (Part of CFBP)
JLINKARM_CM4_REG_FAULTMASK_NS = 78 # Pseudo reg. (Part of CFBP)
JLINKARM_CM4_REG_CONTROL_NS = 79 # Pseudo reg. (Part of CFBP)
JLINKARM_CM4_REG_BASEPRI_MAX_NS = 80 # Pseudo reg. (Part of CFBP)
JLINKARM_CM4_REG_PRIMASK_S = 81 # Pseudo reg. (Part of CFBP)
JLINKARM_CM4_REG_BASEPRI_S = 82 # Pseudo reg. (Part of CFBP)
JLINKARM_CM4_REG_FAULTMASK_S = 83 # Pseudo reg. (Part of CFBP)
JLINKARM_CM4_REG_CONTROL_S = 84 # Pseudo reg. (Part of CFBP)
JLINKARM_CM4_REG_BASEPRI_MAX_S = 85 # Pseudo reg. (Part of CFBP)
JLINKARM_CM4_REG_MSPLIM = 86 # Either real or pseudo reg depending on if security extensions are implemented or not
JLINKARM_CM4_REG_PSPLIM = 87 # Either real or pseudo reg depending on if security extensions are implemented or not
JLINKARM_CM4_REG_MAX = 100
# 其他寄存器可按需添加
# 示例寄存器索引
reg_indices = [
JLINKARM_CM4_REG.JLINKARM_CM4_REG_R0,
JLINKARM_CM4_REG.JLINKARM_CM4_REG_R1,
JLINKARM_CM4_REG.JLINKARM_CM4_REG_R2,
JLINKARM_CM4_REG.JLINKARM_CM4_REG_R3,
JLINKARM_CM4_REG.JLINKARM_CM4_REG_R4,
JLINKARM_CM4_REG.JLINKARM_CM4_REG_R5,
JLINKARM_CM4_REG.JLINKARM_CM4_REG_R6,
JLINKARM_CM4_REG.JLINKARM_CM4_REG_R7,
JLINKARM_CM4_REG.JLINKARM_CM4_REG_R8,
JLINKARM_CM4_REG.JLINKARM_CM4_REG_R9,
JLINKARM_CM4_REG.JLINKARM_CM4_REG_R10,
JLINKARM_CM4_REG.JLINKARM_CM4_REG_R11,
JLINKARM_CM4_REG.JLINKARM_CM4_REG_R12,
JLINKARM_CM4_REG.JLINKARM_CM4_REG_R13,
JLINKARM_CM4_REG.JLINKARM_CM4_REG_R14,
JLINKARM_CM4_REG.JLINKARM_CM4_REG_R15,
JLINKARM_CM4_REG.JLINKARM_CM4_REG_XPSR,
JLINKARM_CM4_REG.JLINKARM_CM4_REG_MSP,
JLINKARM_CM4_REG.JLINKARM_CM4_REG_PSP,
#JLINKARM_CM4_REG.JLINKARM_CM4_REG_RAZ,
JLINKARM_CM4_REG.JLINKARM_CM4_REG_CFBP,
JLINKARM_CM4_REG.JLINKARM_CM4_REG_APSR,
JLINKARM_CM4_REG.JLINKARM_CM4_REG_EPSR,
JLINKARM_CM4_REG.JLINKARM_CM4_REG_IPSR,
JLINKARM_CM4_REG.JLINKARM_CM4_REG_PRIMASK,
JLINKARM_CM4_REG.JLINKARM_CM4_REG_BASEPRI,
JLINKARM_CM4_REG.JLINKARM_CM4_REG_FAULTMASK,
JLINKARM_CM4_REG.JLINKARM_CM4_REG_CONTROL,
# JLINKARM_CM4_REG.JLINKARM_CM4_REG_BASEPRI_MAX,
# JLINKARM_CM4_REG.JLINKARM_CM4_REG_IAPSR,
# JLINKARM_CM4_REG.JLINKARM_CM4_REG_EAPSR,
# JLINKARM_CM4_REG.JLINKARM_CM4_REG_IEPSR,
JLINKARM_CM4_REG.JLINKARM_CM4_REG_FPSCR,
JLINKARM_CM4_REG.JLINKARM_CM4_REG_FPS0,
JLINKARM_CM4_REG.JLINKARM_CM4_REG_FPS1,
JLINKARM_CM4_REG.JLINKARM_CM4_REG_FPS2,
JLINKARM_CM4_REG.JLINKARM_CM4_REG_FPS3,
JLINKARM_CM4_REG.JLINKARM_CM4_REG_FPS4,
JLINKARM_CM4_REG.JLINKARM_CM4_REG_FPS5,
JLINKARM_CM4_REG.JLINKARM_CM4_REG_FPS6,
JLINKARM_CM4_REG.JLINKARM_CM4_REG_FPS7,
JLINKARM_CM4_REG.JLINKARM_CM4_REG_FPS8,
JLINKARM_CM4_REG.JLINKARM_CM4_REG_FPS9,
JLINKARM_CM4_REG.JLINKARM_CM4_REG_FPS10,
JLINKARM_CM4_REG.JLINKARM_CM4_REG_FPS11,
JLINKARM_CM4_REG.JLINKARM_CM4_REG_FPS12,
JLINKARM_CM4_REG.JLINKARM_CM4_REG_FPS13,
JLINKARM_CM4_REG.JLINKARM_CM4_REG_FPS14,
JLINKARM_CM4_REG.JLINKARM_CM4_REG_FPS15,
JLINKARM_CM4_REG.JLINKARM_CM4_REG_FPS16,
JLINKARM_CM4_REG.JLINKARM_CM4_REG_FPS17,
JLINKARM_CM4_REG.JLINKARM_CM4_REG_FPS18,
JLINKARM_CM4_REG.JLINKARM_CM4_REG_FPS19,
JLINKARM_CM4_REG.JLINKARM_CM4_REG_FPS20,
JLINKARM_CM4_REG.JLINKARM_CM4_REG_FPS21,
JLINKARM_CM4_REG.JLINKARM_CM4_REG_FPS22,
JLINKARM_CM4_REG.JLINKARM_CM4_REG_FPS23,
JLINKARM_CM4_REG.JLINKARM_CM4_REG_FPS24,
JLINKARM_CM4_REG.JLINKARM_CM4_REG_FPS25,
JLINKARM_CM4_REG.JLINKARM_CM4_REG_FPS26,
JLINKARM_CM4_REG.JLINKARM_CM4_REG_FPS27,
JLINKARM_CM4_REG.JLINKARM_CM4_REG_FPS28,
JLINKARM_CM4_REG.JLINKARM_CM4_REG_FPS29,
JLINKARM_CM4_REG.JLINKARM_CM4_REG_FPS30,
JLINKARM_CM4_REG.JLINKARM_CM4_REG_FPS31,
JLINKARM_CM4_REG.JLINKARM_CM4_REG_DWT_CYCCNT,
# JLINKARM_CM4_REG.JLINKARM_CM4_REG_MSP_NS,
# JLINKARM_CM4_REG.JLINKARM_CM4_REG_PSP_NS,
# JLINKARM_CM4_REG.JLINKARM_CM4_REG_MSP_S,
# JLINKARM_CM4_REG.JLINKARM_CM4_REG_PSP_S,
# JLINKARM_CM4_REG.JLINKARM_CM4_REG_MSPLIM_S,
# JLINKARM_CM4_REG.JLINKARM_CM4_REG_PSPLIM_S,
# JLINKARM_CM4_REG.JLINKARM_CM4_REG_MSPLIM_NS,
# JLINKARM_CM4_REG.JLINKARM_CM4_REG_PSPLIM_NS,
# JLINKARM_CM4_REG.JLINKARM_CM4_REG_CFBP_S,
# JLINKARM_CM4_REG.JLINKARM_CM4_REG_CFBP_NS,
# JLINKARM_CM4_REG.JLINKARM_CM4_REG_PRIMASK_NS,
# JLINKARM_CM4_REG.JLINKARM_CM4_REG_BASEPRI_NS,
# JLINKARM_CM4_REG.JLINKARM_CM4_REG_FAULTMASK_NS,
# JLINKARM_CM4_REG.JLINKARM_CM4_REG_CONTROL_NS,
# JLINKARM_CM4_REG.JLINKARM_CM4_REG_BASEPRI_MAX_NS,
# JLINKARM_CM4_REG.JLINKARM_CM4_REG_PRIMASK_S,
# JLINKARM_CM4_REG.JLINKARM_CM4_REG_BASEPRI_S,
# JLINKARM_CM4_REG.JLINKARM_CM4_REG_FAULTMASK_S,
# JLINKARM_CM4_REG.JLINKARM_CM4_REG_CONTROL_S,
# JLINKARM_CM4_REG.JLINKARM_CM4_REG_BASEPRI_MAX_S,
# JLINKARM_CM4_REG.JLINKARM_CM4_REG_MSPLIM,
# JLINKARM_CM4_REG.JLINKARM_CM4_REG_PSPLIM,
]
# 定义设备系列常量
JLINKARM_DEV_FAMILY = {
"AUTO": 0,
"CM1": 1,
"CF": 2,
"CM3": 3,
"SIM": 4,
"XSCALE": 5,
"CM0": 6,
"ARM7": 7,
"CORTEX_A8": 8,
"ARM9": 9,
"ARM10": 10,
"ARM11": 11,
"CORTEX_R4": 12,
"RX": 13,
"CM4": 14,
"CORTEX_A5": 15,
"POWER_PC": 16,
"MIPS": 17,
"EFM8": 18,
"RISC_V": 19,
"CORTEX_AR_ARMV8": 0x14,
"BT5511": 0x15,
"ANY": 255
}
def identify_device_family(device_family):
if device_family == JLINKARM_DEV_FAMILY["ARM7"]:
print("ARM7 identified.")
return 0 # O.K.
elif device_family == JLINKARM_DEV_FAMILY["ARM9"]:
print("ARM9 identified.")
return 0 # O.K.
elif device_family == JLINKARM_DEV_FAMILY["ARM11"]:
print("ARM11 identified.")
return 0 # O.K.
elif device_family == JLINKARM_DEV_FAMILY["CM3"]:
print("Cortex-M3 identified.")
return 0 # O.K.
elif device_family == JLINKARM_DEV_FAMILY["CM1"]:
print("Cortex-M1 identified.")
return 0 # O.K.
elif device_family == JLINKARM_DEV_FAMILY["CF"]:
print("ColdFire identified.")
return 0 # O.K.
elif device_family == JLINKARM_DEV_FAMILY["SIM"]:
print("Simulator identified.")
return 0 # O.K.
elif device_family == JLINKARM_DEV_FAMILY["XSCALE"]:
print("XScale identified.")
return 0 # O.K.
elif device_family == JLINKARM_DEV_FAMILY["CM0"]:
print("Cortex-M0 identified.")
return 0 # O.K.
elif device_family == JLINKARM_DEV_FAMILY["CORTEX_A8"]:
print("Cortex-A8 identified.")
return 0 # O.K.
elif device_family == JLINKARM_DEV_FAMILY["ARM10"]:
print("ARM10 identified.")
return 0 # O.K.
elif device_family == JLINKARM_DEV_FAMILY["CORTEX_R4"]:
print("Cortex-R4 identified.")
return 0 # O.K.
elif device_family == JLINKARM_DEV_FAMILY["RX"]:
print("Renesas RX core identified.")
return 0 # O.K.
elif device_family == JLINKARM_DEV_FAMILY["CM4"]:
print("Cortex-M4 identified.")
return 0 # O.K.
elif device_family == JLINKARM_DEV_FAMILY["CORTEX_A5"]:
print("Cortex-A5 identified.")
return 0 # O.K.
elif device_family == JLINKARM_DEV_FAMILY["POWER_PC"]:
print("PowerPC identified.")
return 0 # O.K.
elif device_family == JLINKARM_DEV_FAMILY["MIPS"]:
print("MIPS architecture identified.")
return 0 # O.K.
elif device_family == JLINKARM_DEV_FAMILY["EFM8"]:
print("SiLabs EFM8 identified.")
return 0 # O.K.
elif device_family == JLINKARM_DEV_FAMILY["RISC_V"]:
print("RISC-V identified.")
return 0 # O.K.
elif device_family == JLINKARM_DEV_FAMILY["CORTEX_AR_ARMV8"]:
print("ARMv8A/R identified.")
return 0 # O.K.
elif device_family == JLINKARM_DEV_FAMILY["BT5511"]:
print("Microchip BT5511 identified.")
return 0 # O.K.
elif device_family == JLINKARM_DEV_FAMILY["ANY"]:
print("Any device family identified.")
return 0 # O.K.
else:
print("Unknown device family.")
return -1 # Error
# 定义处理函数
def error_warn_handler(message):
# 将 C 字符串转换为 Python 字符串
message_str = message.decode('utf-8')
print("Error/Warning:", message_str)
# 定义日志处理函数
def log_handler(message):
message_str = message.decode('utf-8')
print("Log:", message_str)
# 定义错误处理函数
def error_handler(message):
message_str = message.decode('utf-8')
print("Error:", message_str)
def read_memory(jlink, start_addr, num_bytes, access_width=0):
# 创建一个缓冲区来存储读取的数据
buffer_type = (ctypes.c_ubyte * num_bytes)() # 使用 c_ubyte 数组
buffer_address = ctypes.cast(buffer_type, ctypes.c_void_p) # 获取缓冲区的地址
# 调用 JLINKARM_ReadMemEx 函数
result = jlink.JLINKARM_ReadMemEx(start_addr, num_bytes, buffer_address, access_width)
# 判断结果
if result > 0:
print(f"Reading {num_bytes} bytes from addr 0x{start_addr:X}... O.K.")
return buffer_type # 返回读取到的缓冲区
else:
raise JLinkException(f"Memory read failed with error code: {result}") # 建议引发异常,而不是返回 None
def save_to_file(buffer, file_path):
"""将缓冲区内容保存到文件"""
with open(file_path, 'wb') as f:
f.write(buffer) # 写入二进制数据
print(f"Data has been saved to '{file_path}'.")
def run_jlink_script(dll_path, axf_path, start_address, length, device_name):
"""
运行 JLink 脚本,连接到设备,读取寄存器和内存,并将结果保存到文件。
"""
try:
# 加载 JLinkARM DLL
jlink = ctypes.CDLL(dll_path)
#所有 JLink 函数的 restype 和 argtypes 配置
jlink.JLINKARM_OpenEx.restype = ctypes.c_char_p
jlink.JLINKARM_Open.restype = ctypes.c_char_p
jlink.JLINKARM_GetFirmwareString.argtypes = [ctypes.c_char_p, ctypes.c_int]
jlink.JLINKARM_GetHardwareVersion.restype = ctypes.c_int
jlink.JLINKARM_GetSN.restype = ctypes.c_int
jlink.JLINKARM_GetFeatureString.argtypes = [ctypes.c_char_p] # Fix: Add argtypes
jlink.JLINKARM_SelectUSB.restype = None # Or appropriate return type
jlink.JLINK_GetpFunc.restype = ctypes.c_void_p
jlink.JLINKARM_DEVICE_GetIndex.argtypes = [ctypes.c_char_p]
jlink.JLINKARM_DEVICE_GetInfo.restype = ctypes.c_int
jlink.JLINKARM_ConfigJTAG.argtypes = [ctypes.c_uint, ctypes.c_uint]
jlink.JLINKARM_ExecCommand.restype = ctypes.c_int
jlink.JLINKARM_ExecCommand.argtypes = [ctypes.c_char_p, ctypes.c_char_p, ctypes.c_int]
jlink.JLINKARM_GetEmuCapsEx.argtypes = [ctypes.POINTER(ctypes.c_uint8), ctypes.c_int]
jlink.JLINKARM_TIF_GetAvailable.argtypes = [ctypes.POINTER(ctypes.c_uint32)]
jlink.JLINKARM_TIF_Select.argtypes = [ctypes.c_int]
jlink.JLINKARM_IsConnected.restype = ctypes.c_int
jlink.JLINKARM_SetSpeed.argtypes = [ctypes.c_uint32]
jlink.JLINKARM_GetIdData.argtypes = [ctypes.POINTER(JTAG_ID_DATA)]
jlink.JLINKARM_HasError.restype = ctypes.c_int
jlink.JLINKARM_CORE_GetFound.restype = ctypes.c_int
jlink.JLINKARM_Core2CoreName.argtypes = [ctypes.c_int, ctypes.c_char_p, ctypes.c_int]
jlink.JLINKARM_Halt.restype = ctypes.c_int
jlink.JLINKARM_GetDeviceFamily.restype = ctypes.c_int
jlink.JLINKARM_GetDebugInfo.restype = ctypes.c_int
jlink.JLINKARM_GetDebugInfo.argtypes = [ctypes.c_int, ctypes.POINTER(ctypes.c_uint32)]
jlink.JLINKARM_ReadRegs.restype = ctypes.c_int
jlink.JLINKARM_ReadRegs.argtypes = [ctypes.POINTER(ctypes.c_uint32), ctypes.POINTER(ctypes.c_uint32), ctypes.c_void_p, ctypes.c_int]
jlink.JLINKARM_ReadMemEx.argtypes = [ctypes.c_uint32, ctypes.c_uint32, ctypes.c_void_p, ctypes.c_uint32]
jlink.JLINKARM_ReadMemEx.restype = ctypes.c_int
jlink.JLINKARM_IsOpen.restype = ctypes.c_int
jlink.JLINKARM_Close.restype = None # Or appropriate return type
jlink.JLINKARM_Connect.restype = ctypes.c_int # Ensure correct return type for JLINKARM_Connect
# 设置 JLINKARM_GetDLLVersion 的返回类型
jlink.JLINKARM_GetDLLVersion.restype = ctypes.c_int
# 获取 DLL 版本号
Ver = jlink.JLINKARM_GetDLLVersion()
# 解析主版本号、次版本号和补丁字母
major = Ver // 10000 # 主版本号
minor = (Ver // 100) % 100 # 次版本号
patch_letter = chr(ord('a') + Ver % 100 - 1) if Ver % 100 > 0 else '' # 补丁字母
# 打印出格式化的版本信息
print(f"J-Link DLL Version: {major}.{minor:02}{patch_letter}")
# 设置 JLINKARM_GetCompileDateTime 的返回类型为 c_char_p
jlink.JLINKARM_GetCompileDateTime.restype = ctypes.c_char_p
# 调用函数并获取返回值
compile_date_time = jlink.JLINKARM_GetCompileDateTime()
# 将 C 字符串转换为 Python 字符串
compile_date_time_str = compile_date_time.decode('utf-8') # 如果使用其他编码,可以相应调整
# 打印返回的编译日期时间
print("Compile Date and Time:", compile_date_time_str)
# --- 错误和日志处理函数 ---
ErrorWarnHandlerType = ctypes.CFUNCTYPE(None, ctypes.c_char_p)
LogHandlerType = ctypes.CFUNCTYPE(None, ctypes.c_char_p)
# 创建处理函数的函数指针
handler_pointer = ErrorWarnHandlerType(error_warn_handler)
# 将函数指针传递给 JLINKARM_SetWarnOutHandler
jlink.JLINKARM_SetWarnOutHandler(handler_pointer)
# 定义日志处理函数的原型
LogHandlerType = ctypes.CFUNCTYPE(None, ctypes.c_char_p)
# 创建处理函数的函数指针
log_handler_pointer = LogHandlerType(log_handler)
error_handler_pointer = LogHandlerType(error_handler)
# 调用 JLINKARM_OpenEx 并传入函数指针
result = jlink.JLINKARM_OpenEx(log_handler_pointer, error_handler_pointer)
# 将返回值转换为 Python 字符串
result_str = result.decode('utf-8') if result else "No result"
print("JLINKARM_OpenEx result:", result_str)
# 调用函数并获取返回值
test_open_log = jlink.JLINKARM_Open()
# 检查返回值是否为 NULL
if test_open_log is None:
print("Connecting to J-Link via USB...O.K.") # 仅在成功时打印相关字符串
else:
# 这里可以处理 test_open_log
test_open_log_str = ctypes.cast(test_open_log, ctypes.c_char_p).value.decode('utf-8')
print("Log String:", test_open_log_str) # 仅在成功时打印相关字符串
# 创建一个字符数组的缓冲区,大小为 256 字节
firmware_string_buffer = ctypes.create_string_buffer(256)
# 调用 JLINKARM_GetFirmwareString,传入字符数组和大小
jlink.JLINKARM_GetFirmwareString(firmware_string_buffer, 256)
# 从缓冲区获取固件字符串
firmware_string = firmware_string_buffer.value.decode('utf-8') # 解码为 Python 字符串
# 打印固件字符串
print("Firmware:", firmware_string)
# 调用函数并获取返回值
version = jlink.JLINKARM_GetHardwareVersion()
# 解析主版本号、次版本号和补丁字母
major = version // 10000 # 主版本号
minor = (version // 100) % 100 # 次版本号
# 打印出格式化的版本信息
print(f"J-Link Hardware Version: V{major}.{minor:02}")
# 调用JLINKARM_GetSN获取并打印J-Link序列号
print("S/N:", jlink.JLINKARM_GetSN())
# 创建一个字符数组的缓冲区,大小为 256 字节
firmware_string_buffer = ctypes.create_string_buffer(256)
jlink.JLINKARM_GetFeatureString(firmware_string_buffer)
firmware_string = firmware_string_buffer.value.decode('utf-8') # 解码为 Python 字符串
print("License(s):", firmware_string)
jlink.JLINKARM_EMU_GetProductId.restype = ctypes.c_int
print("JLINKARM_EMU_GetProductId:", jlink.JLINKARM_EMU_GetProductId())
jlink.JLINKARM_SelectUSB()
# 使用 ctypes 定义一个函数指针类型
ErrorWarnHandlerType = ctypes.CFUNCTYPE(None, ctypes.c_char_p)
# 创建处理函数的函数指针
handler_pointer = ErrorWarnHandlerType(error_warn_handler)
# 将函数指针传递给 JLINKARM_SetWarnOutHandler
jlink.JLINKARM_SetWarnOutHandler(handler_pointer)
# 定义日志处理函数的原型
# 假设处理函数的原型是 void (*handler)(const char*)
LogHandlerType = ctypes.CFUNCTYPE(None, ctypes.c_char_p)
# 创建处理函数的函数指针
log_handler_pointer = LogHandlerType(log_handler)
error_handler_pointer = LogHandlerType(error_handler)
# 调用 JLINKARM_OpenEx 并传入函数指针
result = jlink.JLINKARM_OpenEx(log_handler_pointer, error_handler_pointer)
# 将返回值转换为 Python 字符串
result_str = result.decode('utf-8') if result else "No result"
print("JLINKARM_OpenEx result:", result_str)
print("JLINK_GetpFunc:", jlink.JLINK_GetpFunc(4))
# 定义设备名称
device_name = "GD32F303ZE"
# 将 Python 字符串转换为 C 字符串(使用 UTF-8 编码)
c_device_name = ctypes.create_string_buffer(device_name.encode('utf-8'))
# 调用函数并获取返回值
device_index = jlink.JLINKARM_DEVICE_GetIndex(c_device_name)
# 打印设备索引
print("Device Index for {}: {}".format(device_name, device_index))
num_devices = jlink.JLINKARM_DEVICE_GetInfo(-1, None)
# 打印支持的设备数量
print("Following {} devices are supported:".format(num_devices))
# 定义参数
param1 = ctypes.c_uint(0xFFFFFFFF)
param2 = ctypes.c_uint(0xFFFFFFFF)
# 调用 JLINKARM_ConfigJTAG 函数
result = jlink.JLINKARM_ConfigJTAG(param1, param2)
# 创建 acCmd 和 acOut 的缓冲区
acCmd = ctypes.create_string_buffer(b"Device = GD32F303ZE", 256)
acOut = ctypes.create_string_buffer(256)
# 调用 JLINKARM_ExecCommand
r = jlink.JLINKARM_ExecCommand(acCmd, acOut, ctypes.c_int(len(acOut)))
if acOut.value == b"": # acOut[0] == 0 表示命令成功执行,没有错误信息
print("Command executed successfully!")
print("Return value of command:", r)
else:
print("Failed to execute command!")
print("Output:", acOut.value.decode('utf-8'))
# 定义所需的常量
JLINKARM_CAP_EX_HW_JTAG_WRITE = 32 #
# 创建一个 32 字节的缓冲区 ab,用于接收 JLINKARM_GetEmuCapsEx 的返回值
ab = (ctypes.c_uint8 * 32)()
# 调用 JLINKARM_GetEmuCapsEx,直接传递 ab 数组
jlink.JLINKARM_GetEmuCapsEx(ab, ctypes.c_int(len(ab)))
# 计算 Byte 和 Bit
CapEx = JLINKARM_CAP_EX_HW_JTAG_WRITE
Byte = CapEx >> 3
Bit = CapEx & 7
# 检查指定的功能是否受支持
if ab[Byte] & (1 << Bit):
print("Emulator supports the requested capability.")
result = 1
else:
print("Requested capability is not supported by the emulator.")
result = 0
# 输出结果
print("Result:", result)
print("========================")
# --- 连接到设备 ---
# 获取可用的调试接口
mask = ctypes.c_uint32()
jlink.JLINKARM_TIF_GetAvailable(ctypes.byref(mask))
print("Interface available:",mask)
# 检查 SWD 是否可用
if mask.value & (1 << 1):
# 选择 SWD 接口
jlink.JLINKARM_TIF_Select(1)
print("SWD interface selected.")
if not jlink.JLINKARM_IsConnected():
print("JTAG is connected")
else:
print("JTAG is not connected")
print("SetSpeed(4000)")
jlink.JLINKARM_SetSpeed(4000)
print("====JTAG Connectting====")
# 调用JLINKARM_Connect
jlink.JLINKARM_Connect()
else:
print("SWD interface is not supported by connected J-Link!")
# 创建 JTAG_ID_DATA 结构体实例
id_data = JTAG_ID_DATA()
# 调用函数
jlink.JLINKARM_GetIdData(ctypes.byref(id_data))
# 打印结果
print(f"Number of Devices: {id_data.NumDevices}")
print(f"Scan Length: {id_data.ScanLen}")
for i in range(id_data.NumDevices):
print(f"Device ID[{i}]: 0x{id_data.aId[i]:X}")
print(f"Scan Length[{i}]: {id_data.aScanLen[i]}")
print(f"IR Read[{i}]: {id_data.aIrRead[i]}")
print(f"Scan Read[{i}]: {id_data.aScanRead[i]}")
#JLINK_GetMemZones 没处理
#HasError
print("DLL internal error state:",jlink.JLINKARM_HasError())
#CORE_GetFound
CORE = jlink.JLINKARM_CORE_GetFound()
print("CORE_GetFound:",CORE)
# 创建一个字符数组的缓冲区,大小为 256 字节
core_string_buffer = ctypes.create_string_buffer(50)
jlink.JLINKARM_Core2CoreName(CORE,core_string_buffer,50)
# 解码为 Python 字符串
print("Core Name:", core_string_buffer.value.decode('utf-8'))
#Halt
print("Halt:", jlink.JLINKARM_Halt())
#Get Family
print("DeviceFamily:", jlink.JLINKARM_GetDeviceFamily())
CORE = jlink.JLINKARM_CORE_GetFound()
identify_device_family(jlink.JLINKARM_GetDeviceFamily())
# 定义常量
JLINKARM_ROM_TABLE_ADDR_INDEX = 0x100 # 根据你的实际值进行调整
# 准备参数
ROMTableAddr = ctypes.c_uint32() # 创建一个U32类型的变量来接收结果
index = JLINKARM_ROM_TABLE_ADDR_INDEX # 使用预定义的索引
# 调用JLINKARM_GetDebugInfo
r = jlink.JLINKARM_GetDebugInfo(index, ctypes.byref(ROMTableAddr)) # 通过引用传递地址
# 根据返回值进行输出
if r == 0:
print(f"ROMTableAddr = 0x{ROMTableAddr.value:X}") # 打印地址
else:
print(f"No debug information for index 0x{index:04X} available on this CPU.")
# --- 读取寄存器 ---
# 定义ctypes数组,将枚举值直接放入其中
num_indices = len(reg_indices)
print("num:",num_indices)
#reg_indices_array = (ctypes.c_uint32 * num_indices)(*map(lambda reg: reg.value, reg_indices))
# 获取寄存器索引的数量
reg_indices_values = []
for reg in reg_indices:
try:
reg_value = reg.value # 获取寄存器值
reg_indices_values.append(reg_value)
except AttributeError:
print(f"Warning: The register object does not have 'value' attribute: {reg}")
# 创建 ctypes 数组,存储寄存器索引值
reg_indices_array = (ctypes.c_uint32 * num_indices)(*reg_indices_values)
# 定义aRegData数组,假设我们需要读取5个寄存器值
aRegData = (ctypes.c_uint32 * (num_indices))()
# 调用JLINKARM_ReadRegs,传入数组首地址
reg_data = jlink.JLINKARM_ReadRegs(reg_indices_array, aRegData, None, num_indices)
print("************************ Register information ************************")
# output_lines = []
# for i, reg_index in enumerate(reg_indices):
# try:
# reg_value = aRegData[i] # 获取对应的寄存器值
# reg_name = reg_index.name.replace('JLINKARM_CM4_REG_', '') # 去掉前缀
# output_lines.append(f"{reg_name:<15} = {reg_value:08X}") # 使用左对齐
# except IndexError as e:
# print(f"Index error for reg_index {reg_index}: {e}")
# except Exception as e:
# print(f"An error occurred while processing index {i}: {e}")
# 输出结果
output_lines = []
for i, reg_index in enumerate(reg_indices):
reg_value = aRegData[i] # 获取对应的寄存器值
reg_name = reg_index.name.replace('JLINKARM_CM4_REG_', '') # 去掉前缀
output_lines.append(f"{reg_name:}={reg_value:08X}") # 使用左对齐
# print("output_lines:", output_lines)
# 每4个元素后换行
formatted_lines = []
for i in range(0, len(output_lines), 4):
# 将每四个元素拼接成一行
line = ', '.join(output_lines[i:i + 4])
formatted_lines.append(line) # 添加到格式化后的行列表中
# 定义registers.txt要保存的文件路径
registers_txt_path = os.path.join(os.path.dirname(axf_path), 'registers.txt')
registers_txt_path = os.path.normpath(registers_txt_path)
reg_info = formatted_lines
# 添加SP和PC的打印信息
sp_value = f"{aRegData[JLINKARM_CM4_REG.JLINKARM_CM4_REG_R13.value]:08X}"
pc_value = f"{aRegData[JLINKARM_CM4_REG.JLINKARM_CM4_REG_R15.value]:08X}"
lr_value = f"{aRegData[JLINKARM_CM4_REG.JLINKARM_CM4_REG_R14.value]:08X}"
reg_info_line = f"PC = {pc_value}, SP(R13) = {sp_value}, R14(LR) = {lr_value}"
# 将组合好的行插入到 reg_info 列表的开头
reg_info.insert(0, reg_info_line)
# 将 formatted_lines 内容保存到文件
with open(registers_txt_path, 'w') as file:
for line in reg_info:
file.write(line + '\n') # 每行后添加换行符
print(f"Formatted lines have been saved to '{registers_txt_path}'.")
print('=' * len(formatted_lines[1]))
# 每4行后添加分隔符,分隔符的长度与上一行相同
for i in range(4, len(formatted_lines)+5, 5): # 从第0行开始,每5行插入一次分隔符
previous_line_length = len(formatted_lines[i - 1]) # 获取上一行的字符数
separator = '-' * previous_line_length # 根据上一行的长度生成分隔符
formatted_lines.insert(i, separator) # 在适当的位置插入分隔符
# 通过换行连接结果
output_string = '\n'.join(formatted_lines) # 每行的结果通过换行连接
print(output_string)
print('=' * previous_line_length)
# --- 读取并保存内存 ---
start_address = int(start_address, 0)
length = int(length, 0)
buffer = read_memory(jlink, start_address, length) # 注意这里传入 jlink 对象
if buffer:
save_to_file(buffer, os.path.normpath(os.path.join(os.path.dirname(axf_path), "ram.bin")))
# --- 关闭 J-Link 连接 ---
jlink.JLINKARM_Close()
print("J-Link closed")
except JLinkException as e:
raise # 重新引发 JLink 异常
except Exception as e:
raise # 重新引发其他异常
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。