Browse Source

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)
master
Marc Poulhiès 4 years ago committed by Marc Poulhiès
parent
commit
8fcba4d138
  1. 50
      cmdebug/svd.py
  2. 59
      cmdebug/svd_gdb.py

50
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 = {}

59
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:

Loading…
Cancel
Save