From 8fcba4d138eb6f1f62a0f6d7d6be31cc17f406a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20Poulhi=C3=A8s?= Date: Wed, 7 Mar 2018 22:55:03 +0100 Subject: [PATCH] Better error handling and handle more variant of SVD Try to avoid silencing raised exception as sometime it masks real errors. Make the SVD parser to accept register without fields (and display the full content of register) --- cmdebug/svd.py | 50 +++++++++++++++++++++++++-------------- cmdebug/svd_gdb.py | 59 +++++++++++++++++++++++++--------------------- 2 files changed, 64 insertions(+), 45 deletions(-) diff --git a/cmdebug/svd.py b/cmdebug/svd.py index 9241bc7..6aefdac 100755 --- a/cmdebug/svd.py +++ b/cmdebug/svd.py @@ -42,10 +42,9 @@ class SVDFile: def __init__(self, fname): f = objectify.parse(os.path.expanduser(fname)) root = f.getroot() - periph = root.peripherals.getchildren() self.peripherals = OrderedDict() # XML elements - for p in periph: + for p in root.peripherals.iterchildren(tag='peripheral'): try: self.peripherals[str(p.name)] = SVDPeripheral(p, self) except SVDNonFatalError as e: @@ -70,7 +69,7 @@ def add_register(parent, node): else: try: parent.registers[str(node.name)] = SVDPeripheralRegister(node, parent) - except: + except SVDUnsupportedPeriheral: pass def add_cluster(parent, node): @@ -93,8 +92,8 @@ def add_cluster(parent, node): else: try: parent.clusters[str(node.name)] = SVDRegisterCluster(node, parent) - except SVDNonFatalError as e: - print(e) + except SVDUnsupportedPeriheral: + pass class SVDRegisterCluster: def __init__(self, svd_elem, parent): @@ -124,6 +123,10 @@ class SVDRegisterCluster: def __unicode__(self): return str(self.name) +class SVDUnsupportedPeriheral(Exception): + def __init__(self, elem): + self.elem = elem + class SVDPeripheral: def __init__(self, svd_elem, parent): self.parent = parent @@ -145,16 +148,23 @@ class SVDPeripheral: self.refactor_parent(parent) else: # This doesn't inherit registers from anything - registers = svd_elem.registers.getchildren() - self.description = str(svd_elem.description) + try: + self.description = str(svd_elem.description) + except: + self.description = 'No description provided' self.name = str(svd_elem.name) self.registers = OrderedDict() self.clusters = OrderedDict() - for r in registers: - if r.tag == "cluster": - add_cluster(self, r) - else: - add_register(self, r) + + try: + registers = svd_elem.registers.getchildren() + for r in registers: + if r.tag == "cluster": + add_cluster(self, r) + else: + add_register(self, r) + except: + pass def refactor_parent(self, parent): self.parent = parent @@ -171,8 +181,9 @@ class SVDPeripheral: for c in self.clusters.values(): c.refactor_parent(self) - def __unicode__(self): - return str(self.name) + def __repr__(self): + return self.name + class SVDPeripheralRegister: def __init__(self, svd_elem, parent): @@ -230,10 +241,13 @@ class SVDPeripheralRegisterField: self.offset = bitrange[1] self.width = 1 + bitrange[0] - bitrange[1] except: - lsb = int(str(svd_elem.lsb)) - msb = int(str(svd_elem.msb)) - self.offset = lsb - self.width = 1 + msb - lsb + try: + lsb = int(str(svd_elem.lsb)) + msb = int(str(svd_elem.msb)) + self.offset = lsb + self.width = 1 + msb - lsb + except: + raise SVDUnsupportedPeriheral(svd_elem) self.access = str(getattr(svd_elem, "access", parent.access)) self.enum = {} diff --git a/cmdebug/svd_gdb.py b/cmdebug/svd_gdb.py index ac79cce..119da54 100644 --- a/cmdebug/svd_gdb.py +++ b/cmdebug/svd_gdb.py @@ -138,40 +138,45 @@ class SVD(gdb.Command): def _print_register_fields(self, container_name, form, register): gdb.write("Fields in {}:\n".format(container_name)) - fields = register.fields + if not register.readable(): data = 0 else: data = self.read(register.address(), register.size) - fieldList = [] try: - fields_iter = fields.itervalues() - except AttributeError: - fields_iter = fields.values() - for f in fields_iter: - desc = re.sub(r'\s+', ' ', f.description) - if register.readable(): - val = data >> f.offset - val &= (1 << f.width) - 1 - if f.enum: - if val in f.enum: - desc = f.enum[val][1] + " - " + desc - val = f.enum[val][0] + fields = register.fields + fieldList = [] + try: + fields_iter = fields.itervalues() + except AttributeError: + fields_iter = fields.values() + + for f in fields_iter: + desc = re.sub(r'\s+', ' ', f.description) + if register.readable(): + val = data >> f.offset + val &= (1 << f.width) - 1 + if f.enum: + if val in f.enum: + desc = f.enum[val][1] + " - " + desc + val = f.enum[val][0] + else: + val = "Invalid enum value: " + self.format(val, form, f.width) else: - val = "Invalid enum value: " + self.format(val, form, f.width) + val = self.format(val, form, f.width) else: - val = self.format(val, form, f.width) - else: - val = "(not readable)" - fieldList.append((f.name, val, desc)) - - column1Width = max(len(field[0]) for field in fieldList) + 2 # padding - column2Width = max(len(field[1]) for field in fieldList) # padding - for field in fieldList: - gdb.write("\t{}:{}{}".format(field[0], "".ljust(column1Width - len(field[0])), field[1].rjust(column2Width))) - if field[2] != field[0]: - gdb.write(" {}".format(field[2])) - gdb.write("\n"); + val = "(not readable)" + fieldList.append((f.name, val, desc)) + + column1Width = max(len(field[0]) for field in fieldList) + 2 # padding + column2Width = max(len(field[1]) for field in fieldList) # padding + for field in fieldList: + gdb.write("\t{}:{}{}".format(field[0], "".ljust(column1Width - len(field[0])), field[1].rjust(column2Width))) + if field[2] != field[0]: + gdb.write(" {}".format(field[2])) + gdb.write("\n"); + except: + gdb.write("\t{}: {}\n".format(register.name, self.format(data, form, register.size))) def invoke(self, args, from_tty): try: