📄 xmodem.c
字号:
#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 + -