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
911DEFAULT_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