-
Notifications
You must be signed in to change notification settings - Fork 105
Expand file tree
/
Copy pathjlink.py
More file actions
155 lines (107 loc) · 4.25 KB
/
jlink.py
File metadata and controls
155 lines (107 loc) · 4.25 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
import ctypes
class JLink(object):
def __init__(self, dllpath, mode='arm', core='Cortex-M0', speed=4000):
self.jlk = ctypes.cdll.LoadLibrary(dllpath)
self.open(mode, core, speed)
def open(self, mode='arm', core='Cortex-M0', speed=4000):
self.mode = mode.lower()
self.jlk.JLINKARM_Open()
if not self.jlk.JLINKARM_IsOpen():
raise Exception('No JLink connected')
err_buf = (ctypes.c_char * 64)()
self.jlk.JLINKARM_ExecCommand(f'Device = {core}'.encode('latin-1'), err_buf, 64)
if self.mode == 'arm':
tif = TIF.SWD
elif self.mode == 'rv':
tif = TIF.CJTAG
elif self.mode in ('armj', 'rvj'):
tif = TIF.JTAG
else:
raise Exception('invalid mode value')
self.jlk.JLINKARM_TIF_Select(tif)
self.jlk.JLINKARM_SetSpeed(speed)
self.get_registers()
def get_registers(self):
buffer = (ctypes.c_uint32 * 0x4000)()
n_regs = self.jlk.JLINKARM_GetRegisterList(buffer, 0x4000)
self.jlk.JLINKARM_GetRegisterName.restype = ctypes.c_char_p
self.core_regs = {} # 'name: index' pair
for index in buffer[:n_regs]:
name = self.jlk.JLINKARM_GetRegisterName(index).decode()
self.core_regs[name] = index
def write_U8(self, addr, val):
self.jlk.JLINKARM_WriteU8(addr, val)
def write_U16(self, addr, val):
self.jlk.JLINKARM_WriteU16(addr, val)
def write_U32(self, addr, val):
self.jlk.JLINKARM_WriteU32(addr, val)
def write_U64(self, addr, val):
self.jlk.JLINKARM_WriteU64(addr, val)
def write_mem_U8(self, addr, data):
buffer = (ctypes.c_uint8 * len(data))(*data)
self.jlk.JLINKARM_WriteMem(addr, len(data), buffer)
def write_mem_U32(self, addr, data):
buffer = (ctypes.c_uint32 * len(data))(*data)
self.write_mem_U8(addr, bytes(buffer)) # MCU and PC both little-endian
def read_mem_U8(self, addr, count):
buffer = (ctypes.c_uint8 * count)()
self.jlk.JLINKARM_ReadMemU8(addr, count, buffer, 0)
return buffer[:]
def read_mem_U16(self, addr, count):
buffer = (ctypes.c_uint16 * count)()
self.jlk.JLINKARM_ReadMemU16(addr, count, buffer, 0)
return buffer[:]
def read_mem_U32(self, addr, count):
buffer = (ctypes.c_uint32 * count)()
self.jlk.JLINKARM_ReadMemU32(addr, count, buffer, 0)
return buffer[:]
def read_mem_U64(self, addr, count):
buffer = (ctypes.c_uint64 * count)()
self.jlk.JLINKARM_ReadMemU64(addr, count, buffer, 0)
return buffer[:]
def read_U32(self, addr):
return self.read_mem_U32(addr, 1)[0]
def read_U64(self, addr):
return self.read_mem_U64(addr, 1)[0]
def read_reg(self, reg):
val = self.jlk.JLINKARM_ReadReg(self.core_regs[reg])
if val < 0:
val += 1 << 32
return val
def read_regs(self, rlist):
regIndex = [self.core_regs[reg] for reg in rlist]
regIndex = (ctypes.c_uint32 * len(regIndex))(*regIndex)
regValue = (ctypes.c_uint32 * len(regIndex))()
self.jlk.JLINKARM_ReadRegs(regIndex, regValue, 0, len(regIndex))
return dict(zip(rlist, regValue[:]))
def write_reg(self, reg, val):
self.jlk.JLINKARM_WriteReg(self.core_regs[reg], val)
def reset(self):
self.jlk.JLINKARM_Reset()
def halt(self):
self.jlk.JLINKARM_Halt()
def step(self):
self.jlk.JLINKARM_Step()
def go(self):
self.jlk.JLINKARM_Go()
def halted(self):
return self.jlk.JLINKARM_IsHalted()
def close(self):
self.jlk.JLINKARM_Close()
class TIF:
JTAG = 0
SWD = 1
CJTAG = 7
if __name__ == '__main__':
jlk = JLink(r'D:\Program\Segger\JLink_V688\JLink_x64.dll')
jlk.halt()
res = jlk.read_mem_U32(0x20000000, 4)
print([f'{x:X}' for x in res])
jlk.write_U32(0x20000000, 0x12345678)
jlk.write_U32(0x20000004, 0x55555555)
jlk.write_U32(0x20000008, 0xAAAAAAAA)
jlk.write_U32(0x2000000C, 0x5A5A5A5A)
res = jlk.read_mem_U32(0x20000000, 4)
print([f'{x:X}' for x in res])
print(jlk.read_regs(['R15 (PC)', 'R14', 'R13 (SP)']))
print(jlk.core_regs)