aboutsummaryrefslogtreecommitdiff
path: root/AT91SAM7S256/armdebug/Host/nxt-gdb-server.py
diff options
context:
space:
mode:
Diffstat (limited to 'AT91SAM7S256/armdebug/Host/nxt-gdb-server.py')
-rwxr-xr-xAT91SAM7S256/armdebug/Host/nxt-gdb-server.py76
1 files changed, 60 insertions, 16 deletions
diff --git a/AT91SAM7S256/armdebug/Host/nxt-gdb-server.py b/AT91SAM7S256/armdebug/Host/nxt-gdb-server.py
index 7de81b7..edd3143 100755
--- a/AT91SAM7S256/armdebug/Host/nxt-gdb-server.py
+++ b/AT91SAM7S256/armdebug/Host/nxt-gdb-server.py
@@ -22,12 +22,15 @@ import select
#import usb
import pyfantom
import struct
+import sys
CTRLC = chr(3)
+NAKCHAR = '-'
+ACKCHAR = '+'
STATUS_QUERY = "$?#3F"
DEFAULT_PORT = 2828
SELECT_TIMEOUT = 0.1
-DEBUG = True
+DEBUG = False
DEBUG2 = False
NXT_RECV_ERR = -1
@@ -45,10 +48,12 @@ class NXTGDBServer:
# Debug command header, no reply.
debug_command = 0x8d
- def __init__ (self, port):
+ def __init__ (self, port, nowait):
"""Initialise server."""
+ self.nowait = nowait
self.port = port
self.in_buf = ''
+ self.brick = None
def pack (self, data, segment_no):
"""Return packed data to send to NXT."""
@@ -70,9 +75,25 @@ class NXTGDBServer:
return body, segment_no
def segment (self, data):
- """Split datas in GDB commands and make segments with each command."""
+ """Split messages in GDB commands and make segments with each command."""
segs = [ ]
self.in_buf += data
+
+ # Find ACK '+'
+ end = self.in_buf.find (ACKCHAR)
+ while end == 0:
+ self.in_buf = self.in_buf[end+1:] # Strip out any leading ACKCHAR
+ if DEBUG2:
+ print "stripped ACK, remain: ", self.in_buf
+ end = self.in_buf.find (ACKCHAR)
+
+ # Find NAK '-'
+ end = self.in_buf.find (NAKCHAR)
+ if end == 0:
+ msg, self.in_buf = self.in_buf[0:end+1], self.in_buf[end+1:]
+ segs.append (self.pack (msg, 0))
+ end = self.in_buf.find (NAKCHAR)
+
# Find Ctrl-C (assumed to be by itself and not following a normal command)
end = self.in_buf.find (CTRLC)
if end >= 0:
@@ -87,8 +108,8 @@ class NXTGDBServer:
msg, self.in_buf = self.in_buf[0:end + 3], self.in_buf[end + 3:]
i = 0
gdbprefix = msg[i]
- while gdbprefix in ['+', '-']:
- # Ignore any '+' or '-'
+ while gdbprefix in [ACKCHAR]:
+ # Ignore any '+'
i += 1
gdbprefix = msg[i]
if DEBUG2:
@@ -138,12 +159,16 @@ class NXTGDBServer:
s.setsockopt (socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind (('', self.port))
s.listen (1)
- # Open connection to the NXT brick.
- brick = nxt.locator.find_one_brick (method=nxt.Method(usb=False, bluetooth=False, fantomusb=True, fantombt=False))
- brick.sock.debug = DEBUG
- print "Waiting for GDB connection on port %s..." % self.port
while True:
+ # We should open the NXT connection first, otherwise Python startup delay
+ # may cause GDB to misbehave
+ if not self.nowait:
+ dummy = raw_input('Waiting...Press <ENTER> when NXT GDB Stub is ready. ')
+ # Open connection to the NXT brick.
+ self.brick = nxt.locator.find_one_brick ()
+ self.brick.sock.debug = DEBUG
# Wait for a connection.
+ print "Waiting for GDB connection on port %s..." % self.port
client, addr = s.accept ()
print "Client from", addr
# Work loop, wait for a message from client socket or NXT brick.
@@ -162,12 +187,15 @@ class NXTGDBServer:
# print "CTRL-C Received!"
# data = STATUS_QUERY
if DEBUG:
- print "[GDB->NXT] %s" % data
+ if data[0] == CTRLC:
+ print "[GDB->NXT] <CTRL-C>"
+ else:
+ print "[GDB->NXT] %s" % data
segments = self.segment (data)
data = ''
for seg in segments:
try:
- brick.sock.send (seg)
+ self.brick.sock.send (seg)
except usb.USBError as e:
# Some pyusb are buggy, ignore some "errors".
if e.args != ('No error', ):
@@ -175,14 +203,14 @@ class NXTGDBServer:
if segments != [] and LIBUSB_RECEIVE_BLOCKING:
if DEBUG2:
print "Accessing Blocking sock.recv()"
- data = self.reassemble (brick.sock)
+ data = self.reassemble (self.brick.sock)
else:
client.close ()
client = None
if not LIBUSB_RECEIVE_BLOCKING:
if DEBUG2:
print "Accessing Non-Blocking sock.recv()"
- data = self.reassemble (brick.sock)
+ data = self.reassemble (self.brick.sock)
# Is there something from NXT brick?
if data:
@@ -191,7 +219,10 @@ class NXTGDBServer:
if client:
client.send (data)
data = ''
- print "Connection closed, waiting for GDB connection on port %s..." % self.port
+ self.brick.sock.close()
+ print "Connection closed."
+ if self.nowait:
+ break
if __name__ == '__main__':
# Read options from command line.
@@ -200,9 +231,22 @@ if __name__ == '__main__':
""")
parser.add_option ('-p', '--port', type = 'int', default = DEFAULT_PORT,
help = "server listening port (default: %default)", metavar = "PORT")
+ parser.add_option ('-v', '--verbose', action='store_true', dest='verbose', default = False,
+ help = "verbose mode (default: %default)")
+ parser.add_option ('-n', '--nowait', action='store_true', dest='nowait', default = False,
+ help = "Don't wait for NXT GDB Stub Setup before connecting (default: %default)")
(options, args) = parser.parse_args ()
if args:
parser.error ("Too many arguments")
# Run.
- s = NXTGDBServer (options.port)
- s.run ()
+ try:
+ DEBUG = options.verbose
+ if DEBUG:
+ print "Debug Mode Enabled!"
+ server = NXTGDBServer (options.port, options.nowait)
+ server.run ()
+ except KeyboardInterrupt:
+ print "\n\nException caught. Bye!"
+ if server.brick is not None:
+ server.brick.sock.close()
+ sys.exit()