xymodem.c

来自「ADS下的bios工程」· C语言 代码 · 共 321 行

C
321
字号
#include <bios/s3c2410x.h>#include <bios/xymodem.h>#include <bios/boot.h>#include <bios/malloc.h>#include <bios/time.h>#include <bios/stdio.h>#include <bios/stdioint.h>#include <bios/string.h>extern   REG32 bios_recv_bytes;receive_packet_data rxd_data_packet;static char *data_ptr;static int ymodem_rx(int type,	char *data_ptr);static int receive_xy_modem(int type,int port,char *buffer,\		char NCGparm,int batch_flag);static int receive_start_up(int port,char *NCGchar_pointer,int Flag);static void receive_packet_error(int port, int packet, \		int attempt, char *MsgPtr); static unsigned int crc_update(unsigned char octet,unsigned int crc);static int RxPacket(int type,int port,int PacketNbr,int *PacketSizePtr,\		char *buffer,char NCGchar,int *EOTptr,int follow_flag) ;extern int kbd_hit(void) ;static int serial_probe(void){	return 0 ;}static int serial_start(void){	return 0 ;}static int serial_load(void){	unsigned char *data = (unsigned char *)load_addr;                printf("\nSerial loader image download address is 0x%x\n",(int)load_addr);        printf("Send data to serial port using by YMODEM protocol...\n") ;	if (!ymodem_rx(0,data)) {		printf("\nReceive fail from serial[YMODEM] !!!") ;		return 1 ;	}	return 0 ;}static int serial_stop(void){	/* disable all interrupt */	CSR_WRITE(INTMSK,INT_MASK_DIS) ;	return 0 ;}struct bootdev boot_serial = {	"serial",               /* const char *name; */	serial_probe,           /* int (*init)(void); */	serial_start,           /* int (*start)(void);*/	serial_load,            /* int (*load)(void); */	serial_stop,            /* int (*stop)(void); */      /* (struct bootdev *)(NULL); */};static int ymodem_rx(int type,	char *data_ptr){	int port = 0 ;	char *buffer = data_ptr;	char NCGchar;	if(!type) NCGchar= 'C' ;	else	  NCGchar= 'G' ;	if(receive_xy_modem(type,port,buffer,NCGchar,TRUE)) return (TRUE);	else return (FALSE);}static int receive_xy_modem(int	type, int port, char *buffer, char NCGparm, int batch_flag)/* char *buffer : data buffer *//* char  NCGparm : NAK, 'C', or 'G' *//* if TRUE, get filename from packet 0 */{	int  	p;				/* packet index */	int  	first_packet;	int  	PacketSize;		/* 128 or 1024 */        int     block_size = 0;	int  	EOTflag = FALSE;	char 	NCGchar;	int 	follow_flag=0;	data_ptr = buffer; 	/* begin xmodem protocol program */	NCGchar = NCGparm;	EOTflag = FALSE;	/* waiting for clearing serial port */	wait_cs(100);		/* send NAKs, 'C's, or 'G's */	if(!receive_start_up(port,&NCGchar,TRUE))	{		printf("receive start up fail !!!") ;    		return(FALSE);	} 	if(batch_flag)	first_packet = 0;	else  		first_packet = 1;		/* get each packet in turn */	for(p=first_packet;;p++)	{		/* continuing the reception of packet over 256 packet */		if(p==256) {			p=0;                        block_size++;			rxd_data_packet.header = getc();			follow_flag=1;		}		switch(RxPacket(type,port,p,&PacketSize,data_ptr,NCGchar,&EOTflag,follow_flag)) 		{			case TRUE : break;			default: printf("receive packet error !!!") ;                                   return(FALSE);		}				             		/* all done if EOT was received */		if(EOTflag)		{			if(batch_flag) 			{				do {					p=0;					receive_start_up(port,&NCGchar,FALSE);						RxPacket(type,port,p,&PacketSize,data_ptr,NCGchar,&EOTflag,follow_flag) ;				} while(rxd_data_packet.data[0]!='\0');			}			printf("\n\nTransfer completed...\n");                        bios_recv_bytes += p;			return (TRUE); /*TRUE);*/		}                bios_recv_bytes +=PacketSize;		/* process packet */		if(p==0){			if(!follow_flag) receive_start_up(port,&NCGchar,FALSE);			else rxd_data_packet.header = getc();		}	} /* end -- for(p)  */} /* end - RxyModem */static int RxPacket(	int type,	int port,            // COM port [0..3] 	int PacketNbr,       // Packet # expected 	int *PacketSizePtr,  // Pointer to PacketSize received ( 128 or 1024)	char *buffer,        // 1024 byte data buffer 	char NCGchar,        // NAK, C, or G 	int *EOTptr,         // Pointer to EOT flag	int follow_flag)     // continuous data receive{	int i,Code,Attempt,RxPacketNbr,RxPacketNbrComp;	unsigned short CheckSum,RxCheckSum,RxCheckSum1,RxCheckSum2;	PacketNbr &= 0x00ff;        *PacketSizePtr = 0; // added by yskim 04-13-2000	for(Attempt=1;Attempt<=MAXTRY;Attempt++) {	    	// wait for SOH/STX except for rxstartup    			if(PacketNbr!=1 && PacketNbr!=0)			rxd_data_packet.header = getc();		switch((char)rxd_data_packet.header){			case SOH: // 128 byte buffer incoming        				*PacketSizePtr = 128;				break;							case STX: // 1024 byte buffer incoming 				*PacketSizePtr = 1024;				break;			case CAN: // sender has canceled ! 				return(CANCEL);			case EOT: // all packets have been sent 				putc(ACK);				*EOTptr = TRUE;				return(TRUE);			default: // error ! 				return(FALSE);		}		// receive packet number 		rxd_data_packet.packet_Nbr=getc();		rxd_data_packet.packet_Nbr_cmp=getc();		RxPacketNbr = 0x00ff & rxd_data_packet.packet_Nbr;		RxPacketNbrComp = 0x00ff & rxd_data_packet.packet_Nbr_cmp;                for(i=0;i<*PacketSizePtr;i++)			rxd_data_packet.data[i]=getc();		// receive 2 byte CRC 		rxd_data_packet.checksum1 = getc();		rxd_data_packet.checksum2 = getc();               		// receive data 		CheckSum = 0;                if(PacketNbr==0 && NCGchar=='C' && follow_flag== 0)  // Only Y-MODEM		{			putc(ACK);			return TRUE;		}		for(i=0;i<*PacketSizePtr;i++)		{						Code = rxd_data_packet.data[i];			if(Code==-1) {				receive_packet_error(port,PacketNbr,Attempt,"timed out");				return(FALSE);			}			//if((char)Code!=CTLZ) {				//buffer[i] = Code;				*data_ptr = Code;    			data_ptr++;			//}			// compute CRC or checksum 			if(NCGchar!=NAK) 				CheckSum = crc_update((unsigned char)Code,CheckSum);			else CheckSum = (CheckSum + Code) & 0x00ff;		}		// don't send ACK if 'G' 		if(NCGchar=='G') return(TRUE);		// receive CRC/checksum		if(NCGchar!=NAK)		{						RxCheckSum1 = rxd_data_packet.checksum1 & 0x00ff;			RxCheckSum2 = rxd_data_packet.checksum2 & 0x00ff;			RxCheckSum = (RxCheckSum1<<8) | RxCheckSum2;		} else {			// receive one byte checksum 			Code = getc() ;			RxCheckSum = Code & 0x00ff;		}				// checksum OK ? 		if(RxCheckSum!=CheckSum)	putc(NAK);		// packet number OK ? 		else if(rxd_data_packet.packet_Nbr!=PacketNbr)	putc(NAK);					else {			putc(ACK);			return(TRUE);		} // end if	} // end -- for(Attempt) 	return(FALSE);} // end -- RxPacket static void receive_packet_error(int port, int packet, int attempt, char *MsgPtr){	char temp[81];	sprintf(temp,"packet %d : attempt %d : %s",packet,attempt,MsgPtr);}static int receive_start_up(int port,char *NCGchar_pointer,int Flag){	int i ;	char rxd_header;	/* Send NAKs, 'C's, or 'G's */	for(i=1;i<LIMIT;i++)	{		/* stop attempting CRC/'G' after 1st 4 tries  */		if((*NCGchar_pointer!=NAK)&&(i==5))			*NCGchar_pointer = NAK;						if(Flag)		{			i=100;			while(1) {				i--;				rxd_header=0x00;				wait_cs(300);				putc(*NCGchar_pointer);					rxd_header = getc_timed(100) ;				if(rxd_header==SOH) break;				if(rxd_header==STX) break;				if(i==0) return FALSE;			}		} else {			putc(*NCGchar_pointer);					rxd_header = getc() ;		}				rxd_data_packet.header = rxd_header;				return(TRUE);	} 	/* No response from sender */	return(FALSE);} static unsigned int crc_update(unsigned char octet,unsigned int crc){ return  (crc << 8) ^ crc_table[ (crc >> 8) ^ octet ];}

⌨️ 快捷键说明

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