Skip to content

Commit

Permalink
Merge pull request #295 from Infineon/bugfix/issue#266_cmdjlink_permi…
Browse files Browse the repository at this point in the history
…ssion_denied

Bugfix/issue#266 cmdjlink permission denied
Flashing script update: verify macOS, verbose log
  • Loading branch information
LinjingZhang committed Aug 27, 2024
2 parents ebabfa4 + 593cd19 commit e0d5503
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 29 deletions.
10 changes: 6 additions & 4 deletions platform.txt
Original file line number Diff line number Diff line change
Expand Up @@ -148,9 +148,11 @@ recipe.size.regex.data=^(?:\.data|\.VENEER_Code|\.ram_code|\.bss|\.no_init|\Stac
tools.xmcflasher.path={runtime.platform.path}/tools
tools.xmcflasher.cmd.path={path}/xmc-flasher.py
tools.xmcflasher.erase.params=-d XMC{build.board.version}-{build.board.v} -p {serial.port}
tools.xmcflasher.erase.pattern=python {cmd.path} erase {upload.params}
tools.xmcflasher.erase.pattern=python3 {cmd.path} erase {erase.params}
tools.xmcflasher.erase.pattern.windows=python {cmd.path} erase {erase.params}
tools.xmcflasher.upload.protocol=
tools.xmcflasher.upload.params.verbose=
tools.xmcflasher.upload.params.verbose=--verbose
tools.xmcflasher.upload.params.quiet=
tools.xmcflasher.upload.params=-d XMC{build.board.version}-{build.board.v} -p {serial.port} -f {build.path}/{build.project_name}.hex
tools.xmcflasher.upload.pattern=python {cmd.path} upload {upload.params}
tools.xmcflasher.upload.params=-d XMC{build.board.version}-{build.board.v} -p {serial.port} -f {build.path}/{build.project_name}.hex {upload.verbose}
tools.xmcflasher.upload.pattern=python3 {cmd.path} upload {upload.params}
tools.xmcflasher.upload.pattern.windows=python {cmd.path} upload {upload.params}
75 changes: 50 additions & 25 deletions tools/xmc-flasher.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import argparse, subprocess, os, sys, re, warnings
import argparse, subprocess, os, sys, re, warnings, tempfile
from serial.tools.list_ports import comports
from xmc_data import xmc_master_data

version = '0.1.1'
version = '0.1.2'

jlinkexe = ''

# Set temporary file for jlink command file and output file
cmd_jlink = os.path.join(tempfile.gettempdir(), 'cmd.jlink')
console_out = os.path.join(tempfile.gettempdir(), 'console.output')

def check_python_version():
major = sys.version_info.major
minor = sys.version_info.minor
Expand All @@ -31,9 +35,7 @@ def set_environment():
elif sys.platform == 'win32' or sys.platform == 'cygwin':
jlinkexe = rf"{get_jlink_install_path()}\jlink.exe"
elif sys.platform == 'darwin':
jlinkexe = 'jlink'
print('warning: mac os not validated')
#raise Exception('mac os not supported?')
jlinkexe = 'JLinkExe'

def discover_devices():
ports = comports()
Expand All @@ -46,21 +48,18 @@ def discover_devices():
def get_device_serial_number(port):
port_sn_list = discover_devices()
for device in port_sn_list:
if device[0] == port:
return device[1]

if device[0] == port and device[0] != None:
return device[1]
return None

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

return cmd_jlink

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

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

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

def process_console_output(string):
with open('console.output','r') as f:
with open(console_out,'r') as f:
lines = f.readlines()
lines[0].split('\n')

for line in lines :
if string in line and '=' in line:
print(line)

def check_serial_number(serial_num):
if serial_num == None:
raise Exception("Device not found! Please check the serial port")

def get_mem_contents(addr, bytes, device, port):

serial_num = get_device_serial_number(port)
try:
serial_num = get_device_serial_number(port)
check_serial_number(serial_num)
except ValueError as e:
print(e)
jlink_cmd_file = create_jlink_mem_read_command_file(addr, bytes) # todo: comes from proper metafile
jlink_commander(device, serial_num, jlink_cmd_file, True)
remove_jlink_command_file(jlink_cmd_file)

with open('console.output','r') as f:
with open(console_out,'r') as f:
lines = f.readlines()
lines[0].split('\n')

remove_console_output_file('console.output')
remove_console_output_file(console_out)

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

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

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



def check_mem(device, port):

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

print(f"Flash size is: {int(flash_size)}kB")
print(f"Flash size is: {int(flash_size)}kB.")

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


def upload(device, port, binfile):
def upload(device, port, binfile, enable_jlink_log):
serial_num = get_device_serial_number(port)
jlink_cmd_file = create_jlink_loadbin_command_file(binfile)
jlink_commander(device, serial_num, jlink_cmd_file)
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
remove_jlink_command_file(jlink_cmd_file)

def erase(device, port):
Expand All @@ -217,7 +221,21 @@ def main_parser_func(args):
def parser_upload_func(args):
check_device(args.device, args.port)
check_mem(args.device, args.port)
upload(args.device, args.port, args.binfile)
upload(args.device, args.port, args.binfile, args.verbose)
# remove console output file if verbose is not enabled
if not args.verbose:
# check if upload was successful by parsing the console output
with open(console_out, 'r') as f:
found_loadbin = False
for line in f:
if "J-Link>loadbin" in line:
found_loadbin = True
elif found_loadbin and "O.K." in line:
print("Upload successful.")
break
else:
print("Upload failed.")
remove_console_output_file(console_out)

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

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

# Parser call
# Parse arguments
args = parser.parse_args()
# Set traceback limit based on the --verbose argument
if args.verbose:
sys.tracebacklimit = None # Enable full traceback
else:
sys.tracebacklimit = 0 # Disable traceback
# Parser call
args.func(args)

if __name__ == "__main__":
Expand Down

0 comments on commit e0d5503

Please sign in to comment.