示例#1
0
bool
mon_read_char_with_timeout(unsigned char *c)
{
    bool res = false;
    hal_virtual_comm_table_t *__chan;

#ifdef CYGPKG_REDBOOT_ANY_CONSOLE
    if (!console_selected) {
        int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
        int i, j, tot;
        // Try input from all channels
        tot = 0;
        while (tot < _mon_timeout) {
            for (i = 0;  i < CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS;  i++, tot++) {
                CYGACC_CALL_IF_SET_CONSOLE_COMM(i);
                __chan = CYGACC_CALL_IF_CONSOLE_PROCS();
                res = CYGACC_COMM_IF_GETC_TIMEOUT(*__chan, c);
                if (res) {
                    // Input available on this channel, make it be the console
                    if (*c != '\0') {
                        // Don't chose this unless real data have arrived
                        console_selected = true;
                        CYGACC_CALL_IF_SET_DEBUG_COMM(i);
                        // Disable interrupts on all channels but this one
                        for (j = 0;  j < CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS;  j++) {
                            if (i != j) {
                                CYGACC_CALL_IF_SET_CONSOLE_COMM(j);
                                __chan = CYGACC_CALL_IF_CONSOLE_PROCS();
                                CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_IRQ_DISABLE);
                            }
                        }
                        CYGACC_CALL_IF_SET_CONSOLE_COMM(i);
                        return res;
                    }
                }
            }
        }
        CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);        
    } else 
#endif
    {
        __chan = CYGACC_CALL_IF_CONSOLE_PROCS();
        if (__chan)
            res = CYGACC_COMM_IF_GETC_TIMEOUT(*__chan, c);
        else {
            __chan = CYGACC_CALL_IF_DEBUG_PROCS();
            res = CYGACC_COMM_IF_GETC_TIMEOUT(*__chan, c);
        }
    }
    return res;
}
示例#2
0
/* Wait for the line to go idle */
static void
xyzModem_flush(void)
{
    int res;
    char c;
    while (true) {
        res = CYGACC_COMM_IF_GETC_TIMEOUT(*xyz.__chan, &c);
        if (!res) return;
    }
}
示例#3
0
static void
cyg_hal_diag_mangler_gdb_flush(void* __ch_data)
{
    CYG_INTERRUPT_STATE old;
    hal_virtual_comm_table_t* __chan = CYGACC_CALL_IF_DEBUG_PROCS();
#if CYGNUM_HAL_DEBUG_GDB_PROTOCOL_RETRIES != 0
    int tries = CYGNUM_HAL_DEBUG_GDB_PROTOCOL_RETRIES;
#endif


    // Nothing to do if mangler buffer is empty.
    if (__mangler_pos == 0)
        return;

    // Disable interrupts. This prevents GDB trying to interrupt us
    // while we are in the middle of sending a packet. The serial
    // receive interrupt will be seen when we re-enable interrupts
    // later.
#if defined(CYG_HAL_STARTUP_ROM) \
    || !defined(CYG_HAL_GDB_ENTER_CRITICAL_IO_REGION)
    HAL_DISABLE_INTERRUPTS(old);
#else
    CYG_HAL_GDB_ENTER_CRITICAL_IO_REGION(old);
#endif
        
#if CYGNUM_HAL_DEBUG_GDB_PROTOCOL_RETRIES != 0
    // Only wait 500ms for data to arrive - avoid "stuck" connections
    CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_SET_TIMEOUT, CYGNUM_HAL_DEBUG_GDB_PROTOCOL_TIMEOUT);
