⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xmodem.c

📁 深圳优龙LPC22xx开发板bios源码仅供参考
💻 C
字号:
/*-------------------------------------------------------------------------
 * Filename:	  xmodem.c
 * Version: 	  $Id: xmodem.c,v 1.2 2002/01/06 19:02:29 erikm Exp $
 * Copyright:     Copyright (C) 2001, Hewlett-Packard Company
 * Author:  	  Christopher Hoover <ch@hpl.hp.com>
 * Description:   xmodem functionality for uploading of kernels 
 *  			  and the like
 * Created at:    Thu Dec 20 01:58:08 PST 2001
 *-----------------------------------------------------------------------*/
/*
 * xmodem.c: xmodem functionality for uploading of kernels and 
 *  		  the like
 *
 * Copyright (C) 2001 Hewlett-Packard Laboratories
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 */

#ident "$Id: xmodem.c,v 1.2 2002/01/06 19:02:29 erikm Exp $"

//#ifdef HAVE_CONFIG_H
//# include <blob/config.h>
//#endif

//#include <blob/errno.h>
//#include <blob/serial.h>
//#include <blob/util.h>

#include <../inc/board.h>

#define	UART_RD_TMOUT	300000
#define TIMEOUT 	800
#define MAXERRORS	10//5

#define	serial_write_raw(cc)	putch(cc)

static int SerialInputBlock( char* buf , unsigned long count ,
	unsigned long timeout )
{
	/*	unsigned long i;
		
		do {
			i = 0;
			while(!SerialRxToBuf(buf) && (i++ < UART_RD_TMOUT));
			if(i < UART_RD_TMOUT)
				return 1;			//只读一个字符
		} while(--timeout);
		return -1;*/	

	if ( !WaitEventWithTimeout( kbhit , 1 , timeout ) )
	{
		*buf = getch();
		return 1;
	}
	return 0;
}

//#include "ser2.c"
#define SOH 0x01
#define STX 0x02
#define EOT 0x04
#define ACK 0x06
#define NAK 0x15
#define CAN 0x18
#define BS  0x08

/*

Cf:

  http://www.textfiles.com/apple/xmodem
  http://www.phys.washington.edu/~belonis/xmodem/docxmodem.txt
  http://www.phys.washington.edu/~belonis/xmodem/docymodem.txt
  http://www.phys.washington.edu/~belonis/xmodem/modmprot.col

*/

#undef	ERROR
#define ERROR(...) do { } while (0)

//#define	ERROR	Uart_Printf


//static char blockBuf[1024];
static char* blockBuf;			//使用指针,去掉copy过程

static __inline void WriteByte( char cc )
{
	serial_write_raw( cc );
}

int ReadByteWithTimeout( unsigned int timeout )
{
	char buf[1];
	int n;

	n = SerialInputBlock( buf , 1 , timeout );

	if ( n == 1 )
		return buf[0] & 0xff;
	else
		return -1;
}

static void ReadFlush()
{
	while ( ReadByteWithTimeout( 1000 ) >= 0 );
}


