OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.0/] [gdb/] [xmodem.c] - Blame information for rev 1774

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 104 markom
/* XMODEM support for GDB, the GNU debugger.
2
   Copyright 1995 Free Software Foundation, Inc.
3
 
4
   This file is part of GDB.
5
 
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.
10
 
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.
15
 
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.  */
20
 
21
#include "defs.h"
22
#include "serial.h"
23
#include "target.h"
24
#include "xmodem.h"
25
 
26
/* These definitions are for xmodem protocol. */
27
 
28
#define SOH     0x01
29
#define STX     0x02
30
#define ACK     0x06
31
#define NAK     0x15
32
#define EOT     0x04
33
#define CANCEL  0x18
34
 
35
static int blknum;              /* XMODEM block number */
36
static int crcflag;             /* Sez we are using CRC's instead of cksums */
37
 
38
static int
39
readchar (desc, timeout)
40
     serial_t desc;
41
     int timeout;
42
{
43
  int c;
44
 
45
  c = SERIAL_READCHAR (desc, timeout);
46
 
47
  if (remote_debug > 0)
48
    fputc_unfiltered (c, gdb_stdlog);
49
 
50
  if (c >= 0)
51
    return c;
52
 
53
  if (c == SERIAL_TIMEOUT)
54
    error ("Timeout reading from remote system.");
55
 
56
  perror_with_name ("xmodem.c:readchar()");
57
}
58
 
59
#define CRC16 0x1021            /* Generator polynomial (X^16 + X^12 + X^5 + 1) */
60
 
61
static unsigned short *crctab;
62
 
63
/* Call this to init the fast CRC-16 calculation table.  */
64
 
65
static void
66
crcinit ()
67
{
68
  static int crctab_inited = 0;
69
  int val;
70
 
71
  if (crctab_inited == 1)
72
    return;
73
 
74
  crctab = xmalloc (256 * sizeof (short));
75
 
76
  for (val = 0; val <= 255; val++)
77
    {
78
      int i;
79
      unsigned int crc;
80
 
81
      crc = val << 8;
82
 
83
      for (i = 0; i < 8; ++i)
84
        {
85
          crc <<= 1;
86
 
87
          if (crc & 0x10000)
88
            crc ^= CRC16;
89
        }
90
 
91
      crctab[val] = crc;
92
    }
93
 
94
  crctab_inited = 1;
95
}
96
 
97
/* Calculate a CRC-16 for the LEN byte message pointed at by P.  */
98
 
99
static unsigned short
100
docrc (p, len)
101
     unsigned char *p;
102
     int len;
103
{
104
  unsigned short crc = 0;
105
 
106
  while (len-- > 0)
107
    crc = (crc << 8) ^ crctab[(crc >> 8) ^ *p++];
108
 
109
  return crc;
110
}
111
 
112
/* Start up the transmit process.  Reset state variables.  Wait for receiver to
113
   send NAK or CRC request.  */
114
 
115
int
116
xmodem_init_xfer (desc)
117
     serial_t desc;
118
{
119
  int c;
120
  int i;
121
 
122
  blknum = 1;
123
  crcflag = 0;
124
  crcinit ();
125
 
126
  for (i = 1; i <= 10; i++)
127
    {
128
      c = readchar (desc, 6);
129
 
130
      switch (c)
131
        {
132
        case 'C':
133
          crcflag = 1;
134
        case NAK:
135
          return 0;
136
        default:
137
          fprintf_unfiltered (gdb_stderr, "xmodem_init_xfer: Got unexpected character %c (0%o)\n", c, c);
138
          continue;
139
        case CANCEL:            /* target aborted load */
140
          fprintf_unfiltered (gdb_stderr, "Got a CANCEL from the target.\n");
141
          continue;
142
        }
143
    }
144
  error ("xmodem_init_xfer:  Too many unexpected characters.");
145
}
146
 
