📄 ian_xmodem.c
字号:
if (fname && fname[0]) { strcpy(yif.fname[0], fname); } else { strcpy(yif.fname[0], "noname"); } yif.size[0] = size;#if ! INCLUDE_TFS if ( yif.size[0] <= 0 ) { printf("%s\n", xerr_msg(XERR_NOSIZE)); return(CMD_FAILURE); }#endif r = Yup(&yif); printf("\n"); if ( yif.filecnt > 0 ) { printf("Sent %d file%s.\n", yif.filecnt, (yif.filecnt > 1) ? "s" : ""); for (i = 0; i < yif.filecnt; i++) { printf(" %s: %ld bytes, %ld blocks, @ 0x%08lx\n", yif.fname[i] ? yif.fname[i] : "<noname>", yif.size[i], yif.pktcnt[i], yif.dataddr[i]); } } if ( r < 0 ) { printf("%s\n", xerr_msg(r)); return(CMD_FAILURE); } } else { /* plain X-modem */ xif.dataddr = dataddr; xif.size = size; xif.onek = onek; if ( fname && fname[0] ) {#if INCLUDE_TFS if ( ! (tfp = tfsstat(fname)) ) { printf("%s\n", xerr_msg(XERR_NOFILE)); return(CMD_FAILURE); } memcpy((char *)(xif.dataddr), TFS_BASE(tfp), tfp->filsize); xif.size = size = tfp->filsize;#endif } if ( xif.size <= 0 ) { printf("%s\n", xerr_msg(XERR_NOSIZE)); return(CMD_FAILURE); } r = Xup(&xif, XMODEM); printf("\n"); if ( r < 0 ) { printf("%s\n", xerr_msg(r)); return(CMD_FAILURE); } printf("Sent 1 file.\n"); printf(" %s: %ld bytes, %d blocks, @ 0x%08lx\n", fname[0] ? fname : "<no-name>", xif.size, xif.pktcnt, xif.dataddr); } } else if ( xop == XDOWN ) { /* DOWNLOAD: Host --> Micromonitor */ if ( ymodem ) { /* Use Y-Modem extensions */ yif.baseaddr = dataddr; yif.usecrc = !usecrc; yif.verify = verify; yif.flags = flags; yif.info = info; r = Ydown(&yif); printf("\n"); if ( yif.filecnt ) { printf("Rcvd %d file%s.\n", yif.filecnt, (yif.filecnt > 1) ? "s" : ""); if ( yif.verify ) { for (i = 0; i < yif.filecnt; i++) { printf(" %s: %ld bytes, %ld blocks, %ld errors, " "first err @ 0x%08lx\n", yif.fname[i] ? yif.fname[i] : "<noname>", yif.size[i], yif.pktcnt[i], yif.errcnt[i], yif.firsterrat[i]); } } else { for (i = 0; i < yif.filecnt; i++) { printf(" %s: %ld bytes, %ld blocks, @ 0x%08lx\n", yif.fname[i] ? yif.fname[i] : "<noname>", yif.size[i], yif.pktcnt[i], yif.dataddr[i]); } } } if ( r < 0 ) { if ( r == XERR_TFS ) { printf("%s: %s: %s\n", xerr_msg(XERR_TFS), yif.fname[yif.filecnt], (char *)tfsctrl(TFS_ERRMSG,tfserr,0)); } else { printf("%s\n", xerr_msg(r)); } return(CMD_FAILURE); } } else { /* plain X-Modem */ xif.dataddr = dataddr; xif.usecrc = usecrc; xif.verify = verify; if (verify && fname && fname[0]) {#if INCLUDE_TFS if (! (tfp = tfsstat(fname)) ) { printf("%s\n", xerr_msg(XERR_NOFILE)); return(CMD_FAILURE); } memcpy((char *)(xif.dataddr), TFS_BASE(tfp), tfp->filsize);#endif } r = Xdown(&xif, XMODEM); if (size) { /* override size by user specified value */ xif.size = size; } printf("\n"); if ( r < 0 ) { printf("%s\n", xerr_msg(r)); return(CMD_FAILURE); } if ( ! xif.verify ) {#if INCLUDE_TFS if (xif.size > 0 && fname && fname[0]) { /* save file to TFS */ r = tfsadd(fname, info, flags, (uchar *)xif.dataddr, xif.size); if (r != TFS_OKAY) { printf("%s: %s: %s\n", xerr_msg(XERR_TFS), fname, (char *)tfsctrl(TFS_ERRMSG,r,0)); return(CMD_FAILURE); } }#endif } printf("Rcvd 1 file.\n"); if ( xif.verify ) { printf(" %s: %ld bytes, %d blocks, %d errors, " "first err @ 0x%08lx\n", fname[0] ? fname : "<noname>", xif.size, xif.pktcnt, xif.errcnt, xif.firsterrat); } else { printf(" %s: %ld bytes, %d blocks, @ 0x%08lx\n", fname[0] ? fname : "<no-name>", xif.size, xif.pktcnt, xif.dataddr); } }#if INCLUDE_FLASH /* whether it is an X or a Y modem download, if newboot is set, the (last) downloaded file will be written to the boot-sector */ if (xif.size > 0 && newboot) { extern int FlashProtectWindow; char *bb; ulong bootbase; bb = getenv("BOOTROMBASE"); if (bb) bootbase = strtoul(bb,0,0); else bootbase = BOOTROM_BASE; FlashProtectWindow = 1; printf("Reprogramming boot @ 0x%lx from 0x%lx, %ld bytes.\n", bootbase, xif.dataddr, xif.size); if (askuser("OK?")) { if (flashewrite(&FlashBank[0], (char *)bootbase, (char *)xif.dataddr, xif.size) == -1) { /* flashewrite should never return */ printf("failed\n"); return(CMD_FAILURE); } } }#endif } else { /* Neither Upload nor Download */ return(CMD_PARAM_ERROR); } return(CMD_SUCCESS);}/***************************************************************************/static char*xerr_msg (int code){ return (code >= 0) ? xerr_msgs[0] : xerr_msgs[-code];}/***************************************************************************/static voiddoCAN (void) { waitclear(); /* send eight CANs */ rputchar(CAN); rputchar(CAN); rputchar(CAN); rputchar(CAN); rputchar(CAN); rputchar(CAN); rputchar(CAN); rputchar(CAN); /* send eight backspaces */ rputchar(BS); rputchar(BS); rputchar(BS); rputchar(BS); rputchar(BS); rputchar(BS); rputchar(BS); rputchar(BS); waitclear();}/*************************************************************************** * DOWNLOAD STUFF **************************************************************************//* getPacket(): * Used by Xdown to retrieve packets. */static intgetPacket(uchar *pkt, int len, int usecrc){ int i; uchar seq[2]; /* s: Get and check the frame sequence number */ if ( waitbytes(seq, 2, CHAR_TMO) < 0 ) { Mtrace("T<seq>"); return -1; } if ( seq[0] != (uchar)(~seq[1]) ) { Mtrace("~<%02x != %02x>", seq[0], seq[1]); return -1; } Mtrace("s"); /* d: Get the frame's data */ if ( waitbytes(pkt, len, CHAR_TMO) < 0 ) { Mtrace("T<data>"); return -1; } Mtrace("d"); /* d: Get the frame's CRC or checksum */ if ( usecrc ) { int c; ushort crc, xcrc; c = waitchar(CHAR_TMO); if ( c < 0 ) { Mtrace("T<crc>"); return -1; } crc = (ushort)c << 8; c = (uchar)waitchar(CHAR_TMO); if ( c < 0 ) { Mtrace("T<crc>"); return -1; } crc |= (ushort)c; xcrc = xcrc16((uchar *)pkt,(ulong)(len)); if (crc != xcrc) { Mtrace("C<%04x != %04x>", crc, xcrc); return -1; } } else { uchar csum; int xcsum; xcsum = waitchar(CHAR_TMO); if ( xcsum < 0 ) { Mtrace("T<xcsum>"); return -1; } csum = 0; for(i=0; i < len; i++) csum += *pkt++; if (csum != xcsum) { Mtrace("c<%02x != %02x>",csum,xcsum); return -1; } } Mtrace("c"); return seq[0];}/***************************************************************************//* * waitPacket * * Receive a X or Y modem packet. Step the reception state-machine. * * Acknowledge the previous frame (or 'kick' the transmiter with a 'C' * or NAK if this is the first frame), and receive the next-one. Also * handle frame retransmitions. * * Arguments: * - pb - packet (frame) buffer. Write the packet-data here. * - *len - packet's size in bytes will be written here * - sno - packet sequence number to wait for. * - usercrc - if non-zero, user 16-bit CRC instread of 8-bit checksum. * * Returns: * 0 - if packet was received successfully * 1 - if an EOT was received instead of a packet * Something negative on fatal error: * XERR_SYNC : Synchronization lost * XERR_CAN : Operation canceled * XERR_UCAN : Operation canceled by user */static intwaitPacket (uchar *pb, int *len, ulong lsno, int usecrc){ char nak; int done, rval; int c, r, sno, psize; if ( usecrc ) { nak = 'C'; } else { nak = NAK; } if ( (lsno == 0 || lsno == 1) ) { /* if it is the first frame of a X or Y modem session, 'kick' the transmiter by sending a NAK or a 'C' */ rputchar(nak); } else { /* if it is not the first frame of an X or Y modem session, acknowledge the previous frame */ rputchar(ACK); } sno = lsno % 0x100; /* loop exitst with: done = 1: packet received succesfully done = 2: EOT received and acknowledged done < 0: Fatal error. 'done' holds error code. */ do { done = 0; c = waitchar(FRAME_TMO); switch ( c ) { case STX: case SOH: /* ok, its a block */ Mtrace("P["); *len = psize = (c == STX) ? 1024 : 128; r = getPacket(pb, psize, usecrc); Mtrace("]"); if (r < 0) { /* block reception not ok. request retransmission */ waitclear(); rputchar(nak); break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -