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

Subversion Repositories or1k

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

powered by: WebSVN 2.1.0

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