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

📄 xmodem.c

📁 一款交换机BSP开发代码
💻 C
📖 第 1 页 / 共 2 页
字号:

#ifdef _XMODEM_DEBUG
			Mtrace("--TERABUG--");
#endif

			goto teratermbug;
		}
		UART_Put_Char(CAN);

#ifdef _XMODEM_DEBUG
		Mtrace("3 %02x != %02x",seq[0],xip->sno);
#endif

		return(-1);
	}
teratermbug:
	if ((UCHAR)seq[1] != (UCHAR)~(xip->sno)) {
		UART_Put_Char(CAN);

#ifdef _XMODEM_DEBUG
		Mtrace("4 %02x != %02x",seq[1],(UCHAR)~(xip->sno));
#endif

		return(-1);
	}
	/* First packet of YMODEM contains informaiton about the transfer: */
	/* FILENAME SP FILESIZE SP MOD_DATE SP FILEMODE SP FILE_SNO */
	/* Only the FILENAME is required and if others are present, then none */
	/* can be skipped. */
	if ((xip->flags & YMODEM) && (xip->pktcnt == 0)) {
		char *slash, *space, *fname;

		slash = (char *)strrchr((char *)(xip->dataddr),'/');
		space = (char *)strchr((char *)(xip->dataddr),' ');
		if (slash)
			fname = slash + 1;
		else
			fname = (char *)(xip->dataddr);

#ifdef _XMODEM_DEBUG
		Mtrace("<fname=%s>",fname);
#endif

		if (space) {
			*space = 0;
			xip->size = atoi(space+1);
		}
		strcpy(xip->fname,fname);
		if (fname[0])
			xip->filcnt++;
	}
	else
		xip->dataddr += xip->pktlen;
	xip->sno++;
	xip->pktcnt++;
	xip->xfertot += xip->pktlen;
	UART_Put_Char(ACK);
	if (xip->flags & YMODEM) {
		if (xip->fname[0] == 0) {

#ifdef _XMODEM_DEBUG
			Mtrace("\nRcvd %d file%c\n",
				xip->filcnt,xip->filcnt > 1 ? 's' : ' ');
#endif

			return(1);
		}
	}
	return(0);
}

char packetbuf[1024];

/* Xup():
 * Called when a transfer from target to host is being made (considered
 * an upload).
 */
static int
Xup(struct xinfo *xip)
{
	UCHAR	c, *buf;
	int		done, pktlen;
	long	actualsize;

	buf = (UCHAR *)packetbuf;

#ifdef _XMODEM_DEBUG
	Mtrace("Xup starting");
#endif

	actualsize = xip->size;

	if (xip->size & 0x7f) {
		xip->size += 128;
		xip->size &= 0xffffff80L;
	}

#ifdef _XMODEM_DEBUG
	Mtrace("Upload %ld bytes from 0x%lx\n",xip->size,(ULONG)xip->base);
#endif

	/* Startup synchronization... */
	/* Wait to receive a NAK or 'C' from receiver. */
	done = 0;
	while(!done) {
		c = 0;
		UART_Get_Char1(&c);
		switch(c) {
		case NAK:
			done = 1;

#ifdef _XMODEM_DEBUG
			Mtrace("CSM");
#endif

			break;
		case 'C':
			xip->flags |= USECRC;
			done = 1;

#ifdef _XMODEM_DEBUG
			Mtrace("CRC");
#endif

			break;
		case 'q':	/* ELS addition, not part of XMODEM spec. */
			return(0);
		default:
			break;
		}
	}

	if (xip->flags & YMODEM) {

#ifdef _XMODEM_DEBUG
		Mtrace("SNO_0");
#endif

		xip->sno = 0;
		memset((char *)buf,0,PKTLEN_128);
		sprintf((char *)buf,"%s",xip->fname);
		pktlen = xip->pktlen;
		xip->pktlen = PKTLEN_128;
		putPacket(buf,xip);
		xip->pktlen = pktlen;
	}

	done = 0;
	xip->sno = 1;
	xip->pktcnt = 0;
	while(!done) {
		c = (UCHAR)putPacket((UCHAR *)(xip->dataddr),xip);
		switch(c) {
		case ACK:
			xip->sno++;
			xip->pktcnt++;
			xip->size -= xip->pktlen;
			xip->dataddr += xip->pktlen;

#ifdef _XMODEM_DEBUG
			Mtrace("A");
#endif

			break;
		case NAK:

#ifdef _XMODEM_DEBUG
			Mtrace("N");
#endif

			break;
		case CAN:
			done = 1;

#ifdef _XMODEM_DEBUG
			Mtrace("C");
#endif

			break;
		case EOT:
			done = 1;

#ifdef _XMODEM_DEBUG
			Mtrace("E");
#endif

			break;
		default:
			done = 1;

#ifdef _XMODEM_DEBUG
			Mtrace("<%2x>",c);
#endif

			break;
		}
		if (xip->size <= 0) {
			UART_Put_Char(EOT);
			UART_Get_Char1(&c);	/* Flush the ACK */
			break;
		}

#ifdef _XMODEM_DEBUG
		Mtrace("!");
#endif

	}

#ifdef _XMODEM_DEBUG
	Mtrace("Xup_almost");
#endif

	if (xip->flags & YMODEM) {
		xip->sno = 0;
		xmodemstart = 1;
		memset((char *)buf,0,PKTLEN_128);
		pktlen = xip->pktlen;
		xip->pktlen = PKTLEN_128;
		putPacket(buf,xip);
		xip->pktlen = pktlen;
	}

#ifdef _XMODEM_DEBUG
	Mtrace("Xup_done.");
#endif

	return(0);
}


