4
4
5
5
'''Runner for openocd.'''
6
6
7
+ import subprocess
8
+ import re
9
+
7
10
from os import path
8
11
from pathlib import Path
9
12
@@ -38,13 +41,14 @@ def __init__(self, cfg, pre_init=None, pre_load=None,
38
41
self .openocd_config = config
39
42
40
43
search_args = []
41
- for i in self .openocd_config :
42
- if path .exists (i ):
43
- search_args .append ('-s' )
44
- search_args .append (path .dirname (i ))
45
-
46
- if cfg .openocd_search is not None :
47
- search_args .extend (['-s' , cfg .openocd_search ])
44
+ if self .openocd_config is not None :
45
+ for i in self .openocd_config :
46
+ if path .exists (i ):
47
+ search_args .append ('-s' )
48
+ search_args .append (path .dirname (i ))
49
+
50
+ for p in cfg .openocd_search :
51
+ search_args .extend (['-s' , p ])
48
52
self .openocd_cmd = [cfg .openocd ] + search_args
49
53
# openocd doesn't cope with Windows path names, so convert
50
54
# them to POSIX style just to be sure.
@@ -117,16 +121,56 @@ def do_create(cls, cfg, args):
117
121
tcl_port = args .tcl_port , telnet_port = args .telnet_port ,
118
122
gdb_port = args .gdb_port )
119
123
124
+ def print_gdbserver_message (self ):
125
+ if not self .thread_info_enabled :
126
+ thread_msg = '; no thread info available'
127
+ elif self .supports_thread_info ():
128
+ thread_msg = '; thread info enabled'
129
+ else :
130
+ thread_msg = '; update OpenOCD software for thread info'
131
+ self .logger .info ('OpenOCD GDB server running on port '
132
+ f'{ self .gdb_port } { thread_msg } ' )
133
+
134
+ # pylint: disable=R0201
135
+ def to_num (self , number ):
136
+ dev_match = re .search (r"^\d*\+dev" , number )
137
+ dev_version = not dev_match is None
138
+
139
+ num_match = re .search (r"^\d*" , number )
140
+ num = int (num_match .group (0 ))
141
+
142
+ if dev_version :
143
+ num += 1
144
+
145
+ return num
146
+
147
+ def read_version (self ):
148
+ self .require (self .openocd_cmd [0 ])
149
+
150
+ # OpenOCD prints in stderr, need redirect to get output
151
+ out = self .check_output ([self .openocd_cmd [0 ], '--version' ],
152
+ stderr = subprocess .STDOUT ).decode ()
153
+
154
+ return out .split ('\n ' )[0 ]
155
+
156
+ def supports_thread_info (self ):
157
+ # Zephyr rtos was introduced after 0.11.0
158
+ version_str = self .read_version ().split (' ' )[3 ]
159
+ version = version_str .split ('.' )
160
+ (major , minor , rev ) = [self .to_num (i ) for i in version ]
161
+ return (major , minor , rev ) > (0 , 11 , 0 )
162
+
120
163
def do_run (self , command , ** kwargs ):
121
164
self .require (self .openocd_cmd [0 ])
122
165
if ELFFile is None :
123
166
raise RuntimeError (
124
167
'elftools missing; please "pip3 install elftools"' )
125
168
126
169
self .cfg_cmd = []
127
- for i in self .openocd_config :
128
- self .cfg_cmd .append ('-f' )
129
- self .cfg_cmd .append (i )
170
+ if self .openocd_config is not None :
171
+ for i in self .openocd_config :
172
+ self .cfg_cmd .append ('-f' )
173
+ self .cfg_cmd .append (i )
130
174
131
175
if command == 'flash' and self .use_elf :
132
176
self .do_flash_elf (** kwargs )
@@ -213,6 +257,10 @@ def do_attach_debug(self, command, **kwargs):
213
257
pre_init_cmd .append ("-c" )
214
258
pre_init_cmd .append (i )
215
259
260
+ if self .thread_info_enabled and self .supports_thread_info ():
261
+ pre_init_cmd .append ("-c" )
262
+ pre_init_cmd .append ("$_TARGETNAME configure -rtos Zephyr" )
263
+
216
264
server_cmd = (self .openocd_cmd + self .serial + self .cfg_cmd +
217
265
['-c' , 'tcl_port {}' .format (self .tcl_port ),
218
266
'-c' , 'telnet_port {}' .format (self .telnet_port ),
@@ -225,6 +273,7 @@ def do_attach_debug(self, command, **kwargs):
225
273
if command == 'debug' :
226
274
gdb_cmd .extend (['-ex' , 'load' ])
227
275
self .require (gdb_cmd [0 ])
276
+ self .print_gdbserver_message ()
228
277
self .run_server_and_client (server_cmd , gdb_cmd )
229
278
230
279
def do_debugserver (self , ** kwargs ):
@@ -240,4 +289,5 @@ def do_debugserver(self, **kwargs):
240
289
pre_init_cmd + ['-c' , 'init' ,
241
290
'-c' , 'targets' ,
242
291
'-c' , 'reset halt' ])
292
+ self .print_gdbserver_message ()
243
293
self .check_call (cmd )
0 commit comments