Hi,
is there a way to get breakpoint-adresses for source code lines directly
from simulavr (with the python interface)?
Currently, I call avr-gdb via subprocess.Popen and evaluate the output
of "break" commands (see attached code, get_breakpoint_adresses). But
that seems a bit clumsy.
Sebastian
import unittest
import pysimulavr
import subprocess
import re
class XPin(pysimulavr.Pin):
def __init__(self, dev, name, pinname, state = None):
pysimulavr.Pin.__init__(self)
self.name = name
if state is not None: self.SetPin(state)
# hold the connecting net here, it have not be destroyed, if we leave this method
self.__net = pysimulavr.Net()
self.__net.Add(self)
self.__net.Add(dev.GetPin(pinname))
def SetInState(self, pin):
pysimulavr.Pin.SetInState(self, pin)
if pin.toChar() != self.toChar():
# print "%s='%s'" % (self.name, pin.toChar())
self.SetPin(pin.toChar())
class SingleDeviceTestCase(unittest.TestCase):
def setUp(self):
self.__sc = pysimulavr.SystemClock.Instance()
self.__sc.ResetClock()
self.device = pysimulavr.AvrFactory.instance().makeDevice(self.MCU)
self.device.Load(self.PROGRAM)
self.device.SetClockFreq(self.CLOCK_SETTING)
self.__sc.Add(self.device)
self.messages = []
self.breakpoint_callbacks = {}
def tearDown(self):
del self.device
def setPin(self, pin, state):
self.pins[pin].SetPin(state)
def getPin(self, pin):
return self.pins[pin].toChar()
def showPin(self, pin):
p = self.pins[pin]
self.message('%s = %s' % (p.name, p.toChar()))
def getCurrentTime(self):
return self.__sc.GetCurrentTime() / 1000000.0
def read_uint8(self, symbol):
addr = self.device.data.GetAddressAtSymbol(symbol)
return self.device.getRWMem(addr)
def message(self, m):
# This could be improved...
if len(self.messages) == 0:
print '\n\t' + str(m)
else:
print '\t' + str(m)
self.messages.append(m)
def add_breakpoint_callback(self, key, callback):
addr = self.breakpoint_adresses[key]
self.breakpoint_callbacks.setdefault(addr, []).append((callback, key))
def generic_breakpoint_callback(self, key):
self.message('Breakpoint %s reached, time = %s' % (key, self.getCurrentTime()))
return 0 # Don't stop
def runSteps(self, steps):
last_pc = 0 # Needed to avoid double-callbacks for multi-step instructions
for i in range(steps):
self.assertEqual(self.__sc.Step(), 0)
if self.device.PC in self.breakpoint_callbacks and self.device.PC != last_pc:
for callback, key in self.breakpoint_callbacks[self.device.PC]:
if callback(key):
return i
last_pc = self.device.PC
def read_until_prompt(file, prompt='(gdb)'):
lines = []
while 1:
line = file.readline(len(prompt))
if line == prompt:
return lines
line += file.readline()
lines.append(line)
def ignore_until_prompt(file, prompt='(gdb)'):
lines = read_until_prompt(file, prompt)
#~ print '-'*10 + ' ignoring'
#~ print ''.join(lines)
breakpoint_marker = re.compile(r'/\* *Breakpoint (?P<key>.*)\*/')
breakpoint_adress_output = re.compile(r'Breakpoint \d+ at 0x(?P<bp_addr>[0-9a-fA-F]+):.*')
def get_breakpoint_adresses(debug_directory, program, sourcefiles):
source_positions = {}
breakpoint_adresses = {}
# Search for lines with a match for the regex breakpoint_marker.
# Store filenames and linenumbers in source_positions.
for filename in sourcefiles:
for i, line in enumerate(open(debug_directory+filename, 'r')):
m = breakpoint_marker.search(line)
if m:
source_positions[m.group('key').strip()] = '%s:%s' % (filename, i+1)
# Call avr-gdb to get the adresses where avr-gdb sets breakpoints
# when you set breakpoints at the source lines.
# In breakpoint_adresses, store these addreses under the the key from the breakpoint_marker.
p = subprocess.Popen(['avr-gdb'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, universal_newlines=True)
ignore_until_prompt(p.stdout) # start message
p.stdin.write('file ' + debug_directory + program + '\n')
ignore_until_prompt(p.stdout) # load message
for key, source_position in source_positions.items():
p.stdin.write('break ' + source_position + '\n')
result = ''.join(read_until_prompt(p.stdout)).strip()
m = breakpoint_adress_output.match(result)
if m:
# The adress is divided by two because flash is adressed in 16 bit words
# (see datasheet, In-System Reprogrammable Flash Program Memory)
breakpoint_adresses[key] = int(m.group('bp_addr'), 16)/2
else:
print "couldn't match '%s'" % result
p.stdin.write('quit\n')
unconsumed = p.stdout.read()
#~ if unconsumed.strip():
#~ print '-'*10 + ' ignoring'
#~ print unconsumed
return breakpoint_adresses
if __name__ == "__main__":
pass
_______________________________________________
Simulavr-devel mailing list
[email protected]
http://lists.nongnu.org/mailman/listinfo/simulavr-devel