/* Xdown():
 * Called when a transfer from host to target is being made (considered
 * an download).
 */

static int
Xdown(struct xinfo *xip)
{
	extern	int LoopsPerSecond;
	long	timeout;
	char	c, *tmppkt;
	int		done;

//	tmppkt = malloc(PKTLEN_1K);
//	if (!tmppkt) {
//		Mtrace("malloc failed");
//		return(-1);
//	}

	tmppkt = packetbuf;

nextfile:
	if (xip->flags & YMODEM)
		xip->sno = 0x00;
	else
		xip->sno = 0x01;
	xip->pktcnt = 0;
	xip->errcnt = 0;
	xip->xfertot = 0;
	xip->firsterrat = 0;

	/* Startup synchronization... */
	/* Continuously send NAK or 'C' until sender responds. */
restart:

#ifdef _XMODEM_DEBUG
	Mtrace("Xdown");
#endif

	while(1) {
		if (xip->flags & USECRC)
			UART_Put_Char('C');
		else
			UART_Put_Char(NAK);
		timeout = LoopsPerSecond;
		while(!UART_Data_Ready() && timeout)
			timeout--;
		if (timeout)
			break;
	}

	done = 0;

#ifdef _XMODEM_DEBUG
	Mtrace("Got response");
#endif

	while(done == 0) {
		UART_Get_Char1(&c);
		switch(c) {
		case SOH:				/* 128-byte incoming packet */

#ifdef _XMODEM_DEBUG
			Mtrace("O");
#endif

			xip->pktlen = 128;
			done = getPacket((UCHAR *)tmppkt,xip);
			if (!done && (xip->pktcnt == 1) && (xip->flags & YMODEM))
				goto restart;
			break;
		case STX:				/* 1024-byte incoming packet */

#ifdef _XMODEM_DEBUG
			Mtrace("T");
#endif

			xip->pktlen = 1024;
			done = getPacket((UCHAR *)tmppkt,xip);
			if (!done && (xip->pktcnt == 1) && (xip->flags & YMODEM))
				goto restart;
			break;
		case CAN:

#ifdef _XMODEM_DEBUG
			Mtrace("C");
#endif

			done = -1;
			break;
		case EOT:

#ifdef _XMODEM_DEBUG
			Mtrace("E");
#endif

			UART_Put_Char(ACK);
//			if (xip->flags & YMODEM) {
				if (!xip->size)
					xip->size = xip->pktcnt * xip->pktlen;
				if (xip->fname[0])
					tfsadd(xip->fname,0,0,(UCHAR *)xip->base,xip->size);
				xip->dataddr = xip->base;
				goto nextfile;
//			}
//			else {
//				done = xip->xfertot;
//				Mtrace("\nRcvd %d pkt%c (%d bytes)\n",xip->pktcnt,
//						xip->pktcnt > 1 ? 's' : ' ',xip->xfertot);
//			}
			break;
		case ESC:		/* User-invoked abort */

#ifdef _XMODEM_DEBUG
			Mtrace("X");
#endif

			done = -1;
			break;
		default:

#ifdef _XMODEM_DEBUG
			Mtrace("<%02x>",c);
#endif

			done = -1;
			break;
		}

#ifdef _XMODEM_DEBUG
		Mtrace("!");
#endif

	}
//	if (xip->flags & VERIFY) {
//		if (xip->errcnt)
//			printf("%d errors, first at 0x%lx\n",
//				xip->errcnt,(ULONG)(xip->firsterrat));
//		else
//			printf("verification passed\n");
//	}
//	free(tmppkt);
	return(done);
}


#ifdef _XMODEM_DEBUG
/* Mtrace():
 * Memory trace... This function can be used to place some trace statements
 * (readable text) in some memory location specified by the
 * setting of mtracebuf.  This was originally written for debugging Xmodem
 * because you can't use printf() since the protocol is using the serial 
 * port.  I have since pulled it out of the Xmodem.c file and placed it in
 * generally accessible space so that it can be made available to the
 * application code and other monitor code.
 */
int
Mtrace(format,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,arg11,arg12)
char	*format;
long	arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,arg11,arg12;
{
	int		tot;

	if (!Mtracebuf)
		return(0);
	tot = sprintf(Mtracebuf,format,
		arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,arg11,arg12);
	Mtracebuf += tot;
	return(tot);
}

#endif

⌨️ 快捷键说明

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