Skip to content

Commit e0d5503

Browse files
authored
Merge pull request #295 from Infineon/bugfix/issue#266_cmdjlink_permission_denied
Bugfix/issue#266 cmdjlink permission denied Flashing script update: verify macOS, verbose log
2 parents ebabfa4 + 593cd19 commit e0d5503

File tree

2 files changed

+56
-29
lines changed

2 files changed

+56
-29
lines changed

platform.txt

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -148,9 +148,11 @@ recipe.size.regex.data=^(?:\.data|\.VENEER_Code|\.ram_code|\.bss|\.no_init|\Stac
148148
tools.xmcflasher.path={runtime.platform.path}/tools
149149
tools.xmcflasher.cmd.path={path}/xmc-flasher.py
150150
tools.xmcflasher.erase.params=-d XMC{build.board.version}-{build.board.v} -p {serial.port}
151-
tools.xmcflasher.erase.pattern=python {cmd.path} erase {upload.params}
151+
tools.xmcflasher.erase.pattern=python3 {cmd.path} erase {erase.params}
152+
tools.xmcflasher.erase.pattern.windows=python {cmd.path} erase {erase.params}
152153
tools.xmcflasher.upload.protocol=
153-
tools.xmcflasher.upload.params.verbose=
154+
tools.xmcflasher.upload.params.verbose=--verbose
154155
tools.xmcflasher.upload.params.quiet=
155-
tools.xmcflasher.upload.params=-d XMC{build.board.version}-{build.board.v} -p {serial.port} -f {build.path}/{build.project_name}.hex
156-
tools.xmcflasher.upload.pattern=python {cmd.path} upload {upload.params}
156+
tools.xmcflasher.upload.params=-d XMC{build.board.version}-{build.board.v} -p {serial.port} -f {build.path}/{build.project_name}.hex {upload.verbose}
157+
tools.xmcflasher.upload.pattern=python3 {cmd.path} upload {upload.params}
158+
tools.xmcflasher.upload.pattern.windows=python {cmd.path} upload {upload.params}

tools/xmc-flasher.py

Lines changed: 50 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
1-
import argparse, subprocess, os, sys, re, warnings
1+
import argparse, subprocess, os, sys, re, warnings, tempfile
22
from serial.tools.list_ports import comports
33
from xmc_data import xmc_master_data
44

5-
version = '0.1.1'
5+
version = '0.1.2'
66

77
jlinkexe = ''
88

9+
# Set temporary file for jlink command file and output file
10+
cmd_jlink = os.path.join(tempfile.gettempdir(), 'cmd.jlink')
11+
console_out = os.path.join(tempfile.gettempdir(), 'console.output')
12+
913
def check_python_version():
1014
major = sys.version_info.major
1115
minor = sys.version_info.minor
@@ -31,9 +35,7 @@ def set_environment():
3135
elif sys.platform == 'win32' or sys.platform == 'cygwin':
3236
jlinkexe = rf"{get_jlink_install_path()}\jlink.exe"
3337
elif sys.platform == 'darwin':
34-
jlinkexe = 'jlink'
35-
print('warning: mac os not validated')
36-
#raise Exception('mac os not supported?')
38+
jlinkexe = 'JLinkExe'
3739

3840
def discover_devices():
3941
ports = comports()
@@ -46,21 +48,18 @@ def discover_devices():
4648
def get_device_serial_number(port):
4749
port_sn_list = discover_devices()
4850
for device in port_sn_list:
49-
if device[0] == port:
50-
return device[1]
51-
51+
if device[0] == port and device[0] != None:
52+
return device[1]
5253
return None
5354

5455
def create_jlink_loadbin_command_file(binfile):
55-
cmd_jlink = 'cmd.jlink'
5656
cmd_load_bin = 'loadbin ' + binfile + ' 0x0\n'
5757
with open(cmd_jlink,'w') as f:
5858
f.writelines(['r\n', 'h\n', cmd_load_bin, 'r\n', 'g\n', 'exit\n'])
5959

6060
return cmd_jlink
6161

6262
def create_jlink_mem_read_command_file(addr, bytes):
63-
cmd_jlink = 'cmd.jlink'
6463
#cmd_log_enable
6564
cmd_mem_read = 'mem ' + addr +', '+ bytes + '\n' # todo: store register maps, bytes in file
6665
with open(cmd_jlink,'w') as f:
@@ -69,7 +68,6 @@ def create_jlink_mem_read_command_file(addr, bytes):
6968
return cmd_jlink
7069

7170
def create_jlink_erase_command_file():
72-
cmd_jlink = 'cmd.jlink'
7371
with open(cmd_jlink,'w') as f:
7472
f.writelines(['r\n', 'h\n', 'erase\n', 'exit\n'])
7573

@@ -93,7 +91,7 @@ def jlink_commander(device, serial_num, cmd_file, console_output=False):
9391
jlink_proc = subprocess.Popen(jlink_cmd, stdout=subprocess.PIPE, universal_newlines=True)
9492
if console_output is True:
9593
out, err = jlink_proc.communicate()
96-
with open('console.output', 'w') as f:
94+
with open(console_out, 'w') as f:
9795
f.write(out)
9896
else:
9997
for line in jlink_proc.stdout:
@@ -103,26 +101,33 @@ def jlink_commander(device, serial_num, cmd_file, console_output=False):
103101
raise Exception("jlink error")
104102

105103
def process_console_output(string):
106-
with open('console.output','r') as f:
104+
with open(console_out,'r') as f:
107105
lines = f.readlines()
108106
lines[0].split('\n')
109107

110108
for line in lines :
111109
if string in line and '=' in line:
112110
print(line)
113111

112+
def check_serial_number(serial_num):
113+
if serial_num == None:
114+
raise Exception("Device not found! Please check the serial port")
115+
114116
def get_mem_contents(addr, bytes, device, port):
115-
116-
serial_num = get_device_serial_number(port)
117+
try:
118+
serial_num = get_device_serial_number(port)
119+
check_serial_number(serial_num)
120+
except ValueError as e:
121+
print(e)
117122
jlink_cmd_file = create_jlink_mem_read_command_file(addr, bytes) # todo: comes from proper metafile
118123
jlink_commander(device, serial_num, jlink_cmd_file, True)
119124
remove_jlink_command_file(jlink_cmd_file)
120125

121-
with open('console.output','r') as f:
126+
with open(console_out,'r') as f:
122127
lines = f.readlines()
123128
lines[0].split('\n')
124129

125-
remove_console_output_file('console.output')
130+
remove_console_output_file(console_out)
126131

127132
reg_contents = ""
128133
for line in lines :
@@ -151,14 +156,13 @@ def check_device(device, port):
151156
device_value_masked = f'{device_value_masked:x}'
152157
device_value_masked = device_value_masked.zfill(int(master_data[device]['IDCHIP']['size'])*2)
153158

154-
print(f"Device is: {device.split('-')[0]}")
159+
print(f"Device is: {device.split('-')[0]}.")
155160

156161
#compare with stored master data
157162
if not device_value_masked == master_data[device]['IDCHIP']['value']:
158163
raise Exception("Device connected does not match the selected device to flash")
159164

160165

161-
162166
def check_mem(device, port):
163167

164168
if "XMC1" in device:
@@ -170,7 +174,7 @@ def check_mem(device, port):
170174
flash_size = (device_value-1)*4 #flash size given by (ADDR-1)*4
171175
flash_size = str(flash_size).zfill(4)
172176

173-
print(f"Flash size is: {int(flash_size)}kB")
177+
print(f"Flash size is: {int(flash_size)}kB.")
174178

175179
# special case for XMC2GO-32kB variant, bypass check
176180
if "XMC1100" in device and int(flash_size) == 32:
@@ -194,10 +198,10 @@ def check_mem(device, port):
194198
raise Exception("Memory size of device connected does not match that of the selected device to flash")
195199

196200

197-
def upload(device, port, binfile):
201+
def upload(device, port, binfile, enable_jlink_log):
198202
serial_num = get_device_serial_number(port)
199203
jlink_cmd_file = create_jlink_loadbin_command_file(binfile)
200-
jlink_commander(device, serial_num, jlink_cmd_file)
204+
jlink_commander(device, serial_num, jlink_cmd_file, console_output=not enable_jlink_log) # console_output = true will store the log to file instead of printing
201205
remove_jlink_command_file(jlink_cmd_file)
202206

203207
def erase(device, port):
@@ -217,7 +221,21 @@ def main_parser_func(args):
217221
def parser_upload_func(args):
218222
check_device(args.device, args.port)
219223
check_mem(args.device, args.port)
220-
upload(args.device, args.port, args.binfile)
224+
upload(args.device, args.port, args.binfile, args.verbose)
225+
# remove console output file if verbose is not enabled
226+
if not args.verbose:
227+
# check if upload was successful by parsing the console output
228+
with open(console_out, 'r') as f:
229+
found_loadbin = False
230+
for line in f:
231+
if "J-Link>loadbin" in line:
232+
found_loadbin = True
233+
elif found_loadbin and "O.K." in line:
234+
print("Upload successful.")
235+
break
236+
else:
237+
print("Upload failed.")
238+
remove_console_output_file(console_out)
221239

222240
def parser_erase_func(args):
223241
erase(args.device, args.port)
@@ -242,9 +260,10 @@ def __call__(self, parser, namespace, values, option_string, **kwargs):
242260
required_upload.add_argument('-d','--device', type=str, help='jlink device name', required=True)
243261
required_upload.add_argument('-p','--port', type=str, help='serial port', required=True)
244262
required_upload.add_argument('-f','--binfile', type=str, help='binary file to upload', required=True)
263+
required_upload.add_argument('--verbose', action='store_true', help='Enable verbose logging')
245264
parser_upload.set_defaults(func=parser_upload_func)
246265

247-
# Debug parser
266+
# Erase parser
248267
parser_erase = subparser.add_parser('erase', description='erase command')
249268
required_erase = parser_erase.add_argument_group('required arguments')
250269
required_erase.add_argument('-d','--device', type=str, help='jlink device name', required=True)
@@ -254,8 +273,14 @@ def __call__(self, parser, namespace, values, option_string, **kwargs):
254273
# debug_parser.
255274
# TBD in future
256275

257-
# Parser call
276+
# Parse arguments
258277
args = parser.parse_args()
278+
# Set traceback limit based on the --verbose argument
279+
if args.verbose:
280+
sys.tracebacklimit = None # Enable full traceback
281+
else:
282+
sys.tracebacklimit = 0 # Disable traceback
283+
# Parser call
259284
args.func(args)
260285

261286
if __name__ == "__main__":

0 commit comments

Comments
 (0)