1 /* Remote target communications for serial-line targets using SDS' protocol.
2 Copyright 1997 Free Software Foundation, Inc.
4 This file is part of GDB.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
21 /* This interface was written by studying the behavior of the SDS
22 monitor on an ADS 821/860 board, and by consulting the
23 documentation of the monitor that is available on Motorola's web
27 #include "gdb_string.h"
37 #include "gdb-stabs.h"
38 #include "gdbthread.h"
43 #include <sys/types.h>
49 extern void _initialize_remote_sds (void);
51 /* Declarations of local functions. */
53 static int sds_write_bytes (CORE_ADDR
, char *, int);
55 static int sds_read_bytes (CORE_ADDR
, char *, int);
57 static void sds_files_info (struct target_ops
*ignore
);
59 static int sds_xfer_memory (CORE_ADDR
, char *, int, int, struct target_ops
*);
61 static void sds_prepare_to_store (void);
63 static void sds_fetch_registers (int);
65 static void sds_resume (int, int, enum target_signal
);
67 static int sds_start_remote (PTR
);
69 static void sds_open (char *, int);
71 static void sds_close (int);
73 static void sds_store_registers (int);
75 static void sds_mourn (void);
77 static void sds_create_inferior (char *, char *, char **);
79 static void sds_load (char *, int);
81 static int getmessage (unsigned char *, int);
83 static int putmessage (unsigned char *, int);
85 static int sds_send (unsigned char *, int);
87 static int readchar (int);
89 static int sds_wait (int, struct target_waitstatus
*);
91 static void sds_kill (void);
93 static int tohex (int);
95 static int fromhex (int);
97 static void sds_detach (char *, int);
99 static void sds_interrupt (int);
101 static void sds_interrupt_twice (int);
103 static void interrupt_query (void);
105 static int read_frame (char *);
107 static int sds_insert_breakpoint (CORE_ADDR
, char *);
109 static int sds_remove_breakpoint (CORE_ADDR
, char *);
111 static void init_sds_ops (void);
113 static void sds_command (char *args
, int from_tty
);
115 /* Define the target operations vector. */
117 static struct target_ops sds_ops
;
119 /* This was 5 seconds, which is a long time to sit and wait.
120 Unless this is going though some terminal server or multiplexer or
121 other form of hairy serial connection, I would think 2 seconds would
124 static int sds_timeout
= 2;
126 /* Descriptor for I/O to remote machine. Initialize it to NULL so
127 that sds_open knows that we don't have a file open when the program
130 static serial_t sds_desc
= NULL
;
132 /* This limit comes from the monitor. */
136 /* Maximum number of bytes to read/write at once. The value here
137 is chosen to fill up a packet (the headers account for the 32). */
138 #define MAXBUFBYTES ((PBUFSIZ-32)/2)
140 static int next_msg_id
;
142 static int just_started
;
144 static int message_pending
;
147 /* Clean up connection to a remote debugger. */
151 sds_close (int quitting
)
154 SERIAL_CLOSE (sds_desc
);
158 /* Stub for catch_errors. */
161 sds_start_remote (PTR dummy
)
164 unsigned char buf
[200];
166 immediate_quit
= 1; /* Allow user to interrupt it */
168 /* Ack any packet which the remote side has already sent. */
169 SERIAL_WRITE (sds_desc
, "{#*\r\n", 5);
170 SERIAL_WRITE (sds_desc
, "{#}\r\n", 5);
172 while ((c
= readchar (1)) >= 0)
173 printf_unfiltered ("%c", c
);
174 printf_unfiltered ("\n");
186 start_remote (); /* Initialize gdb process mechanisms */
190 /* Open a connection to a remote debugger.
191 NAME is the filename used for communication. */
193 static DCACHE
*sds_dcache
;
196 sds_open (char *name
, int from_tty
)
199 error ("To open a remote debug connection, you need to specify what serial\n\
200 device is attached to the remote system (e.g. /dev/ttya).");
202 target_preopen (from_tty
);
204 unpush_target (&sds_ops
);
206 sds_dcache
= dcache_init (sds_read_bytes
, sds_write_bytes
);
208 sds_desc
= SERIAL_OPEN (name
);
210 perror_with_name (name
);
214 if (SERIAL_SETBAUDRATE (sds_desc
, baud_rate
))
216 SERIAL_CLOSE (sds_desc
);
217 perror_with_name (name
);
222 SERIAL_RAW (sds_desc
);
224 /* If there is something sitting in the buffer we might take it as a
225 response to a command, which would be bad. */
226 SERIAL_FLUSH_INPUT (sds_desc
);
230 puts_filtered ("Remote debugging using ");
231 puts_filtered (name
);
232 puts_filtered ("\n");
234 push_target (&sds_ops
); /* Switch to using remote target now */
238 /* Start the remote connection; if error (0), discard this target.
239 In particular, if the user quits, be sure to discard it (we'd be
240 in an inconsistent state otherwise). */
241 if (!catch_errors (sds_start_remote
, NULL
,
242 "Couldn't establish connection to remote target\n",
247 /* This takes a program previously attached to and detaches it. After
248 this is done, GDB can be used to debug some other program. We
249 better not have left any breakpoints in the target program or it'll
250 die when it hits one. */
253 sds_detach (char *args
, int from_tty
)
258 error ("Argument given to \"detach\" when remotely debugging.");
261 /* Tell the remote target to detach. */
268 puts_filtered ("Ending remote debugging.\n");
271 /* Convert hex digit A to a number. */
276 if (a
>= '0' && a
<= '9')
278 else if (a
>= 'a' && a
<= 'f')
281 error ("Reply contains invalid hex digit %d", a
);
284 /* Convert number NIB to a hex digit. */
292 return 'a' + nib
- 10;
296 tob64 (unsigned char *inbuf
, char *outbuf
, int len
)
302 error ("bad length");
305 for (i
= 0; i
< len
; i
+= 3)
307 /* Collect the next three bytes into a number. */
308 sum
= ((long) *inbuf
++) << 16;
309 sum
|= ((long) *inbuf
++) << 8;
310 sum
|= ((long) *inbuf
++);
312 /* Spit out 4 6-bit encodings. */
313 *p
++ = ((sum
>> 18) & 0x3f) + '0';
314 *p
++ = ((sum
>> 12) & 0x3f) + '0';
315 *p
++ = ((sum
>> 6) & 0x3f) + '0';
316 *p
++ = (sum
& 0x3f) + '0';
322 fromb64 (char *inbuf
, char *outbuf
, int len
)
327 error ("bad length");
329 for (i
= 0; i
< len
; i
+= 4)
331 /* Collect 4 6-bit digits. */
332 sum
= (*inbuf
++ - '0') << 18;
333 sum
|= (*inbuf
++ - '0') << 12;
334 sum
|= (*inbuf
++ - '0') << 6;
335 sum
|= (*inbuf
++ - '0');
337 /* Now take the resulting 24-bit number and get three bytes out
339 *outbuf
++ = (sum
>> 16) & 0xff;
340 *outbuf
++ = (sum
>> 8) & 0xff;
341 *outbuf
++ = sum
& 0xff;
344 return (len
/ 4) * 3;
348 /* Tell the remote machine to resume. */
350 static enum target_signal last_sent_signal
= TARGET_SIGNAL_0
;
354 sds_resume (int pid
, int step
, enum target_signal siggnal
)
356 unsigned char buf
[PBUFSIZ
];
358 dcache_flush (sds_dcache
);
360 last_sent_signal
= siggnal
;
361 last_sent_step
= step
;
363 buf
[0] = (step
? 21 : 20);
364 buf
[1] = 0; /* (should be signal?) */
369 /* Send a message to target to halt it. Target will respond, and send
370 us a message pending notice. */
373 sds_interrupt (int signo
)
375 unsigned char buf
[PBUFSIZ
];
377 /* If this doesn't work, try more severe steps. */
378 signal (signo
, sds_interrupt_twice
);
381 fprintf_unfiltered (gdb_stdlog
, "sds_interrupt called\n");
387 static void (*ofunc
) ();
389 /* The user typed ^C twice. */
392 sds_interrupt_twice (int signo
)
394 signal (signo
, ofunc
);
398 signal (signo
, sds_interrupt
);
401 /* Ask the user what to do when an interrupt is received. */
404 interrupt_query (void)
406 target_terminal_ours ();
408 if (query ("Interrupted while waiting for the program.\n\
409 Give up (and stop debugging it)? "))
411 target_mourn_inferior ();
412 return_to_top_level (RETURN_QUIT
);
415 target_terminal_inferior ();
418 /* If nonzero, ignore the next kill. */
421 /* Wait until the remote machine stops, then return, storing status in
422 STATUS just as `wait' would. Returns "pid" (though it's not clear
423 what, if anything, that means in the case of this target). */
426 sds_wait (int pid
, struct target_waitstatus
*status
)
428 unsigned char buf
[PBUFSIZ
];
431 status
->kind
= TARGET_WAITKIND_EXITED
;
432 status
->value
.integer
= 0;
434 ofunc
= (void (*)()) signal (SIGINT
, sds_interrupt
);
436 signal (SIGINT
, ofunc
);
441 status
->kind
= TARGET_WAITKIND_STOPPED
;
452 retlen
= sds_send (buf
, 1);
455 fprintf_unfiltered (gdb_stdlog
, "Signals: %02x%02x %02x %02x\n",
460 status
->kind
= TARGET_WAITKIND_STOPPED
;
461 status
->value
.sig
= TARGET_SIGNAL_TRAP
;
469 static unsigned char sprs
[16];
471 /* Read the remote registers into the block REGS. */
472 /* Currently we just read all the registers, so we don't use regno. */
476 sds_fetch_registers (int regno
)
478 unsigned char buf
[PBUFSIZ
];
480 char regs
[REGISTER_BYTES
];
482 /* Unimplemented registers read as all bits zero. */
483 memset (regs
, 0, REGISTER_BYTES
);
488 retlen
= sds_send (buf
, 3);
490 for (i
= 0; i
< 4 * 6; ++i
)
491 regs
[i
+ 4 * 32 + 8 * 32] = buf
[i
];
492 for (i
= 0; i
< 4 * 4; ++i
)
493 sprs
[i
] = buf
[i
+ 4 * 7];
498 retlen
= sds_send (buf
, 3);
500 for (i
= 0; i
< retlen
; i
++)
503 /* (should warn about reply too short) */
505 for (i
= 0; i
< NUM_REGS
; i
++)
506 supply_register (i
, ®s
[REGISTER_BYTE (i
)]);
509 /* Prepare to store registers. Since we may send them all, we have to
510 read out the ones we don't want to change first. */
513 sds_prepare_to_store (void)
515 /* Make sure the entire registers array is valid. */
516 read_register_bytes (0, (char *) NULL
, REGISTER_BYTES
);
519 /* Store register REGNO, or all registers if REGNO == -1, from the contents
520 of REGISTERS. FIXME: ignores errors. */
523 sds_store_registers (int regno
)
525 unsigned char *p
, buf
[PBUFSIZ
];
528 /* Store all the special-purpose registers. */
534 for (i
= 0; i
< 4 * 6; i
++)
535 *p
++ = registers
[i
+ 4 * 32 + 8 * 32];
536 for (i
= 0; i
< 4 * 1; i
++)
538 for (i
= 0; i
< 4 * 4; i
++)
541 sds_send (buf
, p
- buf
);
543 /* Store all the general-purpose registers. */
549 for (i
= 0; i
< 4 * 32; i
++)
552 sds_send (buf
, p
- buf
);
556 /* Write memory data directly to the remote machine. This does not
557 inform the data cache; the data cache uses this. MEMADDR is the
558 address in the remote memory space. MYADDR is the address of the
559 buffer in our space. LEN is the number of bytes.
561 Returns number of bytes transferred, or 0 for error. */
564 sds_write_bytes (CORE_ADDR memaddr
, char *myaddr
, int len
)
566 int max_buf_size
; /* Max size of packet output buffer */
568 unsigned char buf
[PBUFSIZ
];
572 /* Chop the transfer down if necessary */
579 todo
= min (len
, max_buf_size
);
583 buf
[2] = (int) (memaddr
>> 24) & 0xff;
584 buf
[3] = (int) (memaddr
>> 16) & 0xff;
585 buf
[4] = (int) (memaddr
>> 8) & 0xff;
586 buf
[5] = (int) (memaddr
) & 0xff;
590 for (i
= 0; i
< todo
; i
++)
591 buf
[i
+ 8] = myaddr
[i
];
593 sds_send (buf
, 8 + todo
);
595 /* (should look at result) */
604 /* Read memory data directly from the remote machine. This does not
605 use the data cache; the data cache uses this. MEMADDR is the
606 address in the remote memory space. MYADDR is the address of the
607 buffer in our space. LEN is the number of bytes.
609 Returns number of bytes transferred, or 0 for error. */
612 sds_read_bytes (CORE_ADDR memaddr
, char *myaddr
, int len
)
614 int max_buf_size
; /* Max size of packet output buffer */
616 unsigned char buf
[PBUFSIZ
];
620 /* Chop the transfer down if necessary */
627 todo
= min (len
, max_buf_size
);
631 buf
[2] = (int) (memaddr
>> 24) & 0xff;
632 buf
[3] = (int) (memaddr
>> 16) & 0xff;
633 buf
[4] = (int) (memaddr
>> 8) & 0xff;
634 buf
[5] = (int) (memaddr
) & 0xff;
635 buf
[6] = (int) (todo
>> 8) & 0xff;
636 buf
[7] = (int) (todo
) & 0xff;
639 retlen
= sds_send (buf
, 9);
641 if (retlen
- 2 != todo
)
646 /* Reply describes memory byte by byte. */
648 for (i
= 0; i
< todo
; i
++)
649 myaddr
[i
] = buf
[i
+ 2];
659 /* Read or write LEN bytes from inferior memory at MEMADDR,
660 transferring to or from debugger address MYADDR. Write to inferior
661 if SHOULD_WRITE is nonzero. Returns length of data written or
662 read; 0 for error. */
666 sds_xfer_memory (memaddr
, myaddr
, len
, should_write
, target
)
671 struct target_ops
*target
; /* ignored */
673 return dcache_xfer_memory (sds_dcache
, memaddr
, myaddr
, len
, should_write
);
678 sds_files_info (struct target_ops
*ignore
)
680 puts_filtered ("Debugging over a serial connection, using SDS protocol.\n");
683 /* Stuff for dealing with the packets which are part of this protocol.
684 See comment at top of file for details. */
686 /* Read a single character from the remote end, masking it down to 7 bits. */
689 readchar (int timeout
)
693 ch
= SERIAL_READCHAR (sds_desc
, timeout
);
695 if (remote_debug
> 1 && ch
>= 0)
696 fprintf_unfiltered (gdb_stdlog
, "%c(%x)", ch
, ch
);
701 error ("Remote connection closed");
703 perror_with_name ("Remote communication error");
711 /* An SDS-style checksum is a sum of the bytes modulo 253. (Presumably
712 because 253, 254, and 255 are special flags in the protocol.) */
715 compute_checksum (int csum
, char *buf
, int len
)
719 for (i
= 0; i
< len
; ++i
)
720 csum
+= (unsigned char) buf
[i
];
726 /* Send the command in BUF to the remote machine, and read the reply
730 sds_send (unsigned char *buf
, int len
)
732 putmessage (buf
, len
);
734 return getmessage (buf
, 0);
737 /* Send a message to the remote machine. */
740 putmessage (unsigned char *buf
, int len
)
743 unsigned char csum
= 0;
744 char buf2
[PBUFSIZ
], buf3
[PBUFSIZ
];
745 unsigned char header
[3];
748 /* Copy the packet into buffer BUF2, encapsulating it
749 and giving it a checksum. */
751 if (len
> 170) /* Prosanity check */
756 fprintf_unfiltered (gdb_stdlog
, "Message to send: \"");
757 for (i
= 0; i
< len
; ++i
)
758 fprintf_unfiltered (gdb_stdlog
, "%02x", buf
[i
]);
759 fprintf_unfiltered (gdb_stdlog
, "\"\n");
771 header
[1] = next_msg_id
;
775 csum
= compute_checksum (csum
, buf
, len
);
776 csum
= compute_checksum (csum
, header
+ 1, 2);
780 tob64 (header
, p
, 3);
782 enclen
= tob64 (buf
, buf3
, ((len
+ 2) / 3) * 3);
784 for (i
= 0; i
< enclen
; ++i
)
789 next_msg_id
= (next_msg_id
+ 3) % 245;
791 /* Send it over and over until we get a positive ack. */
798 fprintf_unfiltered (gdb_stdlog
, "Sending encoded: \"%s\"", buf2
);
799 fprintf_unfiltered (gdb_stdlog
,
800 " (Checksum %d, id %d, length %d)\n",
801 header
[0], header
[1], header
[2]);
802 gdb_flush (gdb_stdlog
);
804 if (SERIAL_WRITE (sds_desc
, buf2
, p
- buf2
))
805 perror_with_name ("putmessage: write failed");
811 /* Come here after finding the start of the frame. Collect the rest
812 into BUF. Returns 0 on any error, 1 on success. */
815 read_frame (char *buf
)
824 c
= readchar (sds_timeout
);
830 fputs_filtered ("Timeout in mid-message, retrying\n", gdb_stdlog
);
834 fputs_filtered ("Saw new packet start in middle of old one\n",
836 return 0; /* Start a new packet, count retries */
844 fprintf_unfiltered (gdb_stdlog
, "Received encoded: \"%s\"\n",
850 if (bp
< buf
+ PBUFSIZ
- 1)
857 puts_filtered ("Message too long: ");
859 puts_filtered ("\n");
866 /* Read a packet from the remote machine, with error checking,
867 and store it in BUF. BUF is expected to be of size PBUFSIZ.
868 If FOREVER, wait forever rather than timing out; this is used
869 while the target is executing user code. */
872 getmessage (unsigned char *buf
, int forever
)
877 int val
, i
, len
, csum
;
878 unsigned char header
[3];
879 unsigned char inbuf
[500];
881 strcpy (buf
, "timeout");
885 timeout
= watchdog
> 0 ? watchdog
: -1;
889 timeout
= sds_timeout
;
893 for (tries
= 1; tries
<= MAX_TRIES
; tries
++)
895 /* This can loop forever if the remote side sends us characters
896 continuously, but if it pauses, we'll get a zero from readchar
897 because of timeout. Then we'll count that as a retry. */
899 /* Note that we will only wait forever prior to the start of a packet.
900 After that, we expect characters to arrive at a brisk pace. They
901 should show up within sds_timeout intervals. */
905 c
= readchar (timeout
);
907 if (c
== SERIAL_TIMEOUT
)
909 if (forever
) /* Watchdog went off. Kill the target. */
911 target_mourn_inferior ();
912 error ("Watchdog has expired. Target detached.\n");
915 fputs_filtered ("Timed out.\n", gdb_stdlog
);
919 while (c
!= '$' && c
!= '{');
921 /* We might have seen a "trigraph", a sequence of three characters
922 that indicate various sorts of communication state. */
926 /* Read the other two chars of the trigraph. */
927 c2
= readchar (timeout
);
928 c3
= readchar (timeout
);
930 fprintf_unfiltered (gdb_stdlog
, "Trigraph %c%c%c received\n",
940 val
= read_frame (inbuf
);
944 fromb64 (inbuf
, header
, 4);
945 /* (should check out other bits) */
946 fromb64 (inbuf
+ 4, buf
, strlen (inbuf
) - 4);
951 csum
= compute_checksum (csum
, buf
, len
);
952 csum
= compute_checksum (csum
, header
+ 1, 2);
954 if (csum
!= header
[0])
955 fprintf_unfiltered (gdb_stderr
,
956 "Checksum mismatch: computed %d, received %d\n",
959 if (header
[2] == 0xff)
960 fprintf_unfiltered (gdb_stderr
, "Requesting resend...\n");
964 fprintf_unfiltered (gdb_stdlog
,
965 "... (Got checksum %d, id %d, length %d)\n",
966 header
[0], header
[1], header
[2]);
967 fprintf_unfiltered (gdb_stdlog
, "Message received: \"");
968 for (i
= 0; i
< len
; ++i
)
970 fprintf_unfiltered (gdb_stdlog
, "%02x", (unsigned char) buf
[i
]);
972 fprintf_unfiltered (gdb_stdlog
, "\"\n");
975 /* no ack required? */
979 /* Try the whole thing again. */
981 /* need to do something here */
984 /* We have tried hard enough, and just can't receive the packet. Give up. */
986 printf_unfiltered ("Ignoring packet error, continuing...\n");
993 /* Don't try to do anything to the target. */
999 unpush_target (&sds_ops
);
1000 generic_mourn_inferior ();
1004 sds_create_inferior (char *exec_file
, char *args
, char **env
)
1006 inferior_pid
= 42000;
1008 /* Clean up from the last time we were running. */
1009 clear_proceed_status ();
1011 /* Let the remote process run. */
1012 proceed (bfd_get_start_address (exec_bfd
), TARGET_SIGNAL_0
, 0);
1016 sds_load (char *filename
, int from_tty
)
1018 generic_load (filename
, from_tty
);
1023 /* The SDS monitor has commands for breakpoint insertion, although it
1024 it doesn't actually manage the breakpoints, it just returns the
1025 replaced instruction back to the debugger. */
1028 sds_insert_breakpoint (CORE_ADDR addr
, char *contents_cache
)
1031 unsigned char *p
, buf
[PBUFSIZ
];
1036 *p
++ = (int) (addr
>> 24) & 0xff;
1037 *p
++ = (int) (addr
>> 16) & 0xff;
1038 *p
++ = (int) (addr
>> 8) & 0xff;
1039 *p
++ = (int) (addr
) & 0xff;
1041 retlen
= sds_send (buf
, p
- buf
);
1043 for (i
= 0; i
< 4; ++i
)
1044 contents_cache
[i
] = buf
[i
+ 2];
1050 sds_remove_breakpoint (CORE_ADDR addr
, char *contents_cache
)
1053 unsigned char *p
, buf
[PBUFSIZ
];
1058 *p
++ = (int) (addr
>> 24) & 0xff;
1059 *p
++ = (int) (addr
>> 16) & 0xff;
1060 *p
++ = (int) (addr
>> 8) & 0xff;
1061 *p
++ = (int) (addr
) & 0xff;
1062 for (i
= 0; i
< 4; ++i
)
1063 *p
++ = contents_cache
[i
];
1065 retlen
= sds_send (buf
, p
- buf
);
1073 sds_ops
.to_shortname
= "sds";
1074 sds_ops
.to_longname
= "Remote serial target with SDS protocol";
1075 sds_ops
.to_doc
= "Use a remote computer via a serial line; using the SDS protocol.\n\
1076 Specify the serial device it is connected to (e.g. /dev/ttya).";
1077 sds_ops
.to_open
= sds_open
;
1078 sds_ops
.to_close
= sds_close
;
1079 sds_ops
.to_detach
= sds_detach
;
1080 sds_ops
.to_resume
= sds_resume
;
1081 sds_ops
.to_wait
= sds_wait
;
1082 sds_ops
.to_fetch_registers
= sds_fetch_registers
;
1083 sds_ops
.to_store_registers
= sds_store_registers
;
1084 sds_ops
.to_prepare_to_store
= sds_prepare_to_store
;
1085 sds_ops
.to_xfer_memory
= sds_xfer_memory
;
1086 sds_ops
.to_files_info
= sds_files_info
;
1087 sds_ops
.to_insert_breakpoint
= sds_insert_breakpoint
;
1088 sds_ops
.to_remove_breakpoint
= sds_remove_breakpoint
;
1089 sds_ops
.to_kill
= sds_kill
;
1090 sds_ops
.to_load
= sds_load
;
1091 sds_ops
.to_create_inferior
= sds_create_inferior
;
1092 sds_ops
.to_mourn_inferior
= sds_mourn
;
1093 sds_ops
.to_stratum
= process_stratum
;
1094 sds_ops
.to_has_all_memory
= 1;
1095 sds_ops
.to_has_memory
= 1;
1096 sds_ops
.to_has_stack
= 1;
1097 sds_ops
.to_has_registers
= 1;
1098 sds_ops
.to_has_execution
= 1;
1099 sds_ops
.to_magic
= OPS_MAGIC
;
1102 /* Put a command string, in args, out to the monitor and display the
1106 sds_command (char *args
, int from_tty
)
1110 unsigned char buf
[1000];
1112 /* Convert hexadecimal chars into a byte buffer. */
1117 buf
[len
++] = fromhex (p
[0]) * 16 + fromhex (p
[1]);
1123 retlen
= sds_send (buf
, len
);
1125 printf_filtered ("Reply is ");
1126 for (i
= 0; i
< retlen
; ++i
)
1128 printf_filtered ("%02x", buf
[i
]);
1130 printf_filtered ("\n");
1134 _initialize_remote_sds (void)
1137 add_target (&sds_ops
);
1139 add_show_from_set (add_set_cmd ("sdstimeout", no_class
,
1140 var_integer
, (char *) &sds_timeout
,
1141 "Set timeout value for sds read.\n", &setlist
),
1144 add_com ("sds", class_obscure
, sds_command
,
1145 "Send a command to the SDS monitor.");