int XModemReceive( char* bufBase , int bufLen )
{
	unsigned int errors = 0;
	unsigned int wantBlockNo = 1;
	unsigned int length = 0;
	int crc = 1;		//use crc by send 'C', use checksum by send NAK
	char nak = 'C';
	int crc_val;
	unsigned char expectedCksum;

	blockBuf = bufBase;		//将bufBase赋与blockBuf;

	ERROR( "start xmodem!\n" );

	ReadFlush();

	/* Ask for CRC; if we get errors, we will go with checksum */
	WriteByte( nak );
	ERROR( "WriteByte(nak)\n" );

	for ( ; ; )
	{
		int blockBegin;
		int blockNo, blockNoOnesCompl;
		int blockLength;
		int cksum = 0;
		int crcHi = 0;
		int crcLo = 0;

		blockBegin = ReadByteWithTimeout( TIMEOUT );
		if ( blockBegin < 0 )
		{
			ERROR( "Read blockBegin timeout!\n" );
			goto timeout;
		}

		nak = NAK;

		switch ( blockBegin )
		{
			case SOH:
			case STX:
				break;

			case EOT:
				WriteByte( ACK );
				ERROR( "WriteByte(ACK): done\n" );
				goto done;

			default:
				ERROR( "blockBegin error!\n" );
				errors--;
				goto error;
		}

		/* block no */
		blockNo = ReadByteWithTimeout( TIMEOUT );
		if ( blockNo < 0 )
		{
			ERROR( "blockNo timeout!\n" );
			goto timeout;
		}

		/* block no one's compliment */
		blockNoOnesCompl = ReadByteWithTimeout( TIMEOUT );
		if ( blockNoOnesCompl < 0 )
		{
			ERROR( "blockNoOnesCompl timeout!\n" );
			goto timeout;
		}

		if ( blockNo != ( 255 - blockNoOnesCompl ) )
		{
			ERROR( "bad block ones compl\n" );
			goto error;
		}

		blockLength = ( blockBegin == SOH ) ? 128 : 1024;
		{
			int i, j;

			crc_val = 0;			
			expectedCksum = 0;

			for ( i = 0; i < blockLength; i++ )
			{
				int cc = ReadByteWithTimeout( TIMEOUT );
				if ( cc < 0 )
				{
					ERROR( " read block byte timeout!\n" );
					goto timeout;
				}
				blockBuf[i] = cc;		

				//crc 或 checksum 计算加在读数据后
				if ( crc )
				{
					crc_val = crc_val ^ cc << 8;
					for ( j = 0; j < 8; j++ )
						if ( crc_val & 0x8000 )
							crc_val = crc_val << 1 ^ 0x1021;
						else
							crc_val = crc_val << 1;
				}
				else
				{
					expectedCksum += cc;
				}
			}
		}

		if ( crc )
		{
			crcHi = ReadByteWithTimeout( TIMEOUT );
			if ( crcHi < 0 )
			{
				ERROR( " read crcHi timeout!\n" );
				goto timeout;
			}

			crcLo = ReadByteWithTimeout( TIMEOUT );
			if ( crcLo < 0 )
			{
				ERROR( " read crcLo timeout!\n" );
				goto timeout;
			}			

			if ( ( crcHi != ( ( crc_val >> 8 ) & 0xff ) ) ||
				( crcLo != ( crc_val & 0xff ) ) )
			{
				ERROR( "crc error!\n" );
				goto error;
			}
		}
		else
		{
			cksum = ReadByteWithTimeout( TIMEOUT );
			if ( cksum < 0 )
			{
				ERROR( " read chksum timeout!\n" );
				goto timeout;
			}

			if ( cksum != expectedCksum )
			{
				ERROR( "checksum error! \n" );
				goto error;
			}
		}

		if ( blockNo == ( ( wantBlockNo - 1 ) & 0xff ) )
		{
			/* a repeat of the last block is ok, just ignore it. */
			/* this also ignores the initial block 0 which is */
			/* meta data. */
			goto next;
		}
		else if ( blockNo != ( wantBlockNo & 0xff ) )
		{
			ERROR( "unexpected block no! \n" );
			goto error;
		}

		wantBlockNo++;
		length += blockLength;

		if ( length > bufLen )
		{
			ERROR( "out of space\n" );
			goto error;
		}

		/*		{
						int i;
						for (i = 0; i < blockLength; i++)
							*bufBase++ = blockBuf[i];
					}*/
		blockBuf += blockLength;	//接收成功,指针加上收到字节数
		next : errors = 0;
		WriteByte( ACK );
		ERROR( "Receive one block OK!\n" );
		continue;

		error : timeout : ERROR( "Timeout.\n" );
		errors++;
		if ( errors == MAXERRORS )
		{
			/* Abort */
			int i;

			// if using crc, try again w/o crc
			if ( nak == 'C' )
			{
				nak = NAK;
				errors = 0;
				crc = 0;		//use checksum
				goto timeout;
			}

			for ( i = 0; i < 5; i ++ )
				WriteByte( CAN );
			for ( i = 0; i < 5; i ++ )
				WriteByte( BS );
			puts( "too many errors; giving up\n" );
			return -1;
		}

		ReadFlush();
		WriteByte( nak );
		ERROR( "WriteByte(nak)\n" );
	}

	done : ERROR( "\nxmodem done.\n" );
	ReadFlush();
	return length;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -