From mboxrd@z Thu Jan 1 00:00:00 1970 From: Jim Blandy To: gdb-patches@sources.redhat.com Subject: RFA: pause after sending S-records to ROM68K monitor Date: Wed, 08 Aug 2001 17:54:00 -0000 Message-id: <20010809005554.1CDB75E9D8@zwingli.cygnus.com> X-SW-Source: 2001-08/msg00085.html This patch creates another use of baud_rate (as set by `set baud'). I'm not sure that's such a hot idea. But it does make `target rom68k' usable over an SSH tunnel to a portmaster; without the patch, GDB transmits the entire program immediately (I guess it gets absorbed by all the buffers between itself and the real board), and then times out. 2001-08-08 Jim Blandy * rom68k-rom.c (init_rom68k_cmds): Request that monitor.c pause after sending each S-record. * monitor.h (MO_SREC_ACK_DELAY): New flag. * monitor.c: #include . (monitor_wait_srec_ack): If MO_SREC_ACK_DELAY is set, pause long enough for the record to be transmitted, according to baud_rate. * dsrec.c (load_srec): Change WAITACK function to take an argument: the number of bytes transmitted. * srec.h (load_srec): Update prototype. Index: gdb/dsrec.c =================================================================== RCS file: /cvs/src/src/gdb/dsrec.c,v retrieving revision 1.11 diff -c -r1.11 dsrec.c *** gdb/dsrec.c 2001/07/15 20:34:13 1.11 --- gdb/dsrec.c 2001/08/09 00:45:45 *************** *** 42,53 **** various random flags, and HASHMARK is non-zero to cause a `#' to be printed out for each record loaded. WAITACK, if non-NULL, is a function that waits for an acknowledgement after each S-record, and ! returns non-zero if the ack is read correctly. */ void load_srec (struct serial *desc, const char *file, bfd_vma load_offset, int maxrecsize, ! int flags, int hashmark, int (*waitack) (void)) { bfd *abfd; asection *s; --- 42,55 ---- various random flags, and HASHMARK is non-zero to cause a `#' to be printed out for each record loaded. WAITACK, if non-NULL, is a function that waits for an acknowledgement after each S-record, and ! returns non-zero if the ack is read correctly; its argument is the ! number of characters sent to the monitor for this record, for use ! in computing delays (if necessary). */ void load_srec (struct serial *desc, const char *file, bfd_vma load_offset, int maxrecsize, ! int flags, int hashmark, int (*waitack) (int bytes_sent)) { bfd *abfd; asection *s; *************** *** 126,132 **** if (ui_load_progress_hook (section_name, (unsigned long) i)) error ("Canceled the download"); } ! while (waitack != NULL && !waitack ()); if (hashmark) { --- 128,134 ---- if (ui_load_progress_hook (section_name, (unsigned long) i)) error ("Canceled the download"); } ! while (waitack != NULL && !waitack (reclen)); if (hashmark) { Index: gdb/monitor.c =================================================================== RCS file: /cvs/src/src/gdb/monitor.c,v retrieving revision 1.28 diff -c -r1.28 monitor.c *** gdb/monitor.c 2001/07/15 20:34:13 1.28 --- gdb/monitor.c 2001/08/09 00:45:47 *************** *** 44,49 **** --- 44,50 ---- #include #include #include "gdb_string.h" + #include #include #include "command.h" #include "serial.h" *************** *** 2143,2151 **** /* monitor_wait_srec_ack -- wait for the target to send an acknowledgement for an S-record. Return non-zero if the ACK is received properly. */ - static int ! monitor_wait_srec_ack (void) { int ch; --- 2144,2151 ---- /* monitor_wait_srec_ack -- wait for the target to send an acknowledgement for an S-record. Return non-zero if the ACK is received properly. */ static int ! monitor_wait_srec_ack (int bytes_sent) { int ch; *************** *** 2164,2169 **** --- 2164,2197 ---- return 0; if ((ch = readchar (1)) < 0) return 0; + } + else if (current_monitor->flags & MO_SREC_ACK_DELAY) + { + int delay_baud = baud_rate; + long milliseconds; + struct timeval tv; + + /* If the user hasn't specified a baud rate, assume 9600. */ + if (delay_baud == -1) + delay_baud = 9600; + + /* A baud rate is "symbols per second"; on a serial line, that's + the same as "bits per second". Assume ten bits transmitted + per byte: eight data bits, one parity bit, and one stop bit. + (Usually people use 8N1, which I think means the parity bit + isn't transmitted, so we're actually at nine bits transmitted + per byte, but we need to be sure to allow enough time.) + + So bytes_sent * 10 is at least the number of bits + transmitted; that divided by the bits-per-second rate yields + seconds. That times 1000 yields milliseconds. Do the + multiplication first, to minimize round-off errors. */ + milliseconds = (bytes_sent * 10 * 1000) / delay_baud; + tv.tv_usec = milliseconds * 1000; + tv.tv_sec = milliseconds / 1000; + if (select (0, 0, 0, 0, &tv) == -1) + error ("Error waiting for S-record transmission: %s", + strerror (errno)); } return 1; } Index: gdb/monitor.h =================================================================== RCS file: /cvs/src/src/gdb/monitor.h,v retrieving revision 1.7 diff -c -r1.7 monitor.h *** gdb/monitor.h 2001/07/10 21:06:34 1.7 --- gdb/monitor.h 2001/08/09 00:45:47 *************** *** 231,236 **** --- 231,241 ---- */ #define MO_HAS_BLOCKWRITES 0x800000 + /* If set, assume that the target has no flow control, and we have to + sleep long enough (according to baud_rate) for the target to absorb + what we have sent. */ + #define MO_SREC_ACK_DELAY 0x1000000 + #define SREC_SIZE 160 extern void monitor_open (char *args, struct monitor_ops *ops, int from_tty); Index: gdb/rom68k-rom.c =================================================================== RCS file: /cvs/src/src/gdb/rom68k-rom.c,v retrieving revision 1.5 diff -c -r1.5 rom68k-rom.c *** gdb/rom68k-rom.c 2001/03/06 08:21:16 1.5 --- gdb/rom68k-rom.c 2001/08/09 00:45:47 *************** *** 99,105 **** static void init_rom68k_cmds (void) { ! rom68k_cmds.flags = 0; rom68k_cmds.init = rom68k_inits; /* monitor init string */ rom68k_cmds.cont = "go\r"; rom68k_cmds.step = "st\r"; --- 99,105 ---- static void init_rom68k_cmds (void) { ! rom68k_cmds.flags = MO_SREC_ACK | MO_SREC_ACK_DELAY; rom68k_cmds.init = rom68k_inits; /* monitor init string */ rom68k_cmds.cont = "go\r"; rom68k_cmds.step = "st\r"; Index: gdb/srec.h =================================================================== RCS file: /cvs/src/src/gdb/srec.h,v retrieving revision 1.4 diff -c -r1.4 srec.h *** gdb/srec.h 2001/07/11 17:52:32 1.4 --- gdb/srec.h 2001/08/09 00:45:47 *************** *** 20,26 **** void load_srec (struct serial *desc, const char *file, bfd_vma load_offset, int maxrecsize, int flags, int hashmark, ! int (*waitack) (void)); /* S-record capability flags */ --- 20,26 ---- void load_srec (struct serial *desc, const char *file, bfd_vma load_offset, int maxrecsize, int flags, int hashmark, ! int (*waitack) (int chars_sent)); /* S-record capability flags */ Index: gdb/doc/gdb.texinfo =================================================================== RCS file: /cvs/src/src/gdb/doc/gdb.texinfo,v retrieving revision 1.48 diff -c -r1.48 gdb.texinfo *** gdb/doc/gdb.texinfo 2001/08/02 10:52:07 1.48 --- gdb/doc/gdb.texinfo 2001/08/09 00:45:58 *************** *** 11794,11800 **** @kindex target rom68k @item target rom68k @var{dev} ! ROM 68K monitor, running on an M68K IDP board. @end table --- 11794,11805 ---- @kindex target rom68k @item target rom68k @var{dev} ! ROM 68K monitor, running on an M68K IDP board. The IDP board's serial ! port doesn't support flow control, and the monitor doesn't provide any ! acknowledgement for each S-record received, so GDB's @code{load} command ! uses the current baud rate to pace its transmission of S-records. See ! the description of @code{set baud} at @ref{Protocol,, Communication ! Protocol}. @end table