Hi,

Sorry I sent a diff file. Here is the patch file.

Regards,
Dean.

On Tue, 2006-10-10 at 13:35 +0100, Dean Jenkins wrote:
> Hi,
> 
> I am a newbie to this process so please tell me if I need to make
> changes to this message.
> 
> I wish to submit an enhancement to replace the original get_packet()
> function in kgdb.c. Please give me some feedback.
> 
> My modification uses a state based packet detection routine and allows
> for fast recovery from bit errors and missing characters in the received
> packet. The old get_packet() can easily fail to recover quickly and
> therefore will have poor performance when the comms are not 100% good.
> 
> Here is my patch for kgdb.c, I've attached my patch file as evolution
> seems to corrupt my source code if I paste the code directly into my e-
> mail. For example, evolution adds linewrap and seems to remove tabs.
> 
> Regards,
> Dean.
> 
--- kgdb.c.orig	2006-10-09 16:33:39.000000000 +0100
+++ kgdb.c	2006-10-09 17:11:35.000000000 +0100
@@ -24,6 +24,11 @@
  * This file is licensed under the terms of the GNU General Public License
  * version 2. This program is licensed "as is" without any warranty of any
  * kind, whether express or implied.
+ *
+ * Modified by Dean Jenkins
+ * Copyright (C) 2006 Liberte Software Ltd. <[EMAIL PROTECTED]>
+ * get_packet() made more robust to avoid loss of the next "good" received packet.
+ *
  */
 
 #include <linux/string.h>
@@ -338,50 +343,136 @@
 	return (-1);
 }
 
+typedef enum {
+	WAIT_DOLLAR,
+	GOT_DOLLAR,
+	GOT_HASH,
+	GOT_CHK1,
+	GOOD_PACKET
+} rx_state;
+
 /* scan for the sequence $<data>#<checksum>	*/
 static void get_packet(char *buffer)
 {
-	unsigned char checksum;
-	unsigned char xmitcsum;
-	int count;
+	unsigned char checksum = 0;
+	unsigned char xmitcsum = 0;
+	int count = 0, hexvalue;
 	char ch;
-	if (!kgdb_io_ops.read_char)
-		return;
-	do {
-		/* Spin and wait around for the start character, ignore all
-		 * other characters */
-		while ((ch = (kgdb_io_ops.read_char())) != '$') ;
-		kgdb_connected = 1;
-		checksum = 0;
-		xmitcsum = -1;
+	rx_state state = WAIT_DOLLAR;
 
-		count = 0;
+	while( state != GOOD_PACKET ) {
 
-		/* now, read until a # or end of buffer is found */
-		while (count < (BUFMAX - 1)) {
-			ch = kgdb_io_ops.read_char();
-			if (ch == '#')
-				break;
-			checksum = checksum + ch;
-			buffer[count] = ch;
-			count = count + 1;
+		/* read a character ( uses blocking ) */
+		ch = kgdb_io_ops.read_char();
+
+		if( ch == '$' ) {
+			/* start of new packet */
+			/* abandon any old packet processing */
+			/* as incomplete packet received */
+
+			checksum = 0;
+			count = 0;
+
+			state = GOT_DOLLAR;
 		}
-		buffer[count] = 0;
+		else {
+			switch (state) {
 
-		if (ch == '#') {
-			xmitcsum = hex(kgdb_io_ops.read_char()) << 4;
-			xmitcsum += hex(kgdb_io_ops.read_char());
-
-			if (checksum != xmitcsum)
-				/* failed checksum */
-				kgdb_io_ops.write_char('-');
-			else
-				/* successful transfer */
-				kgdb_io_ops.write_char('+');
-			if (kgdb_io_ops.flush)
-				kgdb_io_ops.flush();
+				case WAIT_DOLLAR:
+					/* continue to wait for the next $ */
+					break;
+
+				case GOT_DOLLAR:
+					/* receive the command */
+
+					/* terminator found ? */
+					if (ch == '#') {
+						buffer[count] = 0;
+						state = GOT_HASH;
+					}
+					else if (count < (BUFMAX - 1)) {
+						checksum = checksum + ch;
+						buffer[count] = ch;
+						count = count + 1;
+					}
+					else {
+						/* command is TOO long so abort */
+						kgdb_io_ops.write_char('-');
+
+						if (kgdb_io_ops.flush) {
+							kgdb_io_ops.flush();
+						}
+
+						state = WAIT_DOLLAR;
+					}
+					break;
+
+				case GOT_HASH:
+					/* look at first checksum char */
+					hexvalue = hex(ch);
+
+					if( hexvalue == -1 ) {
+						/* invalid hex char received so abort */
+						kgdb_io_ops.write_char('-');
+
+						if (kgdb_io_ops.flush) {
+							kgdb_io_ops.flush();
+						}
+
+						state = WAIT_DOLLAR;
+					}
+					else {
+						xmitcsum = hexvalue << 4;
+						state = GOT_CHK1;
+					}
+					break;
+
+				case GOT_CHK1:
+					/* look at second checksum char */
+					hexvalue = hex(ch);
+
+					if( hexvalue == -1 ) {
+						/* invalid hex char received so abort */
+						kgdb_io_ops.write_char('-');
+
+						if (kgdb_io_ops.flush) {
+							kgdb_io_ops.flush();
+						}
+
+						state = WAIT_DOLLAR;
+					}
+					else {
+						xmitcsum += hexvalue ;
+
+						/* end of packet so now validate the checksum */
+						if (checksum != xmitcsum) {
+							/* failed checksum */
+							kgdb_io_ops.write_char('-');
+							/* bad packet so look for new packet */
+							state = WAIT_DOLLAR;
+						}
+						else {
+							/* successful transfer */
+							kgdb_io_ops.write_char('+');
+							/* exit as got a good packet */
+							state = GOOD_PACKET;
+						}
+
+						if (kgdb_io_ops.flush) {
+							kgdb_io_ops.flush();
+						}
+					}
+					break;
+
+				default:
+					/* should never get here */
+					state = WAIT_DOLLAR;
+					break;
+			}
 		}
-	} while (checksum != xmitcsum);
+	}
+
+	kgdb_connected = 1;
 }
 
 /*
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys -- and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Kgdb-bugreport mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/kgdb-bugreport

Reply via email to