"""Remote GDB debugging protocol, implemented for the BDI 2000
Using this code, you can execute Commands on your BDI2000 or
poke around in the memory of your device. Using this to burn
images into the memory of your device is also possible.
(c) 2004 by M&N Logistik-Lösungen Online GmbH, written by
H.Schurig
This code is released under both the GPL version 2. You should have
received a copy of the GNU General Public License along with this
program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA.
"""
import sys
import socket
import time
ip_bdi = ''
port = 2001;
connected = 0
debugbdi = 2
# The 'vars' python module is part of hwtester:
try:
import vars
ip_bdi = vars.get('ip_bdi')
debugbdi = vars.get('debugbdi')
except:
pass
class BDIConnection(Exception):
pass
# Pre-Create the socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
def doconnect():
global sock, connected
try:
sock.connect((ip_bdi, port)) # must be a tuple!
connected = 1
except:
raise BDIConnection, "No Connection to BDI 2000 via %s:%d" % (ip_bdi, port)
def response(notext=1):
s = ''
res = ''
while 1:
if res=='':
res = sock.recv(2048)
if debugbdi >= 2: print "bdi: rcvd:", res
if len(res)<4 or res[0]!='$':
raise "bdi: strange protocol response: " +res
# calculate checksum
csum = 0
n = 0
for c in res[1:]:
if c == '#': break
csum = csum + ord(c)
n = n + 1
# check checksum and send ACK
if res[n+2:n+4] != "x" % (csum%6):
raise "bdi: checksum bad"
sock.send('+')
if res[1]=='E':
raise "bdi: gdb protocol error"
if res[1]=='O':
if res[2]=='K':
if notext and s!='':
raise "bdi: unexpeced protocol response: " +s
else:
return s
chunk = ''
for i in xrange(0,n-2,2):
chunk = chunk + chr(int(res[i+2:i+4],16))
if debugbdi > 0: print chunk,
s = s + chunk
res = res[n+4:]
continue
return res[1:-3]
def gdb(cmd, notext=1, sleep=0):
global sock, connected
if not connected:
doconnect()
# calculate checksum:
csum = 0
for c in cmd:
csum = csum + ord(c)
cmd = '$' + cmd + '#' + "x" % (csum % 256)
# send command
sock.send(cmd)
if debugbdi >= 2: print "bdi: sent:", cmd
# get ACK or NACK
res = sock.recv(1)
if len(res)<1 or res[0] != '+':
raise 'bdi: ACK was not + but ' + res
if sleep:
time.sleep(sleep)
return response(notext)
def cmd(cmd, notext=0, sleep=0):
if debugbdi: print "cmd('%s',%d,%d)" % (cmd,notext,sleep)
csum = 0
s = ''
for c in cmd:
s = s + "x" % ord(c)
return gdb('qRcmd,'+s,notext,sleep)
def getlong(addr):
res = socket.htonl(eval("0x" + gdb("m%x,4" % addr)))
if debugbdi: print "getlong(x) = x" % (addr, res)
return res
def getlonghex(addr):
res = gdb("m%x,4" % addr)
res = res[6:8] + res[4:6] + res[2:4] + res[0:2]
if debugbdi: print "getlonghex(x) = %s" % (addr, res)
return res
def setlong(addr, data):
res = gdb("M%x,4:x" % (addr, socket.ntohl(data)) )
if debugbdi: print "setlong(x,x)" % (addr,data)
def getword(addr):
res = socket.htons(int(gdb("m%x,2" % addr),16))
if debugbdi: print "getword(x) = x" % (addr, res)
return res
def setword(addr, data):
res = gdb("M%x,2:x" % (addr, socket.ntohs(data)) )
if debugbdi: print "setword(x,x)" % (addr,data)
def getbyte(addr):
res = int(gdb("m%x,1" % addr),16)
if debugbdi: print "x: x" % (addr, res)
return res
def setbyte(addr, data):
if debugbdi: print "setbyte(x,x)" % (addr,data)
res = gdb("M%x,1:x" % (addr, data) )
def getmem(addr, size):
pos = addr
chunk = ''
while pos < addr+size:
s = gdb("m%x,%x" % (pos, min(512,size)))
for i in xrange(0,len(s),2):
chunk = chunk + chr(int(s[i:i+2],16))
pos = pos + min(512,size)
return chunk
def hexdump(chunk, addr=0):
n = 0
s = ''
while n < len(chunk):
if n % 8 == 0:
print "x :" % (addr+n) ,
print "x" % ord(chunk[n]),
if (chunk[n]>=0x20) and (chunk[n]<0x7f):
s = s + chr(chunk[n])
else:
s = s + '.'
if n % 8 == 7:
print "", s
s = ''
n = n+1
if __name__ == '__main__':
s = cmd("help")
print s
s = cmd("info")
print s
chunk = getmem(0,128)
hexdump(chunk)