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