4
4
5
5
'''Runner for debugging with J-Link.'''
6
6
7
- from .core import ZephyrBinaryRunner , RunnerCaps
7
+ import os
8
+ import tempfile
9
+ from .core import ZephyrBinaryRunner , RunnerCaps , BuildConfiguration
8
10
9
11
DEFAULT_JLINK_GDB_PORT = 2331
10
12
@@ -13,11 +15,17 @@ class JLinkBinaryRunner(ZephyrBinaryRunner):
13
15
'''Runner front-end for the J-Link GDB server.'''
14
16
15
17
def __init__ (self , device ,
18
+ commander = 'JLinkExe' , bin_name = None ,
19
+ flash_addr = 0x0 , erase = True ,
16
20
gdbserver = 'JLinkGDBServer' , iface = 'swd' , speed = 'auto' ,
17
21
elf_name = None , gdb = None , gdb_port = DEFAULT_JLINK_GDB_PORT ,
18
22
tui = False , debug = False ):
19
23
super (JLinkBinaryRunner , self ).__init__ (debug = debug )
20
24
self .device = device
25
+ self .commander = commander
26
+ self .bin_name = bin_name
27
+ self .flash_addr = flash_addr
28
+ self .erase = erase
21
29
self .gdbserver_cmd = [gdbserver ]
22
30
self .iface = iface
23
31
self .speed = speed
@@ -32,7 +40,7 @@ def name(cls):
32
40
33
41
@classmethod
34
42
def capabilities (cls ):
35
- return RunnerCaps (commands = { 'debug' , 'debugserver' } )
43
+ return RunnerCaps (flash_addr = True )
36
44
37
45
@classmethod
38
46
def do_add_parser (cls , parser ):
@@ -51,10 +59,19 @@ def do_add_parser(cls, parser):
51
59
parser .add_argument ('--gdb-port' , default = DEFAULT_JLINK_GDB_PORT ,
52
60
help = 'pyocd gdb port, defaults to {}' .format (
53
61
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' )
54
66
55
67
@classmethod
56
68
def create_from_args (cls , args ):
69
+ build_conf = BuildConfiguration (os .getcwd ())
70
+ flash_addr = cls .get_flash_address (args , build_conf )
57
71
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 ,
58
75
iface = args .iface , speed = args .speed ,
59
76
elf_name = args .kernel_elf ,
60
77
gdb = args .gdb , gdb_port = args .gdb_port ,
@@ -73,7 +90,9 @@ def do_run(self, command, **kwargs):
73
90
'-silent' ,
74
91
'-singlerun' ])
75
92
76
- if command == 'debugserver' :
93
+ if command == 'flash' :
94
+ self .flash (** kwargs )
95
+ elif command == 'debugserver' :
77
96
self .print_gdbserver_message ()
78
97
self .check_call (server_cmd )
79
98
else :
@@ -90,3 +109,30 @@ def do_run(self, command, **kwargs):
90
109
'-ex' , 'load' ])
91
110
self .print_gdbserver_message ()
92
111
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