#endif

    while(1)
    {
	static const char hex[] = "0123456789ABCDEF";
	cyg_uint8 csum = 0;
	char c1;
	int i;
        
	CYGACC_COMM_IF_PUTC(*__chan, '$');
	CYGACC_COMM_IF_PUTC(*__chan, 'O');
	csum += 'O';
	for( i = 0; i < __mangler_pos; i++ )
        {
	    char ch = __mangler_line[i];
	    char h = hex[(ch>>4)&0xF];
	    char l = hex[ch&0xF];
	    CYGACC_COMM_IF_PUTC(*__chan, h);
	    CYGACC_COMM_IF_PUTC(*__chan, l);
	    csum += h;
	    csum += l;
	}
	CYGACC_COMM_IF_PUTC(*__chan, '#');
	CYGACC_COMM_IF_PUTC(*__chan, hex[(csum>>4)&0xF]);
	CYGACC_COMM_IF_PUTC(*__chan, hex[csum&0xF]);

    nak:
#if CYGNUM_HAL_DEBUG_GDB_PROTOCOL_RETRIES != 0
	if (CYGACC_COMM_IF_GETC_TIMEOUT(*__chan, &c1) == 0) {
	    c1 = '-';
	    if (tries && (--tries == 0)) c1 = '+';
	}
#else
	c1 = CYGACC_COMM_IF_GETC(*__chan);
#endif

	if( c1 == '+' ) break;

	if( cyg_hal_is_break( &c1 , 1 ) ) {
	    // Caller's responsibility to react on this.
	    CYGACC_CALL_IF_CONSOLE_INTERRUPT_FLAG_SET(1);
	    break;
	}
	if( c1 != '-' ) goto nak;
    }

    __mangler_pos = 0;
    // And re-enable interrupts
#if defined(CYG_HAL_STARTUP_ROM) \
    || !defined(CYG_HAL_GDB_ENTER_CRITICAL_IO_REGION)
    HAL_RESTORE_INTERRUPTS(old);
#else
    CYG_HAL_GDB_LEAVE_CRITICAL_IO_REGION(old);