147
/* Take 128 bytes of data and make a packet out of it.
148
 
149
 *      Each packet looks like this:
150
 *      +-----+-------+-------+------+-----+
151
 *      | SOH | Seq1. | Seq2. | data | SUM |
152
 *      +-----+-------+-------+------+-----+
153
 *      SOH  = 0x01
154
 *      Seq1 = The sequence number.
155
 *      Seq2 = The complement of the sequence number.
156
 *      Data = A 128 bytes of data.
157
 *      SUM  = Add the contents of the 128 bytes and use the low-order
158
 *             8 bits of the result.
159
 *
160
 * send_xmodem_packet fills in the XMODEM fields of PACKET and sends it to the
161
 * remote system.  PACKET must be XMODEM_PACKETSIZE bytes long.  The data must
162
 * start 3 bytes after the beginning of the packet to leave room for the
163
 * XMODEM header.  LEN is the length of the data portion of the packet (and
164
 * must be <= 128 bytes).  If it is < 128 bytes, ^Z padding will be added.
165
 */
166
 
167
void
168
xmodem_send_packet (desc, packet, len, hashmark)
169
     serial_t desc;
170
     unsigned char *packet;
171
     int len;
172
     int hashmark;
173
{
174
  int i;
175
  int retries;
176
  int pktlen;
177
  int datasize;
178
 
179
  /* build the packet header */
180
 
181
  packet[1] = blknum;
182
  packet[2] = ~blknum;
183
 
184
  blknum++;
185
 
186
  if (len <= XMODEM_DATASIZE)
187
    {
188
      packet[0] = SOH;
189
      datasize = XMODEM_DATASIZE;
190
    }
191
  else if (len <= XMODEM_1KDATASIZE)
192
    {
193
      packet[0] = STX;
194
      datasize = XMODEM_1KDATASIZE;
195
    }
196
  else
197
    abort ();                   /* Packet way too large */
198
 
199
  /* Add ^Z padding if packet < 128 (or 1024) bytes */
200
 
201
  memset (packet + 3 + len, '\026', datasize - len);
202
 
203
  if (crcflag)
204
    {
205
      int crc;
206
 
207
      crc = docrc (packet + 3, datasize);
208
 
209
      packet[3 + datasize] = crc >> 8;
210
      packet[3 + datasize + 1] = crc;
211
      pktlen = datasize + 5;
212
    }
213
  else
214
    {
215
      int sum;
216
 
217
      sum = 0;
218
      for (i = 3; i < datasize + 3; i++)
219
        sum += packet[i];
220
 
221
      packet[3 + datasize] = sum;       /* add the checksum */
222
      pktlen = datasize + 4;
223
    }
224
 
225
  for (retries = 3; retries >= 0; retries--)
226
    {
227
      int c;
228
 
229
      SERIAL_WRITE (desc, packet, pktlen);
230
 
231
      c = readchar (desc, 3);
232
      switch (c)
233
        {
234
        case ACK:
235
          return;
236
        case NAK:
237
          if (!hashmark)
238
            continue;
239
          putchar_unfiltered ('-');
240
          gdb_flush (gdb_stdout);
241
          continue;
242
        case CANCEL:
243
          error ("xmodem_send_packet: Transfer aborted by receiver.");
244
        default:
245
          fprintf_unfiltered (gdb_stderr, "xmodem_send_packet: Got unexpected character %c (0%o)\n", c, c);
246
          continue;
247
        }
248
    }
249
 
250
  SERIAL_WRITE (desc, "\004", 1);       /* Send an EOT */
251
 
252
  error ("xmodem_send_packet:  Excessive retries.");
253
}
254
 
255
/* Finish off the transfer.  Send out the EOT, and wait for an ACK.  */
256
 
257
void
258
xmodem_finish_xfer (desc)
259
     serial_t desc;
260
{
261
  int retries;
262
 
263
  for (retries = 10; retries >= 0; retries--)
264
    {
265
      int c;
266
 
267
      SERIAL_WRITE (desc, "\004", 1);   /* Send an EOT */
268
 
269
      c = readchar (desc, 3);
270
      switch (c)
271
        {
272
        case ACK:
273
          return;
274
        case NAK:
275
          continue;
276
        case CANCEL:
277
          error ("xmodem_finish_xfer: Transfer aborted by receiver.");
278
        default:
279
          fprintf_unfiltered (gdb_stderr, "xmodem_send_packet: Got unexpected character %c (0%o)\n", c, c);
280
          continue;
281
        }
282
    }
283
 
284
  error ("xmodem_finish_xfer:  Excessive retries.");
285
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.