Skip to content

Commit 9f57d11

Browse files
MaureenHelmAnas Nashif
authored andcommitted
scripts: jlink: Add flash command support to the jlink runner
Adds support for the 'flash' command to the jlink runner so we can flash via 'make flash'. This works by generating a temporary jlink commander script file and passing the script to the jlink commander executable. Previously, the only way to flash with jlink was via 'make debug'. Includes support for DT based flash address, and an optional mass erase before loading the flash. Signed-off-by: Maureen Helm <[email protected]>
1 parent 77755af commit 9f57d11

File tree

2 files changed

+51
-4
lines changed

2 files changed

+51
-4
lines changed

boards/common/jlink.board.cmake

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
1+
set_ifndef(BOARD_FLASH_RUNNER jlink)
12
set_ifndef(BOARD_DEBUG_RUNNER jlink)
2-
board_finalize_runner_args(jlink) # No default arguments to provide.
3+
board_finalize_runner_args(jlink "--dt-flash=y")

scripts/support/runner/jlink.py

Lines changed: 49 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44

55
'''Runner for debugging with J-Link.'''
66

7-
from .core import ZephyrBinaryRunner, RunnerCaps
7+
import os
8+
import tempfile
9+
from .core import ZephyrBinaryRunner, RunnerCaps, BuildConfiguration
810

911
DEFAULT_JLINK_GDB_PORT = 2331
1012

@@ -13,11 +15,17 @@ class JLinkBinaryRunner(ZephyrBinaryRunner):
1315
'''Runner front-end for the J-Link GDB server.'''
1416

1517
def __init__(self, device,
18+
commander='JLinkExe', bin_name=None,
19+
flash_addr=0x0, erase=True,
1620
gdbserver='JLinkGDBServer', iface='swd', speed='auto',
1721
elf_name=None, gdb=None, gdb_port=DEFAULT_JLINK_GDB_PORT,
1822
tui=False, debug=False):
1923
super(JLinkBinaryRunner, self).__init__(debug=debug)
2024
self.device = device
25+
self.commander = commander
26+
self.bin_name = bin_name
27+
self.flash_addr = flash_addr
28+
self.erase = erase
2129
self.gdbserver_cmd = [gdbserver]
2230
self.iface = iface
2331
self.speed = speed
@@ -32,7 +40,7 @@ def name(cls):
3240

3341
@classmethod
3442
def capabilities(cls):
35-
return RunnerCaps(commands={'debug', 'debugserver'})
43+
return RunnerCaps(flash_addr=True)
3644

3745
@classmethod
3846
def do_add_parser(cls, parser):
@@ -51,10 +59,19 @@ def do_add_parser(cls, parser):
5159
parser.add_argument('--gdb-port', default=DEFAULT_JLINK_GDB_PORT,
5260
help='pyocd gdb port, defaults to {}'.format(
5361
DEFAULT_JLINK_GDB_PORT))
62+
parser.add_argument('--commander', default='JLinkExe',
63+
help='J-Link Commander, default is JLinkExe')
64+
parser.add_argument('--erase', default=True, action='store_false',
65+
help='erase flash before loading, default is true')
5466

5567
@classmethod
5668
def create_from_args(cls, args):
69+
build_conf = BuildConfiguration(os.getcwd())
70+
flash_addr = cls.get_flash_address(args, build_conf)
5771
return JLinkBinaryRunner(args.device, gdbserver=args.gdbserver,
72+
commander=args.commander,
73+
bin_name=args.kernel_bin,
74+
flash_addr=flash_addr, erase=args.erase,
5875
iface=args.iface, speed=args.speed,
5976
elf_name=args.kernel_elf,
6077
gdb=args.gdb, gdb_port=args.gdb_port,
@@ -73,7 +90,9 @@ def do_run(self, command, **kwargs):
7390
'-silent',
7491
'-singlerun'])
7592

76-
if command == 'debugserver':
93+
if command == 'flash':
94+
self.flash(**kwargs)
95+
elif command == 'debugserver':
7796
self.print_gdbserver_message()
7897
self.check_call(server_cmd)
7998
else:
@@ -90,3 +109,30 @@ def do_run(self, command, **kwargs):
90109
'-ex', 'load'])
91110
self.print_gdbserver_message()
92111
self.run_server_and_client(server_cmd, client_cmd)
112+
113+
def flash(self, **kwargs):
114+
if self.bin_name is None:
115+
raise ValueError('Cannot flash; bin_name is missing')
116+
117+
lines = ['r'] # Reset and halt the target
118+
119+
if self.erase:
120+
lines.append('erase') # Erase all flash sectors
121+
122+
lines.append('loadfile {} 0x{:x}'.format(self.bin_name,
123+
self.flash_addr))
124+
lines.append('g') # Start the CPU
125+
lines.append('q') # Close the connection and quit
126+
127+
with tempfile.NamedTemporaryFile(suffix='.jlink') as f:
128+
f.writelines(bytes(line + '\n', 'utf-8') for line in lines)
129+
f.flush()
130+
131+
cmd = ([self.commander] +
132+
['-if', self.iface,
133+
'-speed', self.speed,
134+
'-device', self.device,
135+
'-CommanderScript', f.name])
136+
137+
print('Flashing Target Device')
138+
self.check_call(cmd)

0 commit comments

Comments
 (0)