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 + -
显示快捷键?