#endif
}
static int
xyzModem_get_hdr (void)
{
  char c;
  int res;
  bool hdr_found = false;
  int i, can_total, hdr_chars;
  unsigned short cksum;

  ZM_DEBUG (zm_new ());
  /* Find the start of a header */
  can_total = 0;
  hdr_chars = 0;

  if (xyz.tx_ack)
    {
      CYGACC_COMM_IF_PUTC (*xyz.__chan, ACK);
      xyz.tx_ack = false;
    }
  while (!hdr_found)
    {
      res = CYGACC_COMM_IF_GETC_TIMEOUT (*xyz.__chan, &c);
      ZM_DEBUG (zm_save (c));
      if (res)
	{
	  hdr_chars++;
	  switch (c)
	    {
	    case SOH:
	      xyz.total_SOH++;
	    case STX:
	      if (c == STX)
		xyz.total_STX++;
	      hdr_found = true;
	      break;
	    case CAN:
	      xyz.total_CAN++;
	      ZM_DEBUG (zm_dump (__LINE__));
	      if (++can_total == xyzModem_CAN_COUNT)
		{
		  return xyzModem_cancel;
		}
	      else
		{
		  /* Wait for multiple CAN to avoid early quits */
		  break;
		}
	    case EOT:
	      /* EOT only supported if no noise */
	      if (hdr_chars == 1)
		{
		  CYGACC_COMM_IF_PUTC (*xyz.__chan, ACK);
		  ZM_DEBUG (zm_dprintf ("ACK on EOT #%d\n", __LINE__));
		  ZM_DEBUG (zm_dump (__LINE__));
		  return xyzModem_eof;
		}
	    default:
	      /* Ignore, waiting for start of header */
	      ;
	    }
	}
      else
	{
	  /* Data stream timed out */
	  xyzModem_flush ();	/* Toss any current input */
	  ZM_DEBUG (zm_dump (__LINE__));
	  CYGACC_CALL_IF_DELAY_US ((cyg_int32) 250000);
	  return xyzModem_timeout;
	}
    }

  /* Header found, now read the data */
  res = CYGACC_COMM_IF_GETC_TIMEOUT (*xyz.__chan, (char *) &xyz.blk);
  ZM_DEBUG (zm_save (xyz.blk));
  if (!res)
    {
      ZM_DEBUG (zm_dump (__LINE__));
      return xyzModem_timeout;
    }
  res = CYGACC_COMM_IF_GETC_TIMEOUT (*xyz.__chan, (char *) &xyz.cblk);
  ZM_DEBUG (zm_save (xyz.cblk));
  if (!res)
    {
      ZM_DEBUG (zm_dump (__LINE__));
      return xyzModem_timeout;
    }
  xyz.len = (c == SOH) ? 128 : 1024;
  xyz.bufp = xyz.pkt;
  for (i = 0; i < xyz.len; i++)
    {
      res = CYGACC_COMM_IF_GETC_TIMEOUT (*xyz.__chan, &c);
      ZM_DEBUG (zm_save (c));
      if (res)
	{
	  xyz.pkt[i] = c;
	}
      else
	{
	  ZM_DEBUG (zm_dump (__LINE__));
	  return xyzModem_timeout;
	}
    }
  res = CYGACC_COMM_IF_GETC_TIMEOUT (*xyz.__chan, (char *) &xyz.crc1);
  ZM_DEBUG (zm_save (xyz.crc1));
  if (!res)
    {
      ZM_DEBUG (zm_dump (__LINE__));
      return xyzModem_timeout;
    }
  if (xyz.crc_mode)
    {
      res = CYGACC_COMM_IF_GETC_TIMEOUT (*xyz.__chan, (char *) &xyz.crc2);
      ZM_DEBUG (zm_save (xyz.crc2));
      if (!res)
	{
	  ZM_DEBUG (zm_dump (__LINE__));
	  return xyzModem_timeout;
	}
    }
  ZM_DEBUG (zm_dump (__LINE__));
  /* Validate the message */
  if ((xyz.blk ^ xyz.cblk) != (unsigned char) 0xFF)
    {
      ZM_DEBUG (zm_dprintf
		("Framing error - blk: %x/%x/%x\n", xyz.blk, xyz.cblk,
		 (xyz.blk ^ xyz.cblk)));
      ZM_DEBUG (zm_dump_buf (xyz.pkt, xyz.len));
      xyzModem_flush ();
      return xyzModem_frame;
    }
  /* Verify checksum/CRC */
  if (xyz.crc_mode)
    {
      cksum = cyg_crc16 (xyz.pkt, xyz.len);
      if (cksum != ((xyz.crc1 << 8) | xyz.crc2))
	{
	  ZM_DEBUG (zm_dprintf ("CRC error - recvd: %02x%02x, computed: %x\n",
				xyz.crc1, xyz.crc2, cksum & 0xFFFF));
	  return xyzModem_cksum;
	}
    }
  else
    {
      cksum = 0;
      for (i = 0; i < xyz.len; i++)
	{
	  cksum += xyz.pkt[i];
	}
      if (xyz.crc1 != (cksum & 0xFF))
	{
	  ZM_DEBUG (zm_dprintf
		    ("Checksum error - recvd: %x, computed: %x\n", xyz.crc1,
		     cksum & 0xFF));
	  return xyzModem_cksum;
	}
    }
  /* If we get here, the message passes [structural] muster */
  return 0;
}
示例#5
0
int
xyzModem_stream_read (char *buf, int size, int *err)
{
    int stat, total, len;
    int retries;

    total = 0;
    stat = xyzModem_cancel;
    /* Try and get 'size' bytes into the buffer */
    while (!xyz.at_eof && (size > 0))
    {
        if (xyz.len == 0)
        {
            retries = xyzModem_MAX_RETRIES;
            while (retries-- > 0)
            {
                stat = xyzModem_get_hdr ();
                if (stat == 0)
                {
                    if (xyz.blk == xyz.next_blk)
                    {
                        xyz.tx_ack = true;
                        ZM_DEBUG (zm_dprintf
                                  ("ACK block %d (%d)\n", xyz.blk, __LINE__));
                        xyz.next_blk = (xyz.next_blk + 1) & 0xFF;

#if defined(xyzModem_zmodem) || defined(USE_YMODEM_LENGTH)
                        if (xyz.mode == xyzModem_xmodem || xyz.file_length == 0)
                        {
#else
                        if (1)
                        {
#endif
                            /* Data blocks can be padded with ^Z (EOF) characters */
                            /* This code tries to detect and remove them */
                            if ((xyz.bufp[xyz.len - 1] == EOF) &&
                                    (xyz.bufp[xyz.len - 2] == EOF) &&
                                    (xyz.bufp[xyz.len - 3] == EOF))
                            {
                                while (xyz.len
                                        && (xyz.bufp[xyz.len - 1] == EOF))
                                {
                                    xyz.len--;
                                }
                            }
                        }

#ifdef USE_YMODEM_LENGTH
                        /*
                         * See if accumulated length exceeds that of the file.
                         * If so, reduce size (i.e., cut out pad bytes)
                         * Only do this for Y-modem (and Z-modem should it ever
                         * be supported since it can fall back to Y-modem mode).
                         */
                        if (xyz.mode != xyzModem_xmodem && 0 != xyz.file_length)
                        {
                            xyz.read_length += xyz.len;
                            if (xyz.read_length > xyz.file_length)
                            {
                                xyz.len -= (xyz.read_length - xyz.file_length);
                            }
                        }
#endif
                        break;
                    }
                    else if (xyz.blk == ((xyz.next_blk - 1) & 0xFF))
                    {
                        /* Just re-ACK this so sender will get on with it */
                        CYGACC_COMM_IF_PUTC (*xyz.__chan, ACK);
                        continue;	/* Need new header */
                    }
                    else
                    {
                        stat = xyzModem_sequence;
                    }
                }
                if (stat == xyzModem_cancel)
                {
                    break;
                }
                if (stat == xyzModem_eof)
                {
                    CYGACC_COMM_IF_PUTC (*xyz.__chan, ACK);
                    ZM_DEBUG (zm_dprintf ("ACK (%d)\n", __LINE__));
                    if (xyz.mode == xyzModem_ymodem)
                    {
                        CYGACC_COMM_IF_PUTC (*xyz.__chan,
                                             (xyz.crc_mode ? 'C' : NAK));
                        xyz.total_retries++;
                        ZM_DEBUG (zm_dprintf ("Reading Final Header\n"));
                        stat = xyzModem_get_hdr ();
                        CYGACC_COMM_IF_PUTC (*xyz.__chan, ACK);
                        ZM_DEBUG (zm_dprintf ("FINAL ACK (%d)\n", __LINE__));
                    }
                    xyz.at_eof = true;
                    break;
                }
                CYGACC_COMM_IF_PUTC (*xyz.__chan, (xyz.crc_mode ? 'C' : NAK));
                xyz.total_retries++;
                ZM_DEBUG (zm_dprintf ("NAK (%d)\n", __LINE__));
            }
            if (stat < 0)
            {
                *err = stat;
                xyz.len = -1;
                return total;
            }
        }
        /* Don't "read" data from the EOF protocol package */
        if (!xyz.at_eof)
        {
            len = xyz.len;
            if (size < len)
                len = size;
            memcpy (buf, xyz.bufp, len);
            size -= len;
            buf += len;
            total += len;
            xyz.len -= len;
            xyz.bufp += len;
        }
    }
    return total;
}

int
xyzModem_stream_write(ulong src,long size)
{
    char c;
    unsigned char  *psrc;
    unsigned short cksum;
    int ultlen = 0;
    int total = 0;
    int retry, i, res;
    int flag_ok = 0;
    int flag_frame = 0;
    psrc =(unsigned char *)src;
    xyz.blk  = 1;
    xyz.cblk = ~xyz.blk;
    xyz.len  = xyzModem_1k;

    for (retry = 0; retry < 300; ++retry) {
        res = CYGACC_COMM_IF_GETC_TIMEOUT (*xyz.__chan, &c);
        if (res) {
            switch (c) {
            case 'C':
                xyz.crc_mode = true;
                flag_ok = 1;
                ZM_DEBUG (zm_dprintf ("Receive char CRC***\n"));
                break;
            case NAK:
                xyz.crc_mode = false;
                flag_ok = 1;
                ZM_DEBUG (zm_dprintf ("Receive char NAK***\n"));
                break;
            case CAN:
                ZM_DEBUG (zm_dprintf ("Receive char cancel***\n"));
                CYGACC_COMM_IF_GETC_TIMEOUT (*xyz.__chan, &c);
                if (c == CAN) {
                    serial_putc_raw(ACK);
                    xyzModem_flush ();
                    return -1;
                }
                break;
            default:
                ZM_DEBUG (zm_dprintf ("Receive  char %x***\n",c));
                break;
            }
        }
        if (flag_ok == 1)
            break;
    }

    if (flag_ok == 0) {
        serial_putc_raw(CAN);
        serial_putc_raw(CAN);
        serial_putc_raw(CAN);
        xyzModem_flush ();
        return -2;
    }

    while(1) {
        flag_frame = 0;
        ultlen = size - total;

        if (ultlen > xyz.len)
            ultlen = xyz.len;

        if (ultlen > 0) {
            memcpy (xyz.pkt, &psrc[total], ultlen);
            if (ultlen < xyz.len) {
                memset (&xyz.pkt[ultlen], EOF, xyz.len-ultlen);
            }

            if (xyz.crc_mode) {
                cksum = cyg_crc16(xyz.pkt, xyz.len);
                xyz.crc1 = (cksum >> 8) & 0xFF;
                xyz.crc2 = cksum & 0xFF;
                ZM_DEBUG (zm_dprintf ("add crc check***\n"));
